@@ -162,6 +162,8 @@ class QLDoc extends TQLDoc, AstNode {
162
162
string getContents ( ) { result = qldoc .getValue ( ) }
163
163
164
164
override string getAPrimaryQlClass ( ) { result = "QLDoc" }
165
+
166
+ override AstNode getParent ( ) { result .getQLDoc ( ) = this }
165
167
}
166
168
167
169
class BlockComment extends TBlockComment , AstNode {
@@ -638,7 +640,7 @@ class FieldDecl extends TFieldDecl, AstNode {
638
640
/**
639
641
* A type reference, such as `DataFlow::Node`.
640
642
*/
641
- class TypeExpr extends TType , AstNode {
643
+ class TypeExpr extends TType , TypeRef {
642
644
QL:: TypeExpr type ;
643
645
644
646
TypeExpr ( ) { this = TType ( type ) }
@@ -675,10 +677,14 @@ class TypeExpr extends TType, AstNode {
675
677
*/
676
678
ModuleExpr getModule ( ) { toQL ( result ) = type .getQualifier ( ) }
677
679
678
- /**
679
- * Gets the type that this type reference refers to.
680
- */
681
- 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
+ }
682
688
683
689
override AstNode getAChild ( string pred ) {
684
690
result = super .getAChild ( pred )
@@ -710,6 +716,9 @@ class Module extends TModule, ModuleDeclaration {
710
716
exists ( int i | result = this .getMember ( i ) and m = this .getMember ( i + 1 ) )
711
717
}
712
718
719
+ /** Gets a ref to the module that this module implements. */
720
+ TypeExpr getImplements ( int i ) { toQL ( result ) = mod .getImplements ( i ) .getTypeExpr ( ) }
721
+
713
722
/** Gets the module expression that this module is an alias for, if any. */
714
723
ModuleExpr getAlias ( ) { toQL ( result ) = mod .getAFieldOrChild ( ) .( QL:: ModuleAliasBody ) .getChild ( ) }
715
724
@@ -719,6 +728,19 @@ class Module extends TModule, ModuleDeclaration {
719
728
pred = directMember ( "getAlias" ) and result = this .getAlias ( )
720
729
or
721
730
pred = directMember ( "getAMember" ) and result = this .getAMember ( )
731
+ or
732
+ exists ( int i | pred = indexedMember ( "getImplements" , i ) and result = this .getImplements ( i ) )
733
+ or
734
+ exists ( int i | pred = indexedMember ( "hasParameter" , i ) and this .hasParameter ( i , _, result ) )
735
+ }
736
+
737
+ /** Holds if the `i`th parameter of this module has `name` and type `sig`. */
738
+ predicate hasParameter ( int i , string name , SignatureExpr sig ) {
739
+ exists ( QL:: ModuleParam param |
740
+ param = mod .getParameter ( i ) and
741
+ name = param .getParameter ( ) .getValue ( ) and
742
+ sig .toQL ( ) = param .getSignature ( )
743
+ )
722
744
}
723
745
}
724
746
@@ -1093,16 +1115,18 @@ class InlineCast extends TInlineCast, Expr {
1093
1115
}
1094
1116
}
1095
1117
1096
- /** An entity that resolves to a module. */
1097
- class ModuleRef extends AstNode , TModuleRef {
1098
- /** Gets the module that this entity resolves to. */
1099
- FileOrModule getResolvedModule ( ) { none ( ) }
1118
+ /** An entity that resolves to a type. */
1119
+ class TypeRef extends AstNode , TTypeRef {
1120
+ abstract Type getResolvedType ( ) ;
1121
+
1122
+ /** Gets the module that this entity resolves to, if this reference resolves to a module */
1123
+ final FileOrModule getResolvedModule ( ) { result .toType ( ) = this .getResolvedType ( ) }
1100
1124
}
1101
1125
1102
1126
/**
1103
1127
* An import statement.
1104
1128
*/
1105
- class Import extends TImport , ModuleMember , ModuleRef {
1129
+ class Import extends TImport , ModuleMember , TypeRef {
1106
1130
QL:: ImportDirective imp ;
1107
1131
1108
1132
Import ( ) { this = TImport ( imp ) }
@@ -1153,7 +1177,9 @@ class Import extends TImport, ModuleMember, ModuleRef {
1153
1177
)
1154
1178
}
1155
1179
1156
- final override FileOrModule getResolvedModule ( ) { resolve ( this , result ) }
1180
+ override Type getResolvedType ( ) {
1181
+ exists ( FileOrModule mod | resolve ( this , mod ) | result = mod .toType ( ) )
1182
+ }
1157
1183
}
1158
1184
1159
1185
/** A formula, such as `x = 6 and y < 5`. */
@@ -2172,7 +2198,7 @@ class DontCare extends TDontCare, Expr {
2172
2198
}
2173
2199
2174
2200
/** A module expression. Such as `DataFlow` in `DataFlow::Node` */
2175
- class ModuleExpr extends TModuleExpr , ModuleRef {
2201
+ class ModuleExpr extends TModuleExpr , TypeRef {
2176
2202
QL:: ModuleExpr me ;
2177
2203
2178
2204
ModuleExpr ( ) { this = TModuleExpr ( me ) }
@@ -2190,6 +2216,10 @@ class ModuleExpr extends TModuleExpr, ModuleRef {
2190
2216
result = me .getName ( ) .( QL:: SimpleId ) .getValue ( )
2191
2217
or
2192
2218
not exists ( me .getName ( ) ) and result = me .getChild ( ) .( QL:: SimpleId ) .getValue ( )
2219
+ or
2220
+ exists ( QL:: ModuleInstantiation instantiation | instantiation .getParent ( ) = me |
2221
+ result = instantiation .getName ( ) .getChild ( ) .getValue ( )
2222
+ )
2193
2223
}
2194
2224
2195
2225
/**
@@ -2203,7 +2233,9 @@ class ModuleExpr extends TModuleExpr, ModuleRef {
2203
2233
*/
2204
2234
ModuleExpr getQualifier ( ) { result = TModuleExpr ( me .getChild ( ) ) }
2205
2235
2206
- final override FileOrModule getResolvedModule ( ) { resolveModuleExpr ( this , result ) }
2236
+ override Type getResolvedType ( ) {
2237
+ exists ( FileOrModule mod | resolveModuleRef ( this , mod ) | result = mod .toType ( ) )
2238
+ }
2207
2239
2208
2240
final override string toString ( ) { result = this .getName ( ) }
2209
2241
@@ -2213,9 +2245,41 @@ class ModuleExpr extends TModuleExpr, ModuleRef {
2213
2245
result = super .getAChild ( pred )
2214
2246
or
2215
2247
pred = directMember ( "getQualifier" ) and result = this .getQualifier ( )
2248
+ or
2249
+ exists ( int i | pred = indexedMember ( "getArgument" , i ) and result = this .getArgument ( i ) )
2250
+ }
2251
+
2252
+ /**
2253
+ * Gets the `i`th type argument if this module is a module instantiation.
2254
+ * The result is either a `PredicateExpr` or a `TypeExpr`.
2255
+ */
2256
+ SignatureExpr getArgument ( int i ) {
2257
+ exists ( QL:: ModuleInstantiation instantiation | instantiation .getParent ( ) = me |
2258
+ result .toQL ( ) = instantiation .getChild ( i )
2259
+ )
2216
2260
}
2217
2261
}
2218
2262
2263
+ /** A signature expression, either a `PredicateExpr` or a `TypeExpr`. */
2264
+ class SignatureExpr extends TSignatureExpr , AstNode {
2265
+ QL:: SignatureExpr sig ;
2266
+
2267
+ SignatureExpr ( ) {
2268
+ toQL ( this ) = sig .getPredicate ( )
2269
+ or
2270
+ toQL ( this ) = sig .getTypeExpr ( )
2271
+ }
2272
+
2273
+ /** Gets the generated AST node that contains this signature expression. */
2274
+ QL:: SignatureExpr toQL ( ) { result = sig }
2275
+
2276
+ /** Gets this signature expression if it represents a predicate expression. */
2277
+ PredicateExpr asPredicate ( ) { result = this }
2278
+
2279
+ /** Gets this signature expression if it represents a type expression. */
2280
+ TypeExpr asType ( ) { result = this }
2281
+ }
2282
+
2219
2283
/** An argument to an annotation. */
2220
2284
private class AnnotationArg extends TAnnotationArg , AstNode {
2221
2285
QL:: AnnotArg arg ;
@@ -2272,7 +2336,7 @@ class Annotation extends TAnnotation, AstNode {
2272
2336
/** Gets the node corresponding to the field `name`. */
2273
2337
string getName ( ) { result = annot .getName ( ) .getValue ( ) }
2274
2338
2275
- override AstNode getParent ( ) { result = AstNode . super . getParent ( ) }
2339
+ override AstNode getParent ( ) { result . getAnAnnotation ( ) = this }
2276
2340
2277
2341
override AstNode getAChild ( string pred ) {
2278
2342
result = super .getAChild ( pred )
0 commit comments