mirror of
https://github.com/github/codeql.git
synced 2026-02-09 19:51:07 +01:00
QL: Merge pull request #15 from github/inheritance
Resolve inheritable members (fields and member predicates)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user