QL: Merge pull request #15 from github/inheritance

Resolve inheritable members (fields and member predicates)
This commit is contained in:
Tom Hvitved
2021-05-28 11:05:28 +02:00
committed by GitHub
2 changed files with 85 additions and 0 deletions

View File

@@ -106,6 +106,8 @@ class Predicate extends TPredicate, AstNode {
*/
VarDecl getParameter(int i) { none() }
int getArity() { result = count(getParameter(_)) }
// TODO: ReturnType.
override AstNode getAChild(string pred) {
pred = "getBody" and result = this.getBody()
@@ -212,11 +214,22 @@ class ClassPredicate extends TClassPredicate, Predicate {
override Class getParent() { result.getAClassPredicate() = this }
predicate isPrivate() {
exists(Generated::ClassMember member |
pred = member.getChild(_) and
member.getAFieldOrChild().(Generated::Annotation).getName().getValue() = "private"
)
}
override VarDecl getParameter(int i) {
toGenerated(result) =
rank[i](Generated::VarDecl decl, int index | decl = pred.getChild(index) | decl order by index)
}
ClassType getDeclaringType() { result.getDeclaration() = getParent() }
predicate overrides(ClassPredicate other) { predOverrides(this, other) }
override AstNode getAChild(string pred_name) {
pred_name = "getBody" and result = this.getBody()
or
@@ -270,6 +283,18 @@ class VarDecl extends TVarDecl, AstNode {
TypeExpr getType() { toGenerated(result) = var.getChild(0) }
predicate isPrivate() {
exists(Generated::ClassMember member |
var = member.getChild(_).(Generated::Field).getChild() and
member.getAFieldOrChild().(Generated::Annotation).getName().getValue() = "private"
)
}
/** If this is a field, returns the class type that declares it. */
ClassType getDeclaringType() { result.getDeclaration().getAField() = this }
predicate overrides(VarDecl other) { fieldOverrides(this, other) }
override AstNode getAChild(string pred) { pred = "getType" and result = this.getType() }
}
@@ -451,6 +476,9 @@ class Class extends TClass, TypeDeclaration, ModuleDeclaration {
toGenerated(result) = cls.getChild(_).(Generated::TypeUnionBody).getChild(_)
}
/** Gets the class type defined by this class declaration. */
Type getType() { result.getDeclaration() = this }
override AstNode getAChild(string pred) {
pred = "getAliasType" and result = this.getAliasType()
or

View File

@@ -77,6 +77,63 @@ class ClassType extends Type, TClass {
or
result = super.getAnInternalSuperType()
}
ClassPredicate getClassPredicate(string name, int arity) {
result = classPredCandidate(this, name, arity) and
not exists(ClassPredicate other | other = classPredCandidate(this, name, arity) |
other.getDeclaringType().getASuperType+() = result.getDeclaringType()
)
}
VarDecl getField(string name) {
result = fieldCandidate(this, name) and
not exists(VarDecl other | other = fieldCandidate(this, name) |
other.getDeclaringType().getASuperType+() = result.getDeclaringType()
)
}
}
private ClassPredicate declaredPred(ClassType ty, string name, int arity) {
result = ty.getDeclaration().getAClassPredicate() and
result.getName() = name and
result.getArity() = arity
}
private ClassPredicate classPredCandidate(ClassType ty, string name, int arity) {
result = declaredPred(ty, name, arity)
or
not exists(declaredPred(ty, name, arity)) and
result = inherClassPredCandidate(ty, name, arity)
}
private ClassPredicate inherClassPredCandidate(ClassType ty, string name, int arity) {
result = classPredCandidate(ty.getASuperType(), name, arity) and
not result.isPrivate()
}
predicate predOverrides(ClassPredicate sub, ClassPredicate sup) {
sup = inherClassPredCandidate(sub.getDeclaringType(), sub.getName(), sub.getArity())
}
private VarDecl declaredField(ClassType ty, string name) {
result = ty.getDeclaration().getAField() and
result.getName() = name
}
private VarDecl fieldCandidate(ClassType ty, string name) {
result = declaredField(ty, name)
or
not exists(declaredField(ty, name)) and
result = inherFieldCandidate(ty, name)
}
private VarDecl inherFieldCandidate(ClassType ty, string name) {
result = fieldCandidate(ty.getASuperType(), name) and
not result.isPrivate()
}
predicate fieldOverrides(VarDecl sub, VarDecl sup) {
sup = inherFieldCandidate(sub.getDeclaringType(), sub.getName())
}
class ClassCharType extends Type, TClassChar {