@@ -162,6 +162,8 @@ class QLDoc extends TQLDoc, AstNode {
162162 string getContents ( ) { result = qldoc .getValue ( ) }
163163
164164 override string getAPrimaryQlClass ( ) { result = "QLDoc" }
165+
166+ override AstNode getParent ( ) { result .getQLDoc ( ) = this }
165167}
166168
167169class BlockComment extends TBlockComment , AstNode {
@@ -638,7 +640,7 @@ class FieldDecl extends TFieldDecl, AstNode {
638640/**
639641 * A type reference, such as `DataFlow::Node`.
640642 */
641- class TypeExpr extends TType , AstNode {
643+ class TypeExpr extends TType , TypeRef {
642644 QL:: TypeExpr type ;
643645
644646 TypeExpr ( ) { this = TType ( type ) }
@@ -675,10 +677,14 @@ class TypeExpr extends TType, AstNode {
675677 */
676678 ModuleExpr getModule ( ) { toQL ( result ) = type .getQualifier ( ) }
677679
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+ }
682688
683689 override AstNode getAChild ( string pred ) {
684690 result = super .getAChild ( pred )
@@ -710,6 +716,9 @@ class Module extends TModule, ModuleDeclaration {
710716 exists ( int i | result = this .getMember ( i ) and m = this .getMember ( i + 1 ) )
711717 }
712718
719+ /** Gets a ref to the module that this module implements. */
720+ TypeExpr getImplements ( int i ) { toQL ( result ) = mod .getImplements ( i ) .getTypeExpr ( ) }
721+
713722 /** Gets the module expression that this module is an alias for, if any. */
714723 ModuleExpr getAlias ( ) { toQL ( result ) = mod .getAFieldOrChild ( ) .( QL:: ModuleAliasBody ) .getChild ( ) }
715724
@@ -719,6 +728,19 @@ class Module extends TModule, ModuleDeclaration {
719728 pred = directMember ( "getAlias" ) and result = this .getAlias ( )
720729 or
721730 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+ )
722744 }
723745}
724746
@@ -1093,16 +1115,18 @@ class InlineCast extends TInlineCast, Expr {
10931115 }
10941116}
10951117
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 ( ) }
11001124}
11011125
11021126/**
11031127 * An import statement.
11041128 */
1105- class Import extends TImport , ModuleMember , ModuleRef {
1129+ class Import extends TImport , ModuleMember , TypeRef {
11061130 QL:: ImportDirective imp ;
11071131
11081132 Import ( ) { this = TImport ( imp ) }
@@ -1153,7 +1177,9 @@ class Import extends TImport, ModuleMember, ModuleRef {
11531177 )
11541178 }
11551179
1156- final override FileOrModule getResolvedModule ( ) { resolve ( this , result ) }
1180+ override Type getResolvedType ( ) {
1181+ exists ( FileOrModule mod | resolve ( this , mod ) | result = mod .toType ( ) )
1182+ }
11571183}
11581184
11591185/** A formula, such as `x = 6 and y < 5`. */
@@ -2172,7 +2198,7 @@ class DontCare extends TDontCare, Expr {
21722198}
21732199
21742200/** A module expression. Such as `DataFlow` in `DataFlow::Node` */
2175- class ModuleExpr extends TModuleExpr , ModuleRef {
2201+ class ModuleExpr extends TModuleExpr , TypeRef {
21762202 QL:: ModuleExpr me ;
21772203
21782204 ModuleExpr ( ) { this = TModuleExpr ( me ) }
@@ -2190,6 +2216,10 @@ class ModuleExpr extends TModuleExpr, ModuleRef {
21902216 result = me .getName ( ) .( QL:: SimpleId ) .getValue ( )
21912217 or
21922218 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+ )
21932223 }
21942224
21952225 /**
@@ -2203,7 +2233,9 @@ class ModuleExpr extends TModuleExpr, ModuleRef {
22032233 */
22042234 ModuleExpr getQualifier ( ) { result = TModuleExpr ( me .getChild ( ) ) }
22052235
2206- final override FileOrModule getResolvedModule ( ) { resolveModuleExpr ( this , result ) }
2236+ override Type getResolvedType ( ) {
2237+ exists ( FileOrModule mod | resolveModuleRef ( this , mod ) | result = mod .toType ( ) )
2238+ }
22072239
22082240 final override string toString ( ) { result = this .getName ( ) }
22092241
@@ -2213,9 +2245,41 @@ class ModuleExpr extends TModuleExpr, ModuleRef {
22132245 result = super .getAChild ( pred )
22142246 or
22152247 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+ )
22162260 }
22172261}
22182262
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+
22192283/** An argument to an annotation. */
22202284private class AnnotationArg extends TAnnotationArg , AstNode {
22212285 QL:: AnnotArg arg ;
@@ -2272,7 +2336,7 @@ class Annotation extends TAnnotation, AstNode {
22722336 /** Gets the node corresponding to the field `name`. */
22732337 string getName ( ) { result = annot .getName ( ) .getValue ( ) }
22742338
2275- override AstNode getParent ( ) { result = AstNode . super . getParent ( ) }
2339+ override AstNode getParent ( ) { result . getAnAnnotation ( ) = this }
22762340
22772341 override AstNode getAChild ( string pred ) {
22782342 result = super .getAChild ( pred )
0 commit comments