Skip to content

Commit 3a3f809

Browse files
authored
QL: Merge pull request #16 from github/var-resolution
Variable resolution
2 parents bf98e96 + ef69a46 commit 3a3f809

7 files changed

Lines changed: 163 additions & 145 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import codeql_ql.ast.internal.Variable::VarConsistency

ql/src/codeql_ql/ast/Ast.qll

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ private import codeql_ql.ast.internal.AstNodes
33
private import codeql_ql.ast.internal.Module
44
private import codeql_ql.ast.internal.Predicate
55
private import codeql_ql.ast.internal.Type
6+
private import codeql_ql.ast.internal.Variable
67

78
bindingset[name, i]
89
private string indexedMember(string name, int i) { result = name + "(" + i.toString() + ")" }
@@ -1172,6 +1173,18 @@ class Identifier extends TIdentifier, Expr {
11721173
override string getAPrimaryQlClass() { result = "Identifier" }
11731174
}
11741175

1176+
/** An access to a variable. */
1177+
class VarAccess extends Identifier {
1178+
private VarDecl decl;
1179+
1180+
VarAccess() { resolveVariable(this, decl) }
1181+
1182+
/** Gets the accessed variable. */
1183+
VarDecl getDeclaration() { result = decl }
1184+
1185+
override string getAPrimaryQlClass() { result = "VarAccess" }
1186+
}
1187+
11751188
/** A `not` formula. */
11761189
class Negation extends TNegation, Formula {
11771190
Generated::Negation neg;
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import ql
2+
import codeql_ql.ast.internal.AstNodes
3+
4+
private class TScope =
5+
TClass or TAggregate or TQuantifier or TSelect or TPredicate or TNewTypeBranch;
6+
7+
/** A variable scope. */
8+
class VariableScope extends TScope, AstNode {
9+
/** Gets the outer scope, if any. */
10+
VariableScope getOuterScope() { result = scopeOf(this) }
11+
12+
/** Gets a variable declared directly in this scope. */
13+
VarDecl getADeclaration() { result.getParent() = this }
14+
15+
/** Holds if this scope contains declaration `decl`, either directly or inherited. */
16+
predicate contains(VarDecl decl) {
17+
decl = this.getADeclaration()
18+
or
19+
this.getOuterScope().contains(decl) and
20+
not this.getADeclaration().getName() = decl.getName()
21+
}
22+
}
23+
24+
private AstNode parent(AstNode child) {
25+
result = child.getParent() and
26+
not child instanceof VariableScope
27+
}
28+
29+
VariableScope scopeOf(AstNode n) { result = parent*(n.getParent()) }
30+
31+
predicate resolveVariable(Identifier i, VarDecl decl) {
32+
scopeOf(i).contains(decl) and
33+
decl.getName() = i.getName()
34+
}
35+
36+
module VarConsistency {
37+
query predicate multipleVarDecls(VarAccess v, VarDecl decl) {
38+
decl = v.getDeclaration() and
39+
strictcount(v.getDeclaration()) > 1
40+
}
41+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import ql
2+
import codeql_ql.ast.internal.Module
3+
import codeql.IDEContextual
4+
5+
private newtype TLoc =
6+
TAst(AstNode n) or
7+
TFileOrModule(FileOrModule m)
8+
9+
class Loc extends TLoc {
10+
string toString() { result = "" }
11+
12+
AstNode asAst() { this = TAst(result) }
13+
14+
FileOrModule asMod() { this = TFileOrModule(result) }
15+
16+
File getFile() { this.hasLocationInfo(result.getAbsolutePath(), _, _, _, _) }
17+
18+
predicate hasLocationInfo(
19+
string filepath, int startline, int startcolumn, int endline, int endcolumn
20+
) {
21+
exists(AstNode n | this = TAst(n) |
22+
n.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
23+
)
24+
or
25+
exists(FileOrModule m | this = TFileOrModule(m) |
26+
m.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
27+
)
28+
}
29+
}
30+
31+
private predicate resolveModule(ModuleRef ref, FileOrModule target, string kind) {
32+
target = ref.getResolvedModule() and
33+
kind = "module"
34+
}
35+
36+
private predicate resolveType(TypeExpr ref, AstNode target, string kind) {
37+
target = ref.getResolvedType().getDeclaration() and
38+
kind = "type"
39+
}
40+
41+
private predicate resolvePredicate(PredicateExpr ref, Predicate target, string kind) {
42+
target = ref.getResolvedPredicate() and
43+
kind = "predicate"
44+
}
45+
46+
private predicate resolveVar(VarAccess va, VarDecl decl, string kind) {
47+
decl = va.getDeclaration() and
48+
kind = "variable"
49+
}
50+
51+
cached
52+
predicate resolve(Loc ref, Loc target, string kind) {
53+
resolveModule(ref.asAst(), target.asMod(), kind)
54+
or
55+
resolveType(ref.asAst(), target.asAst(), kind)
56+
or
57+
resolvePredicate(ref.asAst(), target.asAst(), kind)
58+
or
59+
resolveVar(ref.asAst(), target.asAst(), kind)
60+
}

ql/src/ide-contextual-queries/localDefinitions.ql

Lines changed: 4 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -8,62 +8,13 @@
88
*/
99

1010
import ql
11-
import codeql_ql.ast.internal.Module
12-
import codeql_ql.ast.internal.Type
11+
import Definitions
1312
import codeql.IDEContextual
1413

1514
external string selectedSourceFile();
1615

17-
newtype TLoc =
18-
TAst(AstNode n) or
19-
TFileOrModule(FileOrModule m)
20-
21-
class Loc extends TLoc {
22-
string toString() { result = "" }
23-
24-
AstNode asAst() { this = TAst(result) }
25-
26-
FileOrModule asMod() { this = TFileOrModule(result) }
27-
28-
predicate hasLocationInfo(
29-
string filepath, int startline, int startcolumn, int endline, int endcolumn
30-
) {
31-
exists(AstNode n | this = TAst(n) |
32-
n.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
33-
)
34-
or
35-
exists(FileOrModule m | this = TFileOrModule(m) |
36-
m.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
37-
)
38-
}
39-
}
40-
41-
predicate resolveModule(ModuleRef ref, FileOrModule target, string kind) {
42-
target = ref.getResolvedModule() and
43-
kind = "module" and
44-
ref.getLocation().getFile() = getFileBySourceArchiveName(selectedSourceFile())
45-
}
46-
47-
predicate resolveType(TypeExpr ref, AstNode target, string kind) {
48-
target = ref.getResolvedType().getDeclaration() and
49-
kind = "type" and
50-
ref.getLocation().getFile() = getFileBySourceArchiveName(selectedSourceFile())
51-
}
52-
53-
predicate resolvePredicate(PredicateExpr ref, Predicate target, string kind) {
54-
target = ref.getResolvedPredicate() and
55-
kind = "predicate" and
56-
ref.getLocation().getFile() = getFileBySourceArchiveName(selectedSourceFile())
57-
}
58-
59-
predicate resolve(Loc ref, Loc target, string kind) {
60-
resolveModule(ref.asAst(), target.asMod(), kind)
61-
or
62-
resolveType(ref.asAst(), target.asAst(), kind)
63-
or
64-
resolvePredicate(ref.asAst(), target.asAst(), kind)
65-
}
66-
6716
from Loc ref, Loc target, string kind
68-
where resolve(ref, target, kind)
17+
where
18+
resolve(ref, target, kind) and
19+
ref.getFile() = getFileBySourceArchiveName(selectedSourceFile())
6920
select ref, target, kind

ql/src/ide-contextual-queries/localReferences.ql

Lines changed: 4 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -8,61 +8,13 @@
88
*/
99

1010
import ql
11-
import codeql_ql.ast.internal.Module
11+
import Definitions
1212
import codeql.IDEContextual
1313

1414
external string selectedSourceFile();
1515

16-
newtype TLoc =
17-
TAst(AstNode n) or
18-
TFileOrModule(FileOrModule m)
19-
20-
class Loc extends TLoc {
21-
string toString() { result = "" }
22-
23-
AstNode asAst() { this = TAst(result) }
24-
25-
FileOrModule asMod() { this = TFileOrModule(result) }
26-
27-
predicate hasLocationInfo(
28-
string filepath, int startline, int startcolumn, int endline, int endcolumn
29-
) {
30-
exists(AstNode n | this = TAst(n) |
31-
n.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
32-
)
33-
or
34-
exists(FileOrModule m | this = TFileOrModule(m) |
35-
m.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
36-
)
37-
}
38-
}
39-
40-
predicate resolveModule(ModuleRef ref, FileOrModule target, string kind) {
41-
target = ref.getResolvedModule() and
42-
kind = "module" and
43-
ref.getLocation().getFile() = getFileBySourceArchiveName(selectedSourceFile())
44-
}
45-
46-
predicate resolveType(TypeExpr ref, AstNode target, string kind) {
47-
target = ref.getResolvedType().getDeclaration() and
48-
kind = "type" and
49-
ref.getLocation().getFile() = getFileBySourceArchiveName(selectedSourceFile())
50-
}
51-
52-
predicate resolvePredicate(PredicateExpr ref, Predicate target, string kind) {
53-
target = ref.getResolvedPredicate() and
54-
kind = "predicate" and
55-
ref.getLocation().getFile() = getFileBySourceArchiveName(selectedSourceFile())
56-
}
57-
58-
predicate resolve(Loc ref, Loc target, string kind) {
59-
resolveModule(ref.asAst(), target.asMod(), kind)
60-
or
61-
resolveType(ref.asAst(), target.asAst(), kind)
62-
or
63-
resolvePredicate(ref.asAst(), target.asAst(), kind)
64-
}
65-
6616
from Loc ref, Loc target, string kind
67-
where resolve(ref, target, kind)
17+
where
18+
resolve(ref, target, kind) and
19+
target.getFile() = getFileBySourceArchiveName(selectedSourceFile())
6820
select ref, target, kind

0 commit comments

Comments
 (0)