Merge pull request #25 from github/cleanup

cleanup
This commit is contained in:
Erik Krogh Kristensen
2021-05-28 15:07:16 +02:00
committed by GitHub
4 changed files with 216 additions and 54 deletions

View File

@@ -16,10 +16,22 @@ private string stringIndexedMember(string name, string index) {
result = name + "(_)" and exists(index)
}
/**
* Holds if `node` has an annotation with `name`.
*/
private predicate hasAnnotation(AstNode node, string name) {
exists(Generated::Annotation annotation | annotation.getName().getValue() = name |
toGenerated(node).getParent() = annotation.getParent()
)
}
/** An AST node of a QL program */
class AstNode extends TAstNode {
string toString() { result = getAPrimaryQlClass() }
/**
* Gets the location of the AST node.
*/
Location getLocation() {
exists(Generated::AstNode node | not node instanceof Generated::ParExpr |
node = toGenerated(this) and
@@ -27,6 +39,9 @@ class AstNode extends TAstNode {
)
}
/**
* Gets the parent in the AST for this node.
*/
AstNode getParent() { result.getAChild(_) = this }
/**
@@ -36,14 +51,22 @@ class AstNode extends TAstNode {
cached
AstNode getAChild(string pred) { none() }
/**
* Gets the primary QL class for the ast node.
*/
string getAPrimaryQlClass() { result = "???" }
}
/** A toplevel QL program, i.e. a file. */
class TopLevel extends TTopLevel, AstNode {
Generated::Ql file;
TopLevel() { this = TTopLevel(file) }
/**
* Gets a member from contained in this top-level module.
* Includes private members.
*/
ModuleMember getAMember() { toGenerated(result) = file.getChild(_).getChild(_) }
override ModuleMember getAChild(string pred) {
@@ -61,12 +84,22 @@ class Select extends TSelect, AstNode {
Select() { this = TSelect(sel) }
/**
* Gets the `i`th variable in the `from` clause.
*/
VarDecl getVarDecl(int i) { toGenerated(result) = sel.getChild(i) }
/**
* Gets the formula in the `where`.
*/
Formula getWhere() { toGenerated(result) = sel.getChild(_) }
/**
* Gets the `i`th expression in the `select` clause.
*/
Expr getExpr(int i) { toGenerated(result) = sel.getChild(_).(Generated::AsExprs).getChild(i) }
// TODO: This gets the `i`th order-by, but some expressions might not have an order-by.
Expr getOrderBy(int i) {
toGenerated(result) = sel.getChild(_).(Generated::OrderBys).getChild(i).getChild(0)
}
@@ -90,6 +123,7 @@ class Select extends TSelect, AstNode {
/**
* A QL predicate.
* Either a classless predicate, a class predicate, or a characteristic predicate.
*/
class Predicate extends TPredicate, AstNode {
/**
@@ -107,6 +141,9 @@ class Predicate extends TPredicate, AstNode {
*/
VarDecl getParameter(int i) { none() }
/**
* Gets the number of parameters.
*/
int getArity() { result = count(getParameter(_)) }
/**
@@ -129,6 +166,9 @@ class Predicate extends TPredicate, AstNode {
override string getAPrimaryQlClass() { result = "Predicate" }
}
/**
* An expression that refers to a predicate, e.g. `BasicBlock::succ/2`.
*/
class PredicateExpr extends TPredicateExpr, AstNode {
Generated::PredicateExpr pe;
@@ -136,6 +176,10 @@ class PredicateExpr extends TPredicateExpr, AstNode {
override string toString() { result = "predicate" }
/**
* Gets the name of the predicate.
* E.g. for `BasicBlock::succ/2` the result is "succ".
*/
string getName() {
exists(Generated::AritylessPredicateExpr ape, Generated::LiteralId id |
ape.getParent() = pe and
@@ -144,6 +188,10 @@ class PredicateExpr extends TPredicateExpr, AstNode {
)
}
/**
* Gets the arity of the predicate.
* E.g. for `BasicBlock::succ/2` the result is 2.
*/
int getArity() {
exists(Generated::Integer i |
i.getParent() = pe and
@@ -151,6 +199,10 @@ class PredicateExpr extends TPredicateExpr, AstNode {
)
}
/**
* Gets the module containing the predicate.
* E.g. for `BasicBlock::succ/2` the result is a `ModuleExpr` representing "BasicBlock".
*/
ModuleExpr getQualifier() {
exists(Generated::AritylessPredicateExpr ape |
ape.getParent() = pe and
@@ -158,6 +210,9 @@ class PredicateExpr extends TPredicateExpr, AstNode {
)
}
/**
* Gets the predicate that this expression refers to.
*/
Predicate getResolvedPredicate() { resolvePredicateExpr(this, result) }
override AstNode getAChild(string pred) {
@@ -173,11 +228,15 @@ class PredicateExpr extends TPredicateExpr, AstNode {
* A classless predicate.
*/
class ClasslessPredicate extends TClasslessPredicate, Predicate, ModuleDeclaration {
Generated::ModuleMember member;
Generated::ClasslessPredicate pred;
ClasslessPredicate() { this = TClasslessPredicate(member, pred) }
ClasslessPredicate() { this = TClasslessPredicate(pred) }
/**
* If this predicate is an alias, gets the aliased value.
* E.g. for `predicate foo = Module::bar/2;` gets `Module::bar/2`.
* The result is either a `PredicateExpr` or `HigherOrderFormula`.
*/
final AstNode getAlias() {
exists(Generated::PredicateAliasBody alias |
alias.getParent() = pred and
@@ -187,10 +246,6 @@ class ClasslessPredicate extends TClasslessPredicate, Predicate, ModuleDeclarati
toGenerated(result) = pred.getChild(_).(Generated::HigherOrderTerm)
}
final override predicate isPrivate() {
member.getAFieldOrChild().(Generated::Annotation).getName().getValue() = "private"
}
override string getAPrimaryQlClass() { result = "ClasslessPredicate" }
override Formula getBody() { toGenerated(result) = pred.getChild(_).(Generated::Body).getChild() }
@@ -237,14 +292,15 @@ class ClassPredicate extends TClassPredicate, Predicate {
override Class getParent() { result.getAClassPredicate() = this }
predicate isPrivate() { hasAnnotation("private") }
/**
* Holds if this predicate is private.
*/
predicate isPrivate() { hasAnnotation(this, "private") }
predicate hasAnnotation(string name) {
exists(Generated::ClassMember member |
pred = member.getChild(_) and
member.getAFieldOrChild().(Generated::Annotation).getName().getValue() = name
)
}
/**
* Holds if this predicate is annotated as overriding another predicate.
*/
predicate isOverride() { hasAnnotation(this, "override") }
override VarDecl getParameter(int i) {
toGenerated(result) =
@@ -255,6 +311,9 @@ class ClassPredicate extends TClassPredicate, Predicate {
)
}
/**
* Gets the type representing this class.
*/
ClassType getDeclaringType() { result.getDeclaration() = getParent() }
predicate overrides(ClassPredicate other) { predOverrides(this, other) }
@@ -324,8 +383,14 @@ class VarDecl extends TVarDecl, VarDef {
override string getAPrimaryQlClass() { result = "VarDecl" }
/**
* Gets the type part of this variable declaration.
*/
TypeExpr getTypeExpr() { toGenerated(result) = var.getChild(0) }
/**
* Holds if this variable declaration is a private field on a class.
*/
predicate isPrivate() {
exists(Generated::ClassMember member |
var = member.getChild(_).(Generated::Field).getChild() and
@@ -336,6 +401,9 @@ class VarDecl extends TVarDecl, VarDef {
/** If this is a field, returns the class type that declares it. */
ClassType getDeclaringType() { result.getDeclaration().getAField() = this }
/**
* Holds if this is a class field that overrides the field `other`.
*/
predicate overrides(VarDecl other) { fieldOverrides(this, other) }
override AstNode getAChild(string pred) {
@@ -385,6 +453,9 @@ class TypeExpr extends TType, AstNode {
*/
ModuleExpr getModule() { toGenerated(result) = type.getChild() }
/**
* Gets the type that this type reference refers to.
*/
Type getResolvedType() { resolveTypeExpr(this, result) }
override ModuleExpr getAChild(string pred) {
@@ -404,13 +475,6 @@ class Module extends TModule, ModuleDeclaration {
override string getAPrimaryQlClass() { result = "Module" }
final override predicate isPrivate() {
exists(Generated::ModuleMember member |
mod = member.getChild(_) and
member.getAFieldOrChild().(Generated::Annotation).getName().getValue() = "private"
)
}
override string getName() { result = mod.getName().(Generated::ModuleName).getChild().getValue() }
/**
@@ -439,10 +503,10 @@ class Module extends TModule, ModuleDeclaration {
*/
class ModuleMember extends TModuleMember, AstNode {
/** Holds if this member is declared as `private`. */
predicate isPrivate() { none() } // TODO: Implement.
predicate isPrivate() { hasAnnotation(this, "private") }
}
/** A declaration. */
/** A declaration. E.g. a class, type, predicate, newtype... */
class Declaration extends TDeclaration, AstNode {
/** Gets the name of this declaration. */
string getName() { none() }
@@ -466,13 +530,6 @@ class Class extends TClass, TypeDeclaration, ModuleDeclaration {
override string getAPrimaryQlClass() { result = "Class" }
final override predicate isPrivate() {
exists(Generated::ModuleMember member |
cls = member.getChild(_) and
member.getAFieldOrChild().(Generated::Annotation).getName().getValue() = "private"
)
}
override string getName() { result = cls.getName().getValue() }
/**
@@ -505,6 +562,9 @@ class Class extends TClass, TypeDeclaration, ModuleDeclaration {
cls.getChild(_).(Generated::ClassMember).getChild(_).(Generated::Field).getChild()
}
/**
* Gets a super-type referenced in the `extends` part of the class declaration.
*/
TypeExpr getASuperType() { toGenerated(result) = cls.getChild(_) }
/** Gets the type that this class is defined to be an alias of. */
@@ -552,13 +612,6 @@ class NewType extends TNewType, TypeDeclaration, ModuleDeclaration {
override string getAPrimaryQlClass() { result = "NewType" }
final override predicate isPrivate() {
exists(Generated::ModuleMember member |
type = member.getChild(_) and
member.getAFieldOrChild().(Generated::Annotation).getName().getValue() = "private"
)
}
/**
* Gets a branch in this `newtype`.
*/
@@ -573,6 +626,7 @@ class NewType extends TNewType, TypeDeclaration, ModuleDeclaration {
/**
* A branch in a `newtype`.
* E.g. `Bar()` or `Baz()` in `newtype Foo = Bar() or Baz()`.
*/
class NewTypeBranch extends TNewTypeBranch, TypeDeclaration {
Generated::DatatypeBranch branch;
@@ -605,7 +659,14 @@ class NewTypeBranch extends TNewTypeBranch, TypeDeclaration {
}
}
/**
* A call to a predicate.
* Either a predicate call `foo()`,
* or a member call `foo.bar()`,
* or a special call to `none()` or `any()`.
*/
class Call extends TCall, Expr {
/** Gets the `i`th argument of this call. */
Expr getArgument(int i) {
none() // overriden in sublcasses.
}
@@ -616,9 +677,17 @@ class Call extends TCall, Expr {
final int getNumberOfArguments() { result = count(this.getArgument(_)) }
/**
* Gets the module that contains the predicate.
* E.g. for `Foo::bar()` the result is `Foo`.
*/
ModuleExpr getQualifier() { none() }
}
/**
* A call to a non-member predicate.
* E.g. `foo()` or `Foo::bar()`.
*/
class PredicateCall extends TPredicateCall, Call {
Generated::CallOrUnqualAggExpr expr;
@@ -639,6 +708,10 @@ class PredicateCall extends TPredicateCall, Call {
override string getAPrimaryQlClass() { result = "PredicateCall" }
/**
* Gets the name of the predicate called.
* E.g. for `foo()` the result is "foo".
*/
string getPredicateName() {
result = expr.getChild(0).(Generated::AritylessPredicateExpr).getName().getValue()
}
@@ -652,6 +725,10 @@ class PredicateCall extends TPredicateCall, Call {
}
}
/**
* A member call to a predicate.
* E.g. `foo.bar()`.
*/
class MemberCall extends TMemberCall, Call {
Generated::QualifiedExpr expr;
@@ -659,6 +736,10 @@ class MemberCall extends TMemberCall, Call {
override string getAPrimaryQlClass() { result = "MemberCall" }
/**
* Gets the name of the member called.
* E.g. for `foo.bar()` the result is "bar".
*/
string getMemberName() {
result = expr.getChild(_).(Generated::QualifiedRhs).getName().getValue()
}
@@ -681,6 +762,10 @@ class MemberCall extends TMemberCall, Call {
)
}
/**
* Gets the base of the member call.
* E.g. for `foo.(Bar).baz()` the result is `foo.(Bar)`.
*/
Expr getBase() { toGenerated(result) = expr.getChild(0) }
override AstNode getAChild(string pred) {
@@ -694,6 +779,9 @@ class MemberCall extends TMemberCall, Call {
}
}
/**
* A call to the special `none()` predicate.
*/
class NoneCall extends TNoneCall, Call, Formula {
Generated::SpecialCall call;
@@ -704,6 +792,9 @@ class NoneCall extends TNoneCall, Call, Formula {
override AstNode getParent() { result = Call.super.getParent() }
}
/**
* A call to the special `any()` predicate.
*/
class AnyCall extends TAnyCall, Call {
Generated::Aggregate agg;
@@ -712,6 +803,9 @@ class AnyCall extends TAnyCall, Call {
override string getAPrimaryQlClass() { result = "AnyCall" }
}
/**
* An inline cast, e.g. `foo.(Bar)`.
*/
class InlineCast extends TInlineCast, Expr {
Generated::QualifiedExpr expr;
@@ -719,12 +813,20 @@ class InlineCast extends TInlineCast, Expr {
override string getAPrimaryQlClass() { result = "InlineCast" }
/**
* Gets the type being cast to.
* E.g. for `foo.(Bar)` the result is `Bar`.
*/
TypeExpr getTypeExpr() {
toGenerated(result) = expr.getChild(_).(Generated::QualifiedRhs).getChild(_)
}
override Type getType() { result = this.getTypeExpr().getResolvedType() }
/**
* Gets the expression being cast.
* E.g. for `foo.(Bar)` the result is `foo`.
*/
Expr getBase() { toGenerated(result) = expr.getChild(0) }
override AstNode getAChild(string pred) {
@@ -781,13 +883,6 @@ class Import extends TImport, ModuleMember, ModuleRef {
result = imp.getChild(0).(Generated::ImportModuleExpr).getChild().getName(i).getValue()
}
final override predicate isPrivate() {
exists(Generated::ModuleMember member |
imp = member.getChild(_) and
member.getAFieldOrChild().(Generated::Annotation).getName().getValue() = "private"
)
}
final override FileOrModule getResolvedModule() { resolve(this, result) }
}
@@ -838,6 +933,10 @@ class ComparisonOp extends TComparisonOp, AstNode {
ComparisonOp() { this = TComparisonOp(op) }
/**
* Gets a string representing the operator.
* E.g. "<" or "=".
*/
ComparisonSymbol getSymbol() { result = op.getValue() }
override string getAPrimaryQlClass() { result = "ComparisonOp" }
@@ -878,6 +977,16 @@ class Integer extends Literal {
int getValue() { result = lit.getChild().(Generated::Integer).getValue().toInt() }
}
/** A float literal. */
class Float extends Literal {
Float() { lit.getChild() instanceof Generated::Float }
override string getAPrimaryQlClass() { result = "Float" }
/** Gets the float value of this literal. */
float getValue() { result = lit.getChild().(Generated::Float).getValue().toFloat() }
}
/** A comparison symbol, such as `"<"` or `"="`. */
class ComparisonSymbol extends string {
ComparisonSymbol() {
@@ -1066,8 +1175,6 @@ class InstanceOf extends TInstanceOf, Formula {
/** Gets the reference to the type being checked. */
TypeExpr getType() { toGenerated(result) = inst.getChild(1) }
/** Gets the type being checked. */
//QLTypeExpr getType() { result = getTypeRef().getType() }
override string getAPrimaryQlClass() { result = "InstanceOf" }
override AstNode getAChild(string pred) {
@@ -1079,13 +1186,25 @@ class InstanceOf extends TInstanceOf, Formula {
}
}
/**
* A in formula, such as `foo in [2, 3]`.
* The formula holds if the lhs is in the rhs.
*/
class InFormula extends TInFormula, Formula {
Generated::InExpr inexpr;
InFormula() { this = TInFormula(inexpr) }
/**
* Gets the expression that is checked for membership.
* E.g. for `foo in [2, 3]` the result is `foo`.
*/
Expr getExpr() { toGenerated(result) = inexpr.getLeft() }
/**
* Gets the range for this in formula.
* E.g. for `foo in [2, 3]` the result is `[2, 3]`.
*/
Expr getRange() { toGenerated(result) = inexpr.getRight() }
override string getAPrimaryQlClass() { result = "InFormula" }
@@ -1099,17 +1218,36 @@ class InFormula extends TInFormula, Formula {
}
}
/**
* A "call" to a high-order formula.
* E.g. `fastTC(pathSucc/2)(n1, n2)`.
*/
class HigherOrderFormula extends THigherOrderFormula, Formula {
Generated::HigherOrderTerm hop;
HigherOrderFormula() { this = THigherOrderFormula(hop) }
/**
* Gets the `i`th input to this higher-order formula.
* E.g. for `fastTC(pathSucc/2)(n1, n2)` the result is `pathSucc/2`.
*/
PredicateExpr getInput(int i) { toGenerated(result) = hop.getChild(i).(Generated::PredicateExpr) }
/**
* Gets the number of inputs.
*/
private int getNumInputs() { result = 1 + max(int i | exists(this.getInput(i))) }
/**
* Gets the `i`th argument to this higher-order formula.
* E.g. for `fastTC(pathSucc/2)(n1, n2)` the result is `n1` and `n2`.
*/
Expr getArgument(int i) { toGenerated(result) = hop.getChild(i + getNumInputs()) }
/**
* Gets the name of this higher-order predicate.
* E.g. for `fastTC(pathSucc/2)(n1, n2)` the result is "fastTC".
*/
string getName() { result = hop.getName().getValue() }
override string getAPrimaryQlClass() { result = "HigherOrderFormula" }
@@ -1125,6 +1263,10 @@ class HigherOrderFormula extends THigherOrderFormula, Formula {
}
}
/**
* An aggregate containing an expression.
* E.g. `min(getAPredicate().getArity())`.
*/
class ExprAggregate extends TExprAggregate, Expr {
Generated::Aggregate agg;
Generated::ExprAggregateBody body;
@@ -1136,6 +1278,10 @@ class ExprAggregate extends TExprAggregate, Expr {
body = agg.getChild(_)
}
/**
* Gets the kind of aggregate.
* E.g. for `min(foo())` the result is "min".
*/
string getKind() { result = kind }
/**
@@ -1180,6 +1326,10 @@ class Aggregate extends TAggregate, Expr {
body = agg.getChild(_)
}
/**
* Gets the kind of aggregate.
* E.g. for `min(int i | foo(i))` the result is "foo".
*/
string getKind() { result = kind }
/** Gets the ith declared argument of this quantifier. */
@@ -1288,6 +1438,9 @@ class AsExpr extends TAsExpr, VarDef, Expr {
}
}
/**
* An identifier, such as `foo`.
*/
class Identifier extends TIdentifier, Expr {
Generated::Variable id;
@@ -1377,15 +1530,28 @@ class Expr extends TExpr, AstNode {
Type getType() { none() }
}
/** An expression annotation, such as `pragma[only_bind_into](config)`. */
class ExprAnnotation extends TExprAnnotation, Expr {
Generated::ExprAnnotation expr_anno;
ExprAnnotation() { this = TExprAnnotation(expr_anno) }
/**
* Gets the name of the annotation.
* E.g. for `pragma[only_bind_into](config)` the result is "pragma".
*/
string getName() { result = expr_anno.getName().getValue() }
/**
* Gets the argument to this annotation.
* E.g. for `pragma[only_bind_into](config)` the result is "only_bind_into".
*/
string getAnnotationArgument() { result = expr_anno.getAnnotArg().getValue() }
/**
* Gets the inner expression.
* E.g. for `pragma[only_bind_into](config)` the result is `config`.
*/
Expr getExpression() { toGenerated(result) = expr_anno.getChild() }
override string getAPrimaryQlClass() { result = "ExprAnnotation" }
@@ -1593,7 +1759,7 @@ class DontCare extends TDontCare, Expr {
override string getAPrimaryQlClass() { result = "DontCare" }
}
/** A module expression. */
/** A module expression. Such as `DataFlow` in `DataFlow::Node` */
class ModuleExpr extends TModuleExpr, ModuleRef {
Generated::ModuleExpr me;

View File

@@ -4,9 +4,7 @@ import TreeSitter
cached
newtype TAstNode =
TTopLevel(Generated::Ql file) or
TClasslessPredicate(Generated::ModuleMember member, Generated::ClasslessPredicate pred) {
pred.getParent() = member
} or
TClasslessPredicate(Generated::ClasslessPredicate pred) or
TVarDecl(Generated::VarDecl decl) or
TClass(Generated::Dataclass dc) or
TCharPred(Generated::Charpred pred) or
@@ -119,7 +117,7 @@ Generated::AstNode toGenerated(AST::AstNode n) {
or
n = TTopLevel(result)
or
n = TClasslessPredicate(_, result)
n = TClasslessPredicate(result)
or
n = TVarDecl(result)
or

View File

@@ -72,9 +72,7 @@ class PrintAstNode extends AstNode {
/**
* Gets the child node that is accessed using the predicate `edgeName`.
*/
PrintAstNode getChild(string edgeName) {
result = this.getAChild(edgeName)
}
PrintAstNode getChild(string edgeName) { result = this.getAChild(edgeName) }
}
private predicate shouldPrintNode(AstNode n) {

View File

@@ -15,6 +15,6 @@ string getQualifiedName(ClassPredicate p) {
}
from ClassPredicate pred, ClassPredicate sup
where pred.overrides(sup) and not pred.hasAnnotation("override")
where pred.overrides(sup) and not pred.isOverride()
select pred, getQualifiedName(pred) + "overrides $@ but does not have an override annotation.", sup,
getQualifiedName(sup)