@@ -509,6 +509,15 @@ class LocalNamespaceName extends @local_namespace_name, LexicalName {
509509 /** Gets a use of this namespace in an export. */
510510 ExportVarAccess getAnExportAccess ( ) { namespacebind ( result , this ) }
511511
512+ /**
513+ * Gets an access to a type member of this namespace alias,
514+ * such as `http.ServerRequest` where `http` is a reference to this namespace.
515+ */
516+ QualifiedTypeAccess getAMemberAccess ( string member ) {
517+ result .getIdentifier ( ) .getName ( ) = member and
518+ result .getQualifier ( ) = this .getAnAccess ( )
519+ }
520+
512521 /** Gets an identifier that refers to this namespace name. */
513522 Identifier getAnAccess ( ) { namespacebind ( result , this ) }
514523
@@ -663,13 +672,50 @@ class TypeAccess extends @typeaccess, TypeExpr, TypeRef {
663672
664673 override predicate hasQualifiedName ( string globalName ) {
665674 getTypeName ( ) .hasQualifiedName ( globalName )
675+ or
676+ exists ( LocalTypeAccess local | local = this |
677+ not exists ( local .getLocalTypeName ( ) ) and // Without a local type name, the type is looked up in the global scope.
678+ globalName = local .getName ( )
679+ )
666680 }
667681
668682 override predicate hasQualifiedName ( string moduleName , string exportedName ) {
669683 getTypeName ( ) .hasQualifiedName ( moduleName , exportedName )
684+ or
685+ exists ( ImportDeclaration imprt , ImportSpecifier spec |
686+ moduleName = getImportName ( imprt ) and
687+ spec = imprt .getASpecifier ( )
688+ |
689+ spec .getImportedName ( ) = exportedName and
690+ this = spec .getLocal ( ) .( TypeDecl ) .getLocalTypeName ( ) .getAnAccess ( )
691+ or
692+ spec instanceof ImportNamespaceSpecifier and
693+ this =
694+ spec .getLocal ( ) .( LocalNamespaceDecl ) .getLocalNamespaceName ( ) .getAMemberAccess ( exportedName )
695+ )
696+ or
697+ exists ( ImportEqualsDeclaration imprt |
698+ moduleName = getImportName ( imprt .getImportedEntity ( ) ) and
699+ this =
700+ imprt .getId ( ) .( LocalNamespaceDecl ) .getLocalNamespaceName ( ) .getAMemberAccess ( exportedName )
701+ )
670702 }
671703}
672704
705+ /**
706+ * Gets a suitable name for the library imported by `import`.
707+ *
708+ * For relative imports, this is the snapshot-relative path to the imported module.
709+ * For non-relative imports, it is the import path itself.
710+ */
711+ private string getImportName ( Import imprt ) {
712+ exists ( string path | path = imprt .getImportedPath ( ) .getValue ( ) |
713+ if path .regexpMatch ( "[./].*" )
714+ then result = imprt .getImportedModule ( ) .getFile ( ) .getRelativePath ( )
715+ else result = path
716+ )
717+ }
718+
673719/** An identifier that is used as part of a type, such as `Date`. */
674720class LocalTypeAccess extends @localtypeaccess, TypeAccess , Identifier , LexicalAccess {
675721 override predicate isStringy ( ) { getName ( ) = "String" }
0 commit comments