Skip to content

Commit 13b7436

Browse files
committed
everything is a TypeRef, some TypeRefs just resolve to a module
1 parent 2b5af15 commit 13b7436

File tree

5 files changed

+64
-56
lines changed

5 files changed

+64
-56
lines changed

ql/ql/src/codeql_ql/ast/Ast.qll

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,7 @@ class FieldDecl extends TFieldDecl, AstNode {
640640
/**
641641
* A type reference, such as `DataFlow::Node`.
642642
*/
643-
class TypeExpr extends TType, AstNode {
643+
class TypeExpr extends TType, TypeRef {
644644
QL::TypeExpr type;
645645

646646
TypeExpr() { this = TType(type) }
@@ -677,10 +677,14 @@ class TypeExpr extends TType, AstNode {
677677
*/
678678
ModuleExpr getModule() { toQL(result) = type.getQualifier() }
679679

680-
/**
681-
* Gets the type that this type reference refers to.
682-
*/
683-
Type getResolvedType() { resolveTypeExpr(this, result) }
680+
/** Gets the type that this type reference refers to. */
681+
override Type getResolvedType() {
682+
// resolve type
683+
resolveTypeExpr(this, result)
684+
or
685+
// if it resolves to a module
686+
exists(FileOrModule mod | resolveModuleRef(this, mod) | result = mod.toType())
687+
}
684688

685689
override AstNode getAChild(string pred) {
686690
result = super.getAChild(pred)
@@ -713,7 +717,7 @@ class Module extends TModule, ModuleDeclaration {
713717
}
714718

715719
/** Gets a ref to the module that this module implements. */
716-
ModuleParameterRef getImplements(int i) { toQL(result) = mod.getImplements(i).getTypeExpr() }
720+
TypeExpr getImplements(int i) { toQL(result) = mod.getImplements(i).getTypeExpr() }
717721

718722
/** Gets the module expression that this module is an alias for, if any. */
719723
ModuleExpr getAlias() { toQL(result) = mod.getAFieldOrChild().(QL::ModuleAliasBody).getChild() }
@@ -1111,18 +1115,18 @@ class InlineCast extends TInlineCast, Expr {
11111115
}
11121116
}
11131117

1114-
/** An entity that resolves to a module. */
1115-
class ModuleRef extends AstNode, TModuleRef {
1116-
/** Gets the module that this entity resolves to. */
1117-
FileOrModule getResolvedModule() { none() }
1118+
/** An entity that resolves to a type. */
1119+
class TypeRef extends AstNode, TTypeRef {
1120+
abstract Type getResolvedType();
11181121

1119-
string getName() { none() }
1122+
/** Gets the module that this entity resolves to, if this reference resolves to a module */
1123+
final FileOrModule getResolvedModule() { result.toType() = this.getResolvedType() }
11201124
}
11211125

11221126
/**
11231127
* An import statement.
11241128
*/
1125-
class Import extends TImport, ModuleMember, ModuleRef {
1129+
class Import extends TImport, ModuleMember, TypeRef {
11261130
QL::ImportDirective imp;
11271131

11281132
Import() { this = TImport(imp) }
@@ -1173,7 +1177,9 @@ class Import extends TImport, ModuleMember, ModuleRef {
11731177
)
11741178
}
11751179

1176-
final override FileOrModule getResolvedModule() { resolve(this, result) }
1180+
override Type getResolvedType() {
1181+
exists(FileOrModule mod | resolve(this, mod) | result = mod.toType())
1182+
}
11771183
}
11781184

11791185
/** A formula, such as `x = 6 and y < 5`. */
@@ -2191,18 +2197,8 @@ class DontCare extends TDontCare, Expr {
21912197
override string getAPrimaryQlClass() { result = "DontCare" }
21922198
}
21932199

2194-
/**
2195-
* A type expression seen as a reference to a module as part of a parameterized module (or it's instantiation).
2196-
* This might not be a reference to a module, but we assume so until we find out in the resolve phase.
2197-
*/
2198-
class ModuleParameterRef extends ModuleRef instanceof TypeExpr {
2199-
final override FileOrModule getResolvedModule() { resolveModuleRef(this, result) }
2200-
2201-
override string getName() { result = TypeExpr.super.getClassName() }
2202-
}
2203-
22042200
/** A module expression. Such as `DataFlow` in `DataFlow::Node` */
2205-
class ModuleExpr extends TModuleExpr, ModuleRef {
2201+
class ModuleExpr extends TModuleExpr, TypeRef {
22062202
QL::ModuleExpr me;
22072203

22082204
ModuleExpr() { this = TModuleExpr(me) }
@@ -2216,7 +2212,7 @@ class ModuleExpr extends TModuleExpr, ModuleRef {
22162212
*
22172213
* is `Bar`.
22182214
*/
2219-
override string getName() {
2215+
string getName() {
22202216
result = me.getName().(QL::SimpleId).getValue()
22212217
or
22222218
not exists(me.getName()) and result = me.getChild().(QL::SimpleId).getValue()
@@ -2237,7 +2233,9 @@ class ModuleExpr extends TModuleExpr, ModuleRef {
22372233
*/
22382234
ModuleExpr getQualifier() { result = TModuleExpr(me.getChild()) }
22392235

2240-
final override FileOrModule getResolvedModule() { resolveModuleRef(this, result) }
2236+
override Type getResolvedType() {
2237+
exists(FileOrModule mod | resolveModuleRef(this, mod) | result = mod.toType())
2238+
}
22412239

22422240
final override string toString() { result = this.getName() }
22432241

@@ -2269,7 +2267,7 @@ class SignatureExpr extends TSignatureExpr, AstNode {
22692267
SignatureExpr() {
22702268
toQL(this) = sig.getPredicate()
22712269
or
2272-
toQL(this) = sig.getTypeExpr() // both `TypeExpr` and `ModuleParameterRef`
2270+
toQL(this) = sig.getTypeExpr()
22732271
}
22742272

22752273
/** Gets the generated AST node that contains this signature expression. */
@@ -2280,8 +2278,6 @@ class SignatureExpr extends TSignatureExpr, AstNode {
22802278

22812279
/** Gets this signature expression if it represents a type expression. */
22822280
TypeExpr asType() { result = this }
2283-
2284-
ModuleParameterRef asModuleRef() { result = this }
22852281
}
22862282

22872283
/** An argument to an annotation. */

ql/ql/src/codeql_ql/ast/internal/AstNodes.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ class TExpr =
8383

8484
class TCall = TPredicateCall or TMemberCall or TNoneCall or TAnyCall;
8585

86-
class TModuleRef = TImport or TModuleExpr or TType;
86+
class TTypeRef = TImport or TModuleExpr or TType;
8787

8888
class TYamlNode = TYamlCommemt or TYamlEntry or TYamlKey or TYamlListitem or TYamlValue;
8989

ql/ql/src/codeql_ql/ast/internal/Module.qll

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ class FileOrModule extends TFileOrModule, ContainerOrModule {
4141
or
4242
result = this.asModule().getLocation().getFile()
4343
}
44+
45+
Type toType() {
46+
result.(FileType).getDeclaration().getLocation().getFile() = this.asFile()
47+
or
48+
result.(ModuleType).getDeclaration() = this.asModule()
49+
}
4450
}
4551

4652
private class File_ extends FileOrModule, TFile {
@@ -207,7 +213,7 @@ private module Cached {
207213

208214
/** Holds if module expression `me` resolves to `m`. */
209215
cached
210-
predicate resolveModuleRef(ModuleRef me, FileOrModule m) {
216+
predicate resolveModuleRef(TypeRef me, FileOrModule m) {
211217
not m = TFile(any(File f | f.getExtension() = "ql")) and
212218
not exists(me.(ModuleExpr).getQualifier()) and
213219
exists(ContainerOrModule enclosing, string name | resolveModuleRefHelper(me, enclosing, name) |
@@ -221,9 +227,9 @@ private module Cached {
221227
}
222228

223229
pragma[noinline]
224-
private predicate resolveModuleRefHelper(ModuleRef me, ContainerOrModule enclosing, string name) {
230+
private predicate resolveModuleRefHelper(TypeRef me, ContainerOrModule enclosing, string name) {
225231
enclosing = getEnclosingModule(me).getEnclosing*() and
226-
name = me.getName()
232+
name = [me.(ModuleExpr).getName(), me.(TypeExpr).getClassName()]
227233
}
228234
}
229235

@@ -257,18 +263,18 @@ private predicate definesModule(
257263
)
258264
or
259265
// signature module in a paramertized module
260-
exists(Module mod, SignatureExpr sig, ModuleParameterRef ty, int i |
266+
exists(Module mod, SignatureExpr sig, TypeExpr ty, int i |
261267
mod = container.asModule() and
262268
mod.hasParameter(i, name, sig) and
263269
public = false and
264-
ty = sig.asModuleRef()
270+
ty = sig.asType()
265271
|
266272
// resolve to the signature module
267273
m = ty.getResolvedModule()
268274
or
269275
// resolve to the arguments of the instantiated module
270276
exists(ModuleExpr inst | inst.getResolvedModule().asModule() = mod |
271-
m = inst.getArgument(i).asModuleRef().getResolvedModule()
277+
m = inst.getArgument(i).asType().getResolvedModule()
272278
)
273279
)
274280
or
@@ -307,16 +313,6 @@ module ModConsistency {
307313
.regexpMatch(".*/(test|examples|ql-training|recorded-call-graph-metrics)/.*")
308314
}
309315

310-
query predicate noResolveModuleRef(ModuleRef me) {
311-
not exists(me.getResolvedModule()) and
312-
not me.getLocation()
313-
.getFile()
314-
.getAbsolutePath()
315-
.regexpMatch(".*/(test|examples|ql-training|recorded-call-graph-metrics)/.*") and
316-
// this ModuleRef might really be a type.
317-
not exists(me.(TypeExpr).getResolvedType())
318-
}
319-
320316
query predicate multipleResolve(Import imp, int c, ContainerOrModule m) {
321317
c = strictcount(ContainerOrModule m0 | resolve(imp, m0)) and
322318
c > 1 and

ql/ql/src/codeql_ql/ast/internal/Type.qll

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ private newtype TType =
1414
TDontCare() or
1515
TClassChar(Class c) { isActualClass(c) } or
1616
TClassDomain(Class c) { isActualClass(c) } or
17-
TDatabase(string s) { exists(TypeExpr t | t.isDBType() and s = t.getClassName()) }
17+
TDatabase(string s) { exists(TypeExpr t | t.isDBType() and s = t.getClassName()) } or
18+
TFile(TopLevel t) or
19+
TModule(Module m)
1820

1921
private predicate primTypeName(string s) { s = ["int", "float", "string", "boolean", "date"] }
2022

@@ -110,6 +112,26 @@ class ClassType extends Type, TClass {
110112
}
111113
}
112114

115+
class FileType extends Type, TFile {
116+
TopLevel decl;
117+
118+
FileType() { this = TFile(decl) }
119+
120+
override string getName() { result = decl.getLocation().getFile().getBaseName() }
121+
122+
override TopLevel getDeclaration() { result = decl }
123+
}
124+
125+
class ModuleType extends Type, TModule {
126+
Module decl;
127+
128+
ModuleType() { this = TModule(decl) }
129+
130+
override string getName() { result = decl.getName() }
131+
132+
override Module getDeclaration() { result = decl }
133+
}
134+
113135
private PredicateOrBuiltin declaredPred(Type ty, string name, int arity) {
114136
result.getDeclaringType() = ty and
115137
result.getName() = name and
@@ -343,16 +365,12 @@ private predicate defines(FileOrModule m, string name, Type t, boolean public) {
343365
}
344366

345367
module TyConsistency {
346-
query predicate noResolve(TypeExpr te) {
347-
not resolveTypeExpr(te, _) and
368+
query predicate noResolve(TypeRef te) {
369+
not exists(te.getResolvedType()) and
348370
not te.getLocation()
349371
.getFile()
350372
.getAbsolutePath()
351-
.regexpMatch(".*/(test|examples|ql-training|recorded-call-graph-metrics)/.*") and
352-
// we have some duplicate with moduleRef, so that might be resolved correctly.
353-
not exists(ModuleRef ref | AstNodes::toQL(te) = AstNodes::toQL(ref) |
354-
exists(ref.getResolvedModule())
355-
)
373+
.regexpMatch(".*/(test|examples|ql-training|recorded-call-graph-metrics)/.*")
356374
}
357375

358376
// This can happen with parameterized modules.

ql/ql/src/queries/diagnostics/EmptyConsistencies.ql

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@ where
3939
or
4040
ModConsistency::noResolve(node) and msg = "ModConsistency::noResolve"
4141
or
42-
ModConsistency::noResolveModuleRef(node) and msg = "ModConsistency::noResolveModuleRef"
43-
or
4442
ModConsistency::noName(node) and msg = "ModConsistency::noName"
4543
or
4644
ModConsistency::nonUniqueName(node) and msg = "ModConsistency::nonUniqueName"

0 commit comments

Comments
 (0)