introduce FieldDecl in the ast

This commit is contained in:
Erik Krogh Kristensen
2021-11-18 11:21:56 +01:00
parent cc16fdecbb
commit 5a76e7d4f8
4 changed files with 37 additions and 11 deletions

View File

@@ -563,8 +563,10 @@ class VarDecl extends TVarDecl, VarDef, Declaration {
)
}
/** If this is a field, returns the class type that declares it. */
ClassType getDeclaringType() { result.getDeclaration().getAField() = this }
/** If this is declared in a field, returns the class type that declares it. */
ClassType getDeclaringType() {
exists(FieldDecl f | f.getVarDecl() = this and result = f.getParent().(Class).getType())
}
/**
* Holds if this is a class field that overrides the field `other`.
@@ -580,6 +582,32 @@ class VarDecl extends TVarDecl, VarDef, Declaration {
override string toString() { result = this.getName() }
}
/**
* A field declaration;
*/
class FieldDecl extends TFieldDecl, AstNode {
QL::Field f;
FieldDecl() { this = TFieldDecl(f) }
VarDecl getVarDecl() { toQL(result) = f.getChild() }
override AstNode getAChild(string pred) {
result = super.getAChild(pred)
or
pred = directMember("getVarDecl") and result = this.getVarDecl()
}
override string getAPrimaryQlClass() { result = "FieldDecl" }
/** Holds if this field is annotated as overriding another field. */
predicate isOverride() { this.hasAnnotation("override") }
string getName() { result = getVarDecl().getName() }
override QLDoc getQLDoc() { result = any(Class c).getQLDocFor(this) }
}
/**
* A type reference, such as `DataFlow::Node`.
*/
@@ -716,10 +744,7 @@ class Class extends TClass, TypeDeclaration, ModuleDeclaration {
*/
CharPred getCharPred() { toQL(result) = cls.getChild(_).(QL::ClassMember).getChild(_) }
AstNode getMember(int i) {
toQL(result) = cls.getChild(i).(QL::ClassMember).getChild(_) or
toQL(result) = cls.getChild(i).(QL::ClassMember).getChild(_).(QL::Field).getChild()
}
AstNode getMember(int i) { toQL(result) = cls.getChild(i).(QL::ClassMember).getChild(_) }
QLDoc getQLDocFor(AstNode m) {
exists(int i | result = this.getMember(i) and m = this.getMember(i + 1))
@@ -743,9 +768,7 @@ class Class extends TClass, TypeDeclaration, ModuleDeclaration {
/**
* Gets a field in this class.
*/
VarDecl getAField() {
toQL(result) = cls.getChild(_).(QL::ClassMember).getChild(_).(QL::Field).getChild()
}
FieldDecl getAField() { result = getMember(_) }
/**
* Gets a super-type referenced in the `extends` part of the class declaration.

View File

@@ -8,6 +8,7 @@ newtype TAstNode =
TQLDoc(QL::Qldoc qldoc) or
TClasslessPredicate(QL::ClasslessPredicate pred) or
TVarDecl(QL::VarDecl decl) or
TFieldDecl(QL::Field field) or
TClass(QL::Dataclass dc) or
TCharPred(QL::Charpred pred) or
TClassPredicate(QL::MemberPredicate pred) or
@@ -150,6 +151,8 @@ QL::AstNode toQL(AST::AstNode n) {
or
n = TVarDecl(result)
or
n = TFieldDecl(result)
or
n = TClass(result)
or
n = TCharPred(result)

View File

@@ -134,7 +134,7 @@ predicate predOverrides(ClassPredicate sub, ClassPredicate sup) {
}
private VarDecl declaredField(ClassType ty, string name) {
result = ty.getDeclaration().getAField() and
result = ty.getDeclaration().getAField().getVarDecl() and
result.getName() = name
}

View File

@@ -37,7 +37,7 @@ class VariableScope extends TScope, AstNode {
predicate containsField(VarDef decl, string name) {
name = decl.getName() and
(
decl = this.(Class).getAField()
decl = this.(Class).getAField().getVarDecl()
or
this.getOuterScope().containsField(decl, name) and
not exists(this.getADefinition(name))