@@ -84,6 +84,10 @@ namespace ts.FindAllReferences {
84
84
85
85
switch ( direct . kind ) {
86
86
case SyntaxKind . CallExpression :
87
+ if ( isImportCall ( direct ) ) {
88
+ handleImportCall ( direct ) ;
89
+ break ;
90
+ }
87
91
if ( ! isAvailableThroughGlobal ) {
88
92
const parent = direct . parent ;
89
93
if ( exportKind === ExportKind . ExportEquals && parent . kind === SyntaxKind . VariableDeclaration ) {
@@ -121,7 +125,7 @@ namespace ts.FindAllReferences {
121
125
}
122
126
else if ( direct . exportClause . kind === SyntaxKind . NamespaceExport ) {
123
127
// `export * as foo from "foo"` add to indirect uses
124
- addIndirectUsers ( getSourceFileLikeForImportDeclaration ( direct ) ) ;
128
+ addIndirectUser ( getSourceFileLikeForImportDeclaration ( direct ) , /** addTransitiveDependencies */ true ) ;
125
129
}
126
130
else {
127
131
// This is `export { foo } from "foo"` and creates an alias symbol, so recursive search will get handle re-exports.
@@ -130,6 +134,10 @@ namespace ts.FindAllReferences {
130
134
break ;
131
135
132
136
case SyntaxKind . ImportType :
137
+ // Only check for typeof import('xyz')
138
+ if ( direct . isTypeOf && ! direct . qualifier && isExported ( direct ) ) {
139
+ addIndirectUser ( direct . getSourceFile ( ) , /** addTransitiveDependencies */ true ) ;
140
+ }
133
141
directImports . push ( direct ) ;
134
142
break ;
135
143
@@ -140,6 +148,18 @@ namespace ts.FindAllReferences {
140
148
}
141
149
}
142
150
151
+ function handleImportCall ( importCall : ImportCall ) {
152
+ const top = findAncestor ( importCall , isAmbientModuleDeclaration ) || importCall . getSourceFile ( ) ;
153
+ addIndirectUser ( top , /** addTransitiveDependencies */ ! ! isExported ( importCall , /** stopAtAmbientModule */ true ) ) ;
154
+ }
155
+
156
+ function isExported ( node : Node , stopAtAmbientModule = false ) {
157
+ return findAncestor ( node , node => {
158
+ if ( stopAtAmbientModule && isAmbientModuleDeclaration ( node ) ) return "quit" ;
159
+ return some ( node . modifiers , mod => mod . kind === SyntaxKind . ExportKeyword ) ;
160
+ } ) ;
161
+ }
162
+
143
163
function handleNamespaceImport ( importDeclaration : ImportEqualsDeclaration | ImportDeclaration , name : Identifier , isReExport : boolean , alreadyAddedDirect : boolean ) : void {
144
164
if ( exportKind === ExportKind . ExportEquals ) {
145
165
// This is a direct import, not import-as-namespace.
@@ -149,36 +169,30 @@ namespace ts.FindAllReferences {
149
169
const sourceFileLike = getSourceFileLikeForImportDeclaration ( importDeclaration ) ;
150
170
Debug . assert ( sourceFileLike . kind === SyntaxKind . SourceFile || sourceFileLike . kind === SyntaxKind . ModuleDeclaration ) ;
151
171
if ( isReExport || findNamespaceReExports ( sourceFileLike , name , checker ) ) {
152
- addIndirectUsers ( sourceFileLike ) ;
172
+ addIndirectUser ( sourceFileLike , /** addTransitiveDependencies */ true ) ;
153
173
}
154
174
else {
155
175
addIndirectUser ( sourceFileLike ) ;
156
176
}
157
177
}
158
178
}
159
179
160
- function addIndirectUser ( sourceFileLike : SourceFileLike ) : boolean {
180
+ /** Adds a module and all of its transitive dependencies as possible indirect users. */
181
+ function addIndirectUser ( sourceFileLike : SourceFileLike , addTransitiveDependencies = false ) : void {
161
182
Debug . assert ( ! isAvailableThroughGlobal ) ;
162
183
const isNew = markSeenIndirectUser ( sourceFileLike ) ;
163
- if ( isNew ) {
164
- indirectUserDeclarations ! . push ( sourceFileLike ) ; // TODO: GH#18217
165
- }
166
- return isNew ;
167
- }
168
-
169
- /** Adds a module and all of its transitive dependencies as possible indirect users. */
170
- function addIndirectUsers ( sourceFileLike : SourceFileLike ) : void {
171
- if ( ! addIndirectUser ( sourceFileLike ) ) {
172
- return ;
173
- }
184
+ if ( ! isNew ) return ;
185
+ indirectUserDeclarations ! . push ( sourceFileLike ) ; // TODO: GH#18217
174
186
187
+ if ( ! addTransitiveDependencies ) return ;
175
188
const moduleSymbol = checker . getMergedSymbol ( sourceFileLike . symbol ) ;
189
+ if ( ! moduleSymbol ) return ;
176
190
Debug . assert ( ! ! ( moduleSymbol . flags & SymbolFlags . Module ) ) ;
177
191
const directImports = getDirectImports ( moduleSymbol ) ;
178
192
if ( directImports ) {
179
193
for ( const directImport of directImports ) {
180
194
if ( ! isImportTypeNode ( directImport ) ) {
181
- addIndirectUsers ( getSourceFileLikeForImportDeclaration ( directImport ) ) ;
195
+ addIndirectUser ( getSourceFileLikeForImportDeclaration ( directImport ) , /** addTransitiveDependencies */ true ) ;
182
196
}
183
197
}
184
198
}
0 commit comments