@@ -32,8 +32,8 @@ namespace ts.codefix {
32
32
} ,
33
33
fixIds : [ importFixId ] ,
34
34
getAllCodeActions : context => {
35
- const { sourceFile, program, preferences, host } = context ;
36
- const importAdder = createImportAdderWorker ( sourceFile , program , /*useAutoImportProvider*/ true , preferences , host ) ;
35
+ const { sourceFile, program, preferences, host, cancellationToken } = context ;
36
+ const importAdder = createImportAdderWorker ( sourceFile , program , /*useAutoImportProvider*/ true , preferences , host , cancellationToken ) ;
37
37
eachDiagnostic ( context , errorCodes , diag => importAdder . addImportFromDiagnostic ( diag , context ) ) ;
38
38
return createCombinedCodeActions ( textChanges . ChangeTracker . with ( context , importAdder . writeFixes ) ) ;
39
39
} ,
@@ -49,8 +49,8 @@ namespace ts.codefix {
49
49
writeFixes : ( changeTracker : textChanges . ChangeTracker ) => void ;
50
50
}
51
51
52
- export function createImportAdder ( sourceFile : SourceFile , program : Program , preferences : UserPreferences , host : LanguageServiceHost ) : ImportAdder {
53
- return createImportAdderWorker ( sourceFile , program , /*useAutoImportProvider*/ false , preferences , host ) ;
52
+ export function createImportAdder ( sourceFile : SourceFile , program : Program , preferences : UserPreferences , host : LanguageServiceHost , cancellationToken ?: CancellationToken ) : ImportAdder {
53
+ return createImportAdderWorker ( sourceFile , program , /*useAutoImportProvider*/ false , preferences , host , cancellationToken ) ;
54
54
}
55
55
56
56
interface AddToExistingState {
@@ -59,7 +59,7 @@ namespace ts.codefix {
59
59
readonly namedImports : ESMap < string , AddAsTypeOnly > ;
60
60
}
61
61
62
- function createImportAdderWorker ( sourceFile : SourceFile , program : Program , useAutoImportProvider : boolean , preferences : UserPreferences , host : LanguageServiceHost ) : ImportAdder {
62
+ function createImportAdderWorker ( sourceFile : SourceFile , program : Program , useAutoImportProvider : boolean , preferences : UserPreferences , host : LanguageServiceHost , cancellationToken : CancellationToken | undefined ) : ImportAdder {
63
63
const compilerOptions = program . getCompilerOptions ( ) ;
64
64
// Namespace fixes don't conflict, so just build a list.
65
65
const addToNamespace : FixUseNamespaceImport [ ] = [ ] ;
@@ -83,9 +83,9 @@ namespace ts.codefix {
83
83
const symbolName = getNameForExportedSymbol ( exportedSymbol , getEmitScriptTarget ( compilerOptions ) ) ;
84
84
const checker = program . getTypeChecker ( ) ;
85
85
const symbol = checker . getMergedSymbol ( skipAlias ( exportedSymbol , checker ) ) ;
86
- const exportInfo = getAllReExportingModules ( sourceFile , symbol , moduleSymbol , symbolName , /*isJsxTagName*/ false , host , program , preferences , useAutoImportProvider ) ;
86
+ const exportInfo = getAllExportInfoForSymbol ( sourceFile , symbol , symbolName , /*isJsxTagName*/ false , program , host , preferences , cancellationToken ) ;
87
87
const useRequire = shouldUseRequire ( sourceFile , program ) ;
88
- const fix = getImportFixForSymbol ( sourceFile , exportInfo , moduleSymbol , program , /*useNamespaceInfo*/ undefined , ! ! isValidTypeOnlyUseSite , useRequire , host , preferences ) ;
88
+ const fix = getImportFixForSymbol ( sourceFile , Debug . checkDefined ( exportInfo ) , moduleSymbol , program , /*useNamespaceInfo*/ undefined , ! ! isValidTypeOnlyUseSite , useRequire , host , preferences ) ;
89
89
if ( fix ) {
90
90
addImport ( { fix, symbolName, errorIdentifierText : undefined } ) ;
91
91
}
@@ -345,11 +345,15 @@ namespace ts.codefix {
345
345
formatContext : formatting . FormatContext ,
346
346
position : number ,
347
347
preferences : UserPreferences ,
348
+ cancellationToken : CancellationToken ,
348
349
) : { readonly moduleSpecifier : string , readonly codeAction : CodeAction } {
349
350
const compilerOptions = program . getCompilerOptions ( ) ;
351
+
350
352
const exportInfos = pathIsBareSpecifier ( stripQuotes ( moduleSymbol . name ) )
351
- ? [ getSymbolExportInfoForSymbol ( targetSymbol , moduleSymbol , program , host ) ]
352
- : getAllReExportingModules ( sourceFile , targetSymbol , moduleSymbol , symbolName , isJsxTagName , host , program , preferences , /*useAutoImportProvider*/ true ) ;
353
+ ? [ getSingleExportInfoForSymbol ( targetSymbol , moduleSymbol , program , host ) ]
354
+ : getAllExportInfoForSymbol ( sourceFile , targetSymbol , symbolName , isJsxTagName , program , host , preferences , cancellationToken ) ;
355
+
356
+ Debug . assertIsDefined ( exportInfos ) ;
353
357
const useRequire = shouldUseRequire ( sourceFile , program ) ;
354
358
const isValidTypeOnlyUseSite = isValidTypeOnlyAliasUseSite ( getTokenAtPosition ( sourceFile , position ) ) ;
355
359
const fix = Debug . checkDefined ( getImportFixForSymbol ( sourceFile , exportInfos , moduleSymbol , program , { symbolName, position } , isValidTypeOnlyUseSite , useRequire , host , preferences ) ) ;
@@ -383,7 +387,17 @@ namespace ts.codefix {
383
387
return { description, changes, commands } ;
384
388
}
385
389
386
- function getSymbolExportInfoForSymbol ( symbol : Symbol , moduleSymbol : Symbol , program : Program , host : LanguageServiceHost ) : SymbolExportInfo {
390
+ function getAllExportInfoForSymbol ( importingFile : SourceFile , symbol : Symbol , symbolName : string , preferCapitalized : boolean , program : Program , host : LanguageServiceHost , preferences : UserPreferences , cancellationToken : CancellationToken | undefined ) : readonly SymbolExportInfo [ ] | undefined {
391
+ const getChecker = createGetChecker ( program , host ) ;
392
+ return getExportInfoMap ( importingFile , host , program , preferences , cancellationToken )
393
+ . search ( importingFile . path , preferCapitalized , name => name === symbolName , info => {
394
+ if ( skipAlias ( info [ 0 ] . symbol , getChecker ( info [ 0 ] . isFromPackageJson ) ) === symbol ) {
395
+ return info ;
396
+ }
397
+ } ) ;
398
+ }
399
+
400
+ function getSingleExportInfoForSymbol ( symbol : Symbol , moduleSymbol : Symbol , program : Program , host : LanguageServiceHost ) : SymbolExportInfo {
387
401
const compilerOptions = program . getCompilerOptions ( ) ;
388
402
const mainProgramInfo = getInfoWithChecker ( program . getTypeChecker ( ) , /*isFromPackageJson*/ false ) ;
389
403
if ( mainProgramInfo ) {
@@ -404,38 +418,6 @@ namespace ts.codefix {
404
418
}
405
419
}
406
420
407
- function getAllReExportingModules ( importingFile : SourceFile , targetSymbol : Symbol , exportingModuleSymbol : Symbol , symbolName : string , isJsxTagName : boolean , host : LanguageServiceHost , program : Program , preferences : UserPreferences , useAutoImportProvider : boolean ) : readonly SymbolExportInfo [ ] {
408
- const result : SymbolExportInfo [ ] = [ ] ;
409
- const compilerOptions = program . getCompilerOptions ( ) ;
410
- const getModuleSpecifierResolutionHost = memoizeOne ( ( isFromPackageJson : boolean ) => {
411
- return createModuleSpecifierResolutionHost ( isFromPackageJson ? host . getPackageJsonAutoImportProvider ! ( ) ! : program , host ) ;
412
- } ) ;
413
-
414
- forEachExternalModuleToImportFrom ( program , host , preferences , useAutoImportProvider , ( moduleSymbol , moduleFile , program , isFromPackageJson ) => {
415
- const checker = program . getTypeChecker ( ) ;
416
- // Don't import from a re-export when looking "up" like to `./index` or `../index`.
417
- if ( moduleFile && moduleSymbol !== exportingModuleSymbol && startsWith ( importingFile . fileName , getDirectoryPath ( moduleFile . fileName ) ) ) {
418
- return ;
419
- }
420
-
421
- const defaultInfo = getDefaultLikeExportInfo ( moduleSymbol , checker , compilerOptions ) ;
422
- if ( defaultInfo && ( defaultInfo . name === symbolName || moduleSymbolToValidIdentifier ( moduleSymbol , getEmitScriptTarget ( compilerOptions ) , isJsxTagName ) === symbolName ) && skipAlias ( defaultInfo . symbol , checker ) === targetSymbol && isImportable ( program , moduleFile , isFromPackageJson ) ) {
423
- result . push ( { symbol : defaultInfo . symbol , moduleSymbol, moduleFileName : moduleFile ?. fileName , exportKind : defaultInfo . exportKind , targetFlags : skipAlias ( defaultInfo . symbol , checker ) . flags , isFromPackageJson } ) ;
424
- }
425
-
426
- for ( const exported of checker . getExportsAndPropertiesOfModule ( moduleSymbol ) ) {
427
- if ( exported . name === symbolName && checker . getMergedSymbol ( skipAlias ( exported , checker ) ) === targetSymbol && isImportable ( program , moduleFile , isFromPackageJson ) ) {
428
- result . push ( { symbol : exported , moduleSymbol, moduleFileName : moduleFile ?. fileName , exportKind : ExportKind . Named , targetFlags : skipAlias ( exported , checker ) . flags , isFromPackageJson } ) ;
429
- }
430
- }
431
- } ) ;
432
- return result ;
433
-
434
- function isImportable ( program : Program , moduleFile : SourceFile | undefined , isFromPackageJson : boolean ) {
435
- return ! moduleFile || isImportableFile ( program , importingFile , moduleFile , preferences , /*packageJsonFilter*/ undefined , getModuleSpecifierResolutionHost ( isFromPackageJson ) , host . getModuleSpecifierCache ?.( ) ) ;
436
- }
437
- }
438
-
439
421
function getImportFixes (
440
422
exportInfos : readonly SymbolExportInfo [ ] ,
441
423
useNamespaceInfo : {
@@ -661,6 +643,10 @@ namespace ts.codefix {
661
643
return true ;
662
644
}
663
645
646
+ function createGetChecker ( program : Program , host : LanguageServiceHost ) {
647
+ return memoizeOne ( ( isFromPackageJson : boolean ) => isFromPackageJson ? host . getPackageJsonAutoImportProvider ! ( ) ! . getTypeChecker ( ) : program . getTypeChecker ( ) ) ;
648
+ }
649
+
664
650
function getNewImportFixes (
665
651
program : Program ,
666
652
sourceFile : SourceFile ,
@@ -675,7 +661,7 @@ namespace ts.codefix {
675
661
const isJs = isSourceFileJS ( sourceFile ) ;
676
662
const compilerOptions = program . getCompilerOptions ( ) ;
677
663
const moduleSpecifierResolutionHost = createModuleSpecifierResolutionHost ( program , host ) ;
678
- const getChecker = memoizeOne ( ( isFromPackageJson : boolean ) => isFromPackageJson ? host . getPackageJsonAutoImportProvider ! ( ) ! . getTypeChecker ( ) : program . getTypeChecker ( ) ) ;
664
+ const getChecker = createGetChecker ( program , host ) ;
679
665
const rejectNodeModulesRelativePaths = moduleResolutionUsesNodeModules ( getEmitModuleResolutionKind ( compilerOptions ) ) ;
680
666
const getModuleSpecifiers = fromCacheOnly
681
667
? ( moduleSymbol : Symbol ) => ( { moduleSpecifiers : moduleSpecifiers . tryGetModuleSpecifiersFromCache ( moduleSymbol , sourceFile , moduleSpecifierResolutionHost , preferences ) , computedWithoutCache : false } )
0 commit comments