From 51fbee69c246c38993dfb91dcbe6c7763b86028d Mon Sep 17 00:00:00 2001 From: Taus Date: Fri, 28 May 2021 17:05:44 +0000 Subject: [PATCH 1/6] QL: Add AST nodes for QLDoc --- ql/src/codeql_ql/ast/Ast.qll | 87 +++++++++++++++++++++- ql/src/codeql_ql/ast/internal/AstNodes.qll | 7 +- 2 files changed, 88 insertions(+), 6 deletions(-) diff --git a/ql/src/codeql_ql/ast/Ast.qll b/ql/src/codeql_ql/ast/Ast.qll index dc378cf190e..101e24d568d 100644 --- a/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/src/codeql_ql/ast/Ast.qll @@ -56,6 +56,9 @@ class AstNode extends TAstNode { * Gets the primary QL class for the ast node. */ string getAPrimaryQlClass() { result = "???" } + + /** Gets the QLDoc comment for this AST node, if any. */ + QLDoc getQLDoc() { none() } } /** A toplevel QL program, i.e. a file. */ @@ -70,11 +73,49 @@ class TopLevel extends TTopLevel, AstNode { */ ModuleMember getAMember() { toGenerated(result) = file.getChild(_).getChild(_) } + ModuleMember getMember(int i) { toGenerated(result) = file.getChild(i).getChild(_) } + + /** Gets a top-level import in this module. */ + Import getAnImport() { result = this.getAMember() } + + /** Gets a top-level class in this module. */ + Class getAClass() { result = this.getAMember() } + + /** Gets a top-level predicate in this module. */ + ClasslessPredicate getAPredicate() { result = this.getAMember() } + + /** Gets a module defined at the top-level module of this module. */ + Module getAModule() { result = this.getAMember() } + override ModuleMember getAChild(string pred) { pred = directMember("getAMember") and result = this.getAMember() + or + pred = directMember("getQLDoc") and result = this.getQLDoc() + or + pred = directMember("getAnImport") and result = this.getAnImport() + or + pred = directMember("getAClass") and result = this.getAClass() + or + pred = directMember("getAPredicate") and result = this.getAPredicate() + } + + QLDoc getQLDocFor(ModuleMember m) { + exists(int i | i > 0 and result = this.getMember(i) and m = this.getMember(i + 1)) } override string getAPrimaryQlClass() { result = "TopLevel" } + + override QLDoc getQLDoc() { toGenerated(result) = file.getChild(0).getChild(0) } +} + +class QLDoc extends TQLDoc, AstNode { + Generated::Qldoc qldoc; + + QLDoc() { this = TQLDoc(qldoc) } + + string getContents() { result = qldoc.getValue() } + + override string getAPrimaryQlClass() { result = "QLDoc" } } /** @@ -126,7 +167,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 { +class Predicate extends TPredicate, AstNode, Declaration { /** * Gets the body of the predicate. */ @@ -135,7 +176,7 @@ class Predicate extends TPredicate, AstNode { /** * Gets the name of the predicate. */ - string getName() { none() } + override string getName() { none() } /** * Gets the `i`th parameter of the predicate. @@ -373,7 +414,7 @@ class VarDef extends TVarDef, AstNode { /** * A variable declaration, with a type and a name. */ -class VarDecl extends TVarDecl, VarDef { +class VarDecl extends TVarDecl, VarDef, Declaration { Generated::VarDecl var; VarDecl() { this = TVarDecl(var) } @@ -412,6 +453,8 @@ class VarDecl extends TVarDecl, VarDef { or pred = directMember("getTypeExpr") and result = this.getTypeExpr() } + + override string toString() { result = Declaration.super.toString() } } /** @@ -485,6 +528,14 @@ class Module extends TModule, ModuleDeclaration { toGenerated(result) = mod.getChild(_).(Generated::ModuleMember).getChild(_) } + AstNode getMember(int i) { + toGenerated(result) = mod.getChild(i).(Generated::ModuleMember).getChild(_) + } + + QLDoc getQLDocFor(AstNode m) { + exists(int i | result = this.getMember(i) and m = this.getMember(i + 1)) + } + /** Gets the module expression that this module is an alias for, if any. */ ModuleExpr getAlias() { toGenerated(result) = mod.getAFieldOrChild().(Generated::ModuleAliasBody).getChild() @@ -512,7 +563,21 @@ class Declaration extends TDeclaration, AstNode { /** Gets the name of this declaration. */ string getName() { none() } - final override string toString() { result = this.getName() } + override string toString() { result = this.getName() } + + override QLDoc getQLDoc() { + result = any(TopLevel m).getQLDocFor(this) + or + result = any(Module m).getQLDocFor(this) + or + result = any(Class c).getQLDocFor(this) + } + + override AstNode getAChild(string pred) { + result = super.getAChild(pred) + or + pred = directMember("getQLDoc") and result = this.getQLDoc() + } } /** An entity that can be declared in a module. */ @@ -540,6 +605,16 @@ class Class extends TClass, TypeDeclaration, ModuleDeclaration { toGenerated(result) = cls.getChild(_).(Generated::ClassMember).getChild(_) } + AstNode getMember(int i) { + toGenerated(result) = cls.getChild(i).(Generated::ClassMember).getChild(_) or + toGenerated(result) = + cls.getChild(i).(Generated::ClassMember).getChild(_).(Generated::Field).getChild() + } + + QLDoc getQLDocFor(AstNode m) { + exists(int i | result = this.getMember(i) and m = this.getMember(i + 1)) + } + /** * Gets a predicate in this class. */ @@ -651,6 +726,8 @@ class NewTypeBranch extends TNewTypeBranch, TypeDeclaration { /** Gets the body of this branch. */ Formula getBody() { toGenerated(result) = branch.getChild(_).(Generated::Body).getChild() } + override QLDoc getQLDoc() { toGenerated(result) = branch.getChild(_) } + NewType getNewType() { result.getABranch() = this } override AstNode getAChild(string pred) { @@ -659,6 +736,8 @@ class NewTypeBranch extends TNewTypeBranch, TypeDeclaration { pred = directMember("getBody") and result = this.getBody() or exists(int i | pred = indexedMember("getField", i) and result = this.getField(i)) + or + pred = directMember("getQLDoc") and result = this.getQLDoc() } } diff --git a/ql/src/codeql_ql/ast/internal/AstNodes.qll b/ql/src/codeql_ql/ast/internal/AstNodes.qll index d3f5bb6e2e3..a74cc439d2a 100644 --- a/ql/src/codeql_ql/ast/internal/AstNodes.qll +++ b/ql/src/codeql_ql/ast/internal/AstNodes.qll @@ -4,6 +4,7 @@ import TreeSitter cached newtype TAstNode = TTopLevel(Generated::Ql file) or + TQLDoc(Generated::Qldoc qldoc) or TClasslessPredicate(Generated::ClasslessPredicate pred) or TVarDecl(Generated::VarDecl decl) or TClass(Generated::Dataclass dc) or @@ -117,6 +118,8 @@ Generated::AstNode toGenerated(AST::AstNode n) { or n = TTopLevel(result) or + n = TQLDoc(result) + or n = TClasslessPredicate(result) or n = TVarDecl(result) @@ -158,9 +161,9 @@ Generated::AstNode toGenerated(AST::AstNode n) { class TPredicate = TCharPred or TClasslessPredicate or TClassPredicate; -class TModuleMember = TModuleDeclaration or TImport or TSelect; +class TModuleMember = TModuleDeclaration or TImport or TSelect or TQLDoc; -class TDeclaration = TTypeDeclaration or TModuleDeclaration; +class TDeclaration = TTypeDeclaration or TModuleDeclaration or TPredicate or TVarDecl; class TTypeDeclaration = TClass or TNewType or TNewTypeBranch; From 24230dc205bfc7580c944d2b21abd13c7bad1e42 Mon Sep 17 00:00:00 2001 From: Taus Date: Fri, 28 May 2021 21:12:02 +0000 Subject: [PATCH 2/6] QL: Remove `getAMember` from `getAChild` Adds `getAQLDocComment` for accessing those module members that are simply QLDoc comments (apart from the one that applies to the module itself, which is still accessed through `getQLDoc`.) --- ql/src/codeql_ql/ast/Ast.qll | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ql/src/codeql_ql/ast/Ast.qll b/ql/src/codeql_ql/ast/Ast.qll index 101e24d568d..032238f69d7 100644 --- a/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/src/codeql_ql/ast/Ast.qll @@ -84,11 +84,18 @@ class TopLevel extends TTopLevel, AstNode { /** Gets a top-level predicate in this module. */ ClasslessPredicate getAPredicate() { result = this.getAMember() } + /** + * Gets a QLDoc comment for a top-level entity in this module. + * + * Use `getQLDoc` if you want the QLDoc for the module itself. + */ + QLDoc getAQLDocComment() { result = getQLDocFor(_) } + /** Gets a module defined at the top-level module of this module. */ Module getAModule() { result = this.getAMember() } override ModuleMember getAChild(string pred) { - pred = directMember("getAMember") and result = this.getAMember() + pred = directMember("getAQLDocComment") and result = this.getAQLDocComment() or pred = directMember("getQLDoc") and result = this.getQLDoc() or From 109f9389687e2e5f6cef510d1de6caf56a7ecec2 Mon Sep 17 00:00:00 2001 From: Taus Date: Fri, 28 May 2021 21:44:41 +0000 Subject: [PATCH 3/6] QL: Add `getAModule` and `getANewType` Also removes `getAQLDocComment`, as those were already dangling off of their respective successors in the file (and so should not dangle off of the top level as well). --- ql/src/codeql_ql/ast/Ast.qll | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/ql/src/codeql_ql/ast/Ast.qll b/ql/src/codeql_ql/ast/Ast.qll index 032238f69d7..eaebf4d1273 100644 --- a/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/src/codeql_ql/ast/Ast.qll @@ -84,19 +84,13 @@ class TopLevel extends TTopLevel, AstNode { /** Gets a top-level predicate in this module. */ ClasslessPredicate getAPredicate() { result = this.getAMember() } - /** - * Gets a QLDoc comment for a top-level entity in this module. - * - * Use `getQLDoc` if you want the QLDoc for the module itself. - */ - QLDoc getAQLDocComment() { result = getQLDocFor(_) } - - /** Gets a module defined at the top-level module of this module. */ + /** Gets a module defined at the top-level of this module. */ Module getAModule() { result = this.getAMember() } + /** Gets a `newtype` defined at the top-level of this module. */ + NewType getANewType() { result = this.getAMember() } + override ModuleMember getAChild(string pred) { - pred = directMember("getAQLDocComment") and result = this.getAQLDocComment() - or pred = directMember("getQLDoc") and result = this.getQLDoc() or pred = directMember("getAnImport") and result = this.getAnImport() @@ -104,6 +98,10 @@ class TopLevel extends TTopLevel, AstNode { pred = directMember("getAClass") and result = this.getAClass() or pred = directMember("getAPredicate") and result = this.getAPredicate() + or + pred = directMember("getAModule") and result = this.getAModule() + or + pred = directMember("getANewType") and result = this.getANewType() } QLDoc getQLDocFor(ModuleMember m) { From 23e4281ddb2021e2eb71a1185ff8884b5bce19a0 Mon Sep 17 00:00:00 2001 From: Taus Date: Fri, 28 May 2021 22:00:15 +0000 Subject: [PATCH 4/6] QL: Fix tests I'm not really a fan of `toString`s that don't indicate the type of the object, so I added a reference to `getAPrimaryQlClass`. Hopefully this should result in less noise in the diff. --- ql/src/codeql_ql/ast/Ast.qll | 4 +- ql/test/printAst/printAst.expected | 76 +++++++++---------- .../MissingOverride/MissingOverride.expected | 2 +- 3 files changed, 41 insertions(+), 41 deletions(-) diff --git a/ql/src/codeql_ql/ast/Ast.qll b/ql/src/codeql_ql/ast/Ast.qll index eaebf4d1273..63d365d1bc6 100644 --- a/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/src/codeql_ql/ast/Ast.qll @@ -459,7 +459,7 @@ class VarDecl extends TVarDecl, VarDef, Declaration { pred = directMember("getTypeExpr") and result = this.getTypeExpr() } - override string toString() { result = Declaration.super.toString() } + override string toString() { result = this.getName() } } /** @@ -568,7 +568,7 @@ class Declaration extends TDeclaration, AstNode { /** Gets the name of this declaration. */ string getName() { none() } - override string toString() { result = this.getName() } + override string toString() { result = this.getAPrimaryQlClass() + " " + this.getName() } override QLDoc getQLDoc() { result = any(TopLevel m).getQLDocFor(this) diff --git a/ql/test/printAst/printAst.expected b/ql/test/printAst/printAst.expected index ddff8033d5a..e60995af312 100644 --- a/ql/test/printAst/printAst.expected +++ b/ql/test/printAst/printAst.expected @@ -3,12 +3,12 @@ nodes | Foo.qll:1:1:1:17 | Import | semmle.order | 1 | | Foo.qll:1:1:25:2 | TopLevel | semmle.label | [TopLevel] TopLevel | | Foo.qll:1:1:25:2 | TopLevel | semmle.order | 1 | -| Foo.qll:3:1:7:1 | Foo | semmle.label | [Class] Foo | -| Foo.qll:3:1:7:1 | Foo | semmle.order | 3 | +| Foo.qll:3:1:7:1 | Class Foo | semmle.label | [Class] Class Foo | +| Foo.qll:3:1:7:1 | Class Foo | semmle.order | 3 | | Foo.qll:3:19:3:22 | TypeExpr | semmle.label | [TypeExpr] TypeExpr | | Foo.qll:3:19:3:22 | TypeExpr | semmle.order | 4 | -| Foo.qll:4:3:4:17 | CharPred | semmle.label | [CharPred] CharPred | -| Foo.qll:4:3:4:17 | CharPred | semmle.order | 5 | +| Foo.qll:4:3:4:17 | CharPred Foo | semmle.label | [CharPred] CharPred Foo | +| Foo.qll:4:3:4:17 | CharPred Foo | semmle.order | 5 | | Foo.qll:4:11:4:11 | Integer | semmle.label | [Integer] Integer | | Foo.qll:4:11:4:11 | Integer | semmle.order | 6 | | Foo.qll:4:11:4:15 | ComparisonFormula | semmle.label | [ComparisonFormula] ComparisonFormula | @@ -19,8 +19,8 @@ nodes | Foo.qll:4:15:4:15 | Integer | semmle.order | 9 | | Foo.qll:6:3:6:8 | TypeExpr | semmle.label | [TypeExpr] TypeExpr | | Foo.qll:6:3:6:8 | TypeExpr | semmle.order | 10 | -| Foo.qll:6:3:6:38 | ClassPredicate | semmle.label | [ClassPredicate] ClassPredicate | -| Foo.qll:6:3:6:38 | ClassPredicate | semmle.order | 10 | +| Foo.qll:6:3:6:38 | ClassPredicate toString | semmle.label | [ClassPredicate] ClassPredicate toString | +| Foo.qll:6:3:6:38 | ClassPredicate toString | semmle.order | 10 | | Foo.qll:6:23:6:28 | result | semmle.label | [ResultAccess] result | | Foo.qll:6:23:6:28 | result | semmle.order | 12 | | Foo.qll:6:23:6:36 | ComparisonFormula | semmle.label | [ComparisonFormula] ComparisonFormula | @@ -29,8 +29,8 @@ nodes | Foo.qll:6:30:6:30 | ComparisonOp | semmle.order | 14 | | Foo.qll:6:32:6:36 | String | semmle.label | [String] String | | Foo.qll:6:32:6:36 | String | semmle.order | 15 | -| Foo.qll:9:7:11:1 | foo | semmle.label | [ClasslessPredicate] foo | -| Foo.qll:9:7:11:1 | foo | semmle.order | 16 | +| Foo.qll:9:7:11:1 | ClasslessPredicate foo | semmle.label | [ClasslessPredicate] ClasslessPredicate foo | +| Foo.qll:9:7:11:1 | ClasslessPredicate foo | semmle.order | 16 | | Foo.qll:9:21:9:23 | TypeExpr | semmle.label | [TypeExpr] TypeExpr | | Foo.qll:9:21:9:23 | TypeExpr | semmle.order | 17 | | Foo.qll:9:21:9:25 | f | semmle.label | [VarDecl] f | @@ -65,8 +65,8 @@ nodes | Foo.qll:10:69:10:73 | inner | semmle.order | 32 | | Foo.qll:10:69:10:84 | MemberCall | semmle.label | [MemberCall] MemberCall | | Foo.qll:10:69:10:84 | MemberCall | semmle.order | 32 | -| Foo.qll:13:1:25:1 | calls | semmle.label | [ClasslessPredicate] calls | -| Foo.qll:13:1:25:1 | calls | semmle.order | 34 | +| Foo.qll:13:1:25:1 | ClasslessPredicate calls | semmle.label | [ClasslessPredicate] ClasslessPredicate calls | +| Foo.qll:13:1:25:1 | ClasslessPredicate calls | semmle.order | 34 | | Foo.qll:13:17:13:19 | TypeExpr | semmle.label | [TypeExpr] TypeExpr | | Foo.qll:13:17:13:19 | TypeExpr | semmle.order | 35 | | Foo.qll:13:17:13:21 | f | semmle.label | [VarDecl] f | @@ -164,42 +164,42 @@ nodes | printAst.ql:1:1:1:29 | TopLevel | semmle.label | [TopLevel] TopLevel | | printAst.ql:1:1:1:29 | TopLevel | semmle.order | 81 | edges -| Foo.qll:1:1:25:2 | TopLevel | Foo.qll:1:1:1:17 | Import | semmle.label | getAMember() | +| Foo.qll:1:1:25:2 | TopLevel | Foo.qll:1:1:1:17 | Import | semmle.label | getAnImport() | | Foo.qll:1:1:25:2 | TopLevel | Foo.qll:1:1:1:17 | Import | semmle.order | 1 | -| Foo.qll:1:1:25:2 | TopLevel | Foo.qll:3:1:7:1 | Foo | semmle.label | getAMember() | -| Foo.qll:1:1:25:2 | TopLevel | Foo.qll:3:1:7:1 | Foo | semmle.order | 3 | -| Foo.qll:1:1:25:2 | TopLevel | Foo.qll:9:7:11:1 | foo | semmle.label | getAMember() | -| Foo.qll:1:1:25:2 | TopLevel | Foo.qll:9:7:11:1 | foo | semmle.order | 16 | -| Foo.qll:1:1:25:2 | TopLevel | Foo.qll:13:1:25:1 | calls | semmle.label | getAMember() | -| Foo.qll:1:1:25:2 | TopLevel | Foo.qll:13:1:25:1 | calls | semmle.order | 34 | -| Foo.qll:3:1:7:1 | Foo | Foo.qll:3:19:3:22 | TypeExpr | semmle.label | getASuperType() | -| Foo.qll:3:1:7:1 | Foo | Foo.qll:3:19:3:22 | TypeExpr | semmle.order | 4 | -| Foo.qll:3:1:7:1 | Foo | Foo.qll:4:3:4:17 | CharPred | semmle.label | getCharPred() | -| Foo.qll:3:1:7:1 | Foo | Foo.qll:4:3:4:17 | CharPred | semmle.order | 5 | -| Foo.qll:3:1:7:1 | Foo | Foo.qll:6:3:6:38 | ClassPredicate | semmle.label | getClassPredicate(_) | -| Foo.qll:3:1:7:1 | Foo | Foo.qll:6:3:6:38 | ClassPredicate | semmle.order | 10 | -| Foo.qll:4:3:4:17 | CharPred | Foo.qll:4:11:4:15 | ComparisonFormula | semmle.label | getBody() | -| Foo.qll:4:3:4:17 | CharPred | Foo.qll:4:11:4:15 | ComparisonFormula | semmle.order | 6 | +| Foo.qll:1:1:25:2 | TopLevel | Foo.qll:3:1:7:1 | Class Foo | semmle.label | getAClass() | +| Foo.qll:1:1:25:2 | TopLevel | Foo.qll:3:1:7:1 | Class Foo | semmle.order | 3 | +| Foo.qll:1:1:25:2 | TopLevel | Foo.qll:9:7:11:1 | ClasslessPredicate foo | semmle.label | getAPredicate() | +| Foo.qll:1:1:25:2 | TopLevel | Foo.qll:9:7:11:1 | ClasslessPredicate foo | semmle.order | 16 | +| Foo.qll:1:1:25:2 | TopLevel | Foo.qll:13:1:25:1 | ClasslessPredicate calls | semmle.label | getAPredicate() | +| Foo.qll:1:1:25:2 | TopLevel | Foo.qll:13:1:25:1 | ClasslessPredicate calls | semmle.order | 34 | +| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:3:19:3:22 | TypeExpr | semmle.label | getASuperType() | +| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:3:19:3:22 | TypeExpr | semmle.order | 4 | +| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:4:3:4:17 | CharPred Foo | semmle.label | getCharPred() | +| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:4:3:4:17 | CharPred Foo | semmle.order | 5 | +| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:6:3:6:38 | ClassPredicate toString | semmle.label | getClassPredicate(_) | +| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:6:3:6:38 | ClassPredicate toString | semmle.order | 10 | +| Foo.qll:4:3:4:17 | CharPred Foo | Foo.qll:4:11:4:15 | ComparisonFormula | semmle.label | getBody() | +| Foo.qll:4:3:4:17 | CharPred Foo | Foo.qll:4:11:4:15 | ComparisonFormula | semmle.order | 6 | | Foo.qll:4:11:4:15 | ComparisonFormula | Foo.qll:4:11:4:11 | Integer | semmle.label | getLeftOperand() | | Foo.qll:4:11:4:15 | ComparisonFormula | Foo.qll:4:11:4:11 | Integer | semmle.order | 6 | | Foo.qll:4:11:4:15 | ComparisonFormula | Foo.qll:4:13:4:13 | ComparisonOp | semmle.label | getOperator() | | Foo.qll:4:11:4:15 | ComparisonFormula | Foo.qll:4:13:4:13 | ComparisonOp | semmle.order | 8 | | Foo.qll:4:11:4:15 | ComparisonFormula | Foo.qll:4:15:4:15 | Integer | semmle.label | getRightOperand() | | Foo.qll:4:11:4:15 | ComparisonFormula | Foo.qll:4:15:4:15 | Integer | semmle.order | 9 | -| Foo.qll:6:3:6:38 | ClassPredicate | Foo.qll:6:3:6:8 | TypeExpr | semmle.label | getReturnTypeExpr() | -| Foo.qll:6:3:6:38 | ClassPredicate | Foo.qll:6:3:6:8 | TypeExpr | semmle.order | 10 | -| Foo.qll:6:3:6:38 | ClassPredicate | Foo.qll:6:23:6:36 | ComparisonFormula | semmle.label | getBody() | -| Foo.qll:6:3:6:38 | ClassPredicate | Foo.qll:6:23:6:36 | ComparisonFormula | semmle.order | 12 | +| Foo.qll:6:3:6:38 | ClassPredicate toString | Foo.qll:6:3:6:8 | TypeExpr | semmle.label | getReturnTypeExpr() | +| Foo.qll:6:3:6:38 | ClassPredicate toString | Foo.qll:6:3:6:8 | TypeExpr | semmle.order | 10 | +| Foo.qll:6:3:6:38 | ClassPredicate toString | Foo.qll:6:23:6:36 | ComparisonFormula | semmle.label | getBody() | +| Foo.qll:6:3:6:38 | ClassPredicate toString | Foo.qll:6:23:6:36 | ComparisonFormula | semmle.order | 12 | | Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:23:6:28 | result | semmle.label | getLeftOperand() | | Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:23:6:28 | result | semmle.order | 12 | | Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:30:6:30 | ComparisonOp | semmle.label | getOperator() | | Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:30:6:30 | ComparisonOp | semmle.order | 14 | | Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:32:6:36 | String | semmle.label | getRightOperand() | | Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:32:6:36 | String | semmle.order | 15 | -| Foo.qll:9:7:11:1 | foo | Foo.qll:9:21:9:25 | f | semmle.label | getParameter(_) | -| Foo.qll:9:7:11:1 | foo | Foo.qll:9:21:9:25 | f | semmle.order | 17 | -| Foo.qll:9:7:11:1 | foo | Foo.qll:10:3:10:85 | ComparisonFormula | semmle.label | getBody() | -| Foo.qll:9:7:11:1 | foo | Foo.qll:10:3:10:85 | ComparisonFormula | semmle.order | 19 | +| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:9:21:9:25 | f | semmle.label | getParameter(_) | +| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:9:21:9:25 | f | semmle.order | 17 | +| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:10:3:10:85 | ComparisonFormula | semmle.label | getBody() | +| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:10:3:10:85 | ComparisonFormula | semmle.order | 19 | | Foo.qll:9:21:9:25 | f | Foo.qll:9:21:9:23 | TypeExpr | semmle.label | getTypeExpr() | | Foo.qll:9:21:9:25 | f | Foo.qll:9:21:9:23 | TypeExpr | semmle.order | 17 | | Foo.qll:10:3:10:85 | ComparisonFormula | Foo.qll:10:3:10:3 | f | semmle.label | getLeftOperand() | @@ -230,10 +230,10 @@ edges | Foo.qll:10:27:10:50 | ComparisonFormula | Foo.qll:10:46:10:50 | String | semmle.order | 30 | | Foo.qll:10:69:10:84 | MemberCall | Foo.qll:10:69:10:73 | inner | semmle.label | getBase() | | Foo.qll:10:69:10:84 | MemberCall | Foo.qll:10:69:10:73 | inner | semmle.order | 32 | -| Foo.qll:13:1:25:1 | calls | Foo.qll:13:17:13:21 | f | semmle.label | getParameter(_) | -| Foo.qll:13:1:25:1 | calls | Foo.qll:13:17:13:21 | f | semmle.order | 35 | -| Foo.qll:13:1:25:1 | calls | Foo.qll:14:3:24:23 | Disjunction | semmle.label | getBody() | -| Foo.qll:13:1:25:1 | calls | Foo.qll:14:3:24:23 | Disjunction | semmle.order | 37 | +| Foo.qll:13:1:25:1 | ClasslessPredicate calls | Foo.qll:13:17:13:21 | f | semmle.label | getParameter(_) | +| Foo.qll:13:1:25:1 | ClasslessPredicate calls | Foo.qll:13:17:13:21 | f | semmle.order | 35 | +| Foo.qll:13:1:25:1 | ClasslessPredicate calls | Foo.qll:14:3:24:23 | Disjunction | semmle.label | getBody() | +| Foo.qll:13:1:25:1 | ClasslessPredicate calls | Foo.qll:14:3:24:23 | Disjunction | semmle.order | 37 | | Foo.qll:13:17:13:21 | f | Foo.qll:13:17:13:19 | TypeExpr | semmle.label | getTypeExpr() | | Foo.qll:13:17:13:21 | f | Foo.qll:13:17:13:19 | TypeExpr | semmle.order | 35 | | Foo.qll:14:3:14:10 | PredicateCall | Foo.qll:14:9:14:9 | f | semmle.label | getArgument(_) | @@ -322,7 +322,7 @@ edges | Foo.qll:24:17:24:21 | AddExpr | Foo.qll:24:17:24:17 | Integer | semmle.order | 78 | | Foo.qll:24:17:24:21 | AddExpr | Foo.qll:24:21:24:21 | Integer | semmle.label | getRightOperand() | | Foo.qll:24:17:24:21 | AddExpr | Foo.qll:24:21:24:21 | Integer | semmle.order | 80 | -| printAst.ql:1:1:1:29 | TopLevel | printAst.ql:1:1:1:28 | Import | semmle.label | getAMember() | +| printAst.ql:1:1:1:29 | TopLevel | printAst.ql:1:1:1:28 | Import | semmle.label | getAnImport() | | printAst.ql:1:1:1:29 | TopLevel | printAst.ql:1:1:1:28 | Import | semmle.order | 81 | graphProperties | semmle.graphKind | tree | diff --git a/ql/test/queries/style/MissingOverride/MissingOverride.expected b/ql/test/queries/style/MissingOverride/MissingOverride.expected index d6a2a7e365d..bd5a4153c9d 100644 --- a/ql/test/queries/style/MissingOverride/MissingOverride.expected +++ b/ql/test/queries/style/MissingOverride/MissingOverride.expected @@ -1 +1 @@ -| Test.qll:12:3:12:33 | ClassPredicate | Wrong.testoverrides $@ but does not have an override annotation. | Test.qll:4:3:4:40 | ClassPredicate | Super.test | +| Test.qll:12:3:12:33 | ClassPredicate test | Wrong.testoverrides $@ but does not have an override annotation. | Test.qll:4:3:4:40 | ClassPredicate test | Super.test | From 1feb35efb70292a68d0b02045b106dadcabd6462 Mon Sep 17 00:00:00 2001 From: Taus Date: Sat, 29 May 2021 08:07:44 +0000 Subject: [PATCH 5/6] QL: Fix test output --- ql/test/queries/style/MissingOverride/MissingOverride.expected | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ql/test/queries/style/MissingOverride/MissingOverride.expected b/ql/test/queries/style/MissingOverride/MissingOverride.expected index bd5a4153c9d..f59b21d0d73 100644 --- a/ql/test/queries/style/MissingOverride/MissingOverride.expected +++ b/ql/test/queries/style/MissingOverride/MissingOverride.expected @@ -1 +1 @@ -| Test.qll:12:3:12:33 | ClassPredicate test | Wrong.testoverrides $@ but does not have an override annotation. | Test.qll:4:3:4:40 | ClassPredicate test | Super.test | +| Test.qll:12:3:12:33 | ClassPredicate test | Wrong.test overrides $@ but does not have an override annotation. | Test.qll:4:3:4:40 | ClassPredicate test | Super.test | From 855683e980f5cac6f1d58a744a03f70e4341f5cb Mon Sep 17 00:00:00 2001 From: Taus Date: Mon, 31 May 2021 10:26:50 +0200 Subject: [PATCH 6/6] QL: Simplify `getAMember` Co-authored-by: Erik Krogh Kristensen --- ql/src/codeql_ql/ast/Ast.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ql/src/codeql_ql/ast/Ast.qll b/ql/src/codeql_ql/ast/Ast.qll index af03bc1ba56..d7cb876f5ea 100644 --- a/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/src/codeql_ql/ast/Ast.qll @@ -80,7 +80,7 @@ class TopLevel extends TTopLevel, AstNode { * Gets a member from contained in this top-level module. * Includes private members. */ - ModuleMember getAMember() { toGenerated(result) = file.getChild(_).getChild(_) } + ModuleMember getAMember() { result = getMember(_) } ModuleMember getMember(int i) { toGenerated(result) = file.getChild(i).getChild(_) }