@@ -16,7 +16,7 @@ import { AstEntity } from './AstEntity';
16
16
import { AstNamespaceImport } from './AstNamespaceImport' ;
17
17
import { MessageRouter } from '../collector/MessageRouter' ;
18
18
import { TypeScriptInternals , IGlobalVariableAnalyzer } from './TypeScriptInternals' ;
19
- import { StringChecks } from './StringChecks ' ;
19
+ import { SyntaxHelpers } from './SyntaxHelpers ' ;
20
20
import { SourceFileLocationFormatter } from './SourceFileLocationFormatter' ;
21
21
22
22
/**
@@ -88,7 +88,7 @@ export class AstSymbolTable {
88
88
89
89
// Note that this is a mapping from specific AST nodes that we analyzed, based on the underlying symbol
90
90
// for that node.
91
- private readonly _entitiesByIdentifierNode : Map < ts . Identifier , AstEntity | undefined > = new Map <
91
+ private readonly _entitiesByNode : Map < ts . Identifier | ts . ImportTypeNode , AstEntity | undefined > = new Map <
92
92
ts . Identifier ,
93
93
AstEntity | undefined
94
94
> ( ) ;
@@ -187,11 +187,11 @@ export class AstSymbolTable {
187
187
* @remarks
188
188
* Throws an Error if the ts.Identifier is not part of node tree that was analyzed.
189
189
*/
190
- public tryGetEntityForIdentifierNode ( identifier : ts . Identifier ) : AstEntity | undefined {
191
- if ( ! this . _entitiesByIdentifierNode . has ( identifier ) ) {
190
+ public tryGetEntityForNode ( identifier : ts . Identifier | ts . ImportTypeNode ) : AstEntity | undefined {
191
+ if ( ! this . _entitiesByNode . has ( identifier ) ) {
192
192
throw new InternalError ( 'tryGetEntityForIdentifier() called for an identifier that was not analyzed' ) ;
193
193
}
194
- return this . _entitiesByIdentifierNode . get ( identifier ) ;
194
+ return this . _entitiesByNode . get ( identifier ) ;
195
195
}
196
196
197
197
/**
@@ -261,7 +261,7 @@ export class AstSymbolTable {
261
261
// Otherwise that name may come from a quoted string or pseudonym like `__constructor`.
262
262
// If the string is not a safe identifier, then we must add quotes.
263
263
// Note that if it was quoted but did not need to be quoted, here we will remove the quotes.
264
- if ( ! StringChecks . isSafeUnquotedMemberIdentifier ( unquotedName ) ) {
264
+ if ( ! SyntaxHelpers . isSafeUnquotedMemberIdentifier ( unquotedName ) ) {
265
265
// For API Extractor's purposes, a canonical form is more appropriate than trying to reflect whatever
266
266
// appeared in the source code. The code is not even guaranteed to be consistent, for example:
267
267
//
@@ -360,8 +360,7 @@ export class AstSymbolTable {
360
360
) ;
361
361
362
362
if ( identifierNode ) {
363
- let referencedAstEntity : AstEntity | undefined =
364
- this . _entitiesByIdentifierNode . get ( identifierNode ) ;
363
+ let referencedAstEntity : AstEntity | undefined = this . _entitiesByNode . get ( identifierNode ) ;
365
364
if ( ! referencedAstEntity ) {
366
365
const symbol : ts . Symbol | undefined = this . _typeChecker . getSymbolAtLocation ( identifierNode ) ;
367
366
if ( ! symbol ) {
@@ -412,7 +411,7 @@ export class AstSymbolTable {
412
411
governingAstDeclaration . astSymbol . isExternal
413
412
) ;
414
413
415
- this . _entitiesByIdentifierNode . set ( identifierNode , referencedAstEntity ) ;
414
+ this . _entitiesByNode . set ( identifierNode , referencedAstEntity ) ;
416
415
}
417
416
}
418
417
@@ -427,19 +426,38 @@ export class AstSymbolTable {
427
426
case ts . SyntaxKind . Identifier :
428
427
{
429
428
const identifierNode : ts . Identifier = node as ts . Identifier ;
430
- if ( ! this . _entitiesByIdentifierNode . has ( identifierNode ) ) {
429
+ if ( ! this . _entitiesByNode . has ( identifierNode ) ) {
431
430
const symbol : ts . Symbol | undefined = this . _typeChecker . getSymbolAtLocation ( identifierNode ) ;
432
431
433
432
let referencedAstEntity : AstEntity | undefined = undefined ;
434
433
435
434
if ( symbol === governingAstDeclaration . astSymbol . followedSymbol ) {
436
- referencedAstEntity = this . _fetchEntityForIdentifierNode (
437
- identifierNode ,
438
- governingAstDeclaration
439
- ) ;
435
+ referencedAstEntity = this . _fetchEntityForNode ( identifierNode , governingAstDeclaration ) ;
440
436
}
441
437
442
- this . _entitiesByIdentifierNode . set ( identifierNode , referencedAstEntity ) ;
438
+ this . _entitiesByNode . set ( identifierNode , referencedAstEntity ) ;
439
+ }
440
+ }
441
+ break ;
442
+
443
+ case ts . SyntaxKind . ImportType :
444
+ {
445
+ const importTypeNode : ts . ImportTypeNode = node as ts . ImportTypeNode ;
446
+ let referencedAstEntity : AstEntity | undefined = this . _entitiesByNode . get ( importTypeNode ) ;
447
+
448
+ if ( ! this . _entitiesByNode . has ( importTypeNode ) ) {
449
+ referencedAstEntity = this . _fetchEntityForNode ( importTypeNode , governingAstDeclaration ) ;
450
+
451
+ if ( ! referencedAstEntity ) {
452
+ // This should never happen
453
+ throw new Error ( 'Failed to fetch entity for import() type node: ' + importTypeNode . getText ( ) ) ;
454
+ }
455
+
456
+ this . _entitiesByNode . set ( importTypeNode , referencedAstEntity ) ;
457
+ }
458
+
459
+ if ( referencedAstEntity ) {
460
+ governingAstDeclaration . _notifyReferencedAstEntity ( referencedAstEntity ) ;
443
461
}
444
462
}
445
463
break ;
@@ -456,23 +474,30 @@ export class AstSymbolTable {
456
474
}
457
475
}
458
476
459
- private _fetchEntityForIdentifierNode (
460
- identifierNode : ts . Identifier ,
477
+ private _fetchEntityForNode (
478
+ node : ts . Identifier | ts . ImportTypeNode ,
461
479
governingAstDeclaration : AstDeclaration
462
480
) : AstEntity | undefined {
463
- let referencedAstEntity : AstEntity | undefined = this . _entitiesByIdentifierNode . get ( identifierNode ) ;
481
+ let referencedAstEntity : AstEntity | undefined = this . _entitiesByNode . get ( node ) ;
464
482
if ( ! referencedAstEntity ) {
465
- const symbol : ts . Symbol | undefined = this . _typeChecker . getSymbolAtLocation ( identifierNode ) ;
466
- if ( ! symbol ) {
467
- throw new Error ( 'Symbol not found for identifier: ' + identifierNode . getText ( ) ) ;
468
- }
483
+ if ( node . kind === ts . SyntaxKind . ImportType ) {
484
+ referencedAstEntity = this . _exportAnalyzer . fetchReferencedAstEntityFromImportTypeNode (
485
+ node ,
486
+ governingAstDeclaration . astSymbol . isExternal
487
+ ) ;
488
+ } else {
489
+ const symbol : ts . Symbol | undefined = this . _typeChecker . getSymbolAtLocation ( node ) ;
490
+ if ( ! symbol ) {
491
+ throw new Error ( 'Symbol not found for identifier: ' + node . getText ( ) ) ;
492
+ }
469
493
470
- referencedAstEntity = this . _exportAnalyzer . fetchReferencedAstEntity (
471
- symbol ,
472
- governingAstDeclaration . astSymbol . isExternal
473
- ) ;
494
+ referencedAstEntity = this . _exportAnalyzer . fetchReferencedAstEntity (
495
+ symbol ,
496
+ governingAstDeclaration . astSymbol . isExternal
497
+ ) ;
498
+ }
474
499
475
- this . _entitiesByIdentifierNode . set ( identifierNode , referencedAstEntity ) ;
500
+ this . _entitiesByNode . set ( node , referencedAstEntity ) ;
476
501
}
477
502
return referencedAstEntity ;
478
503
}
0 commit comments