@@ -32,8 +32,8 @@ namespace ts.codefix {
3232 } ,
3333 fixIds : [ importFixId ] ,
3434 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 ) ;
3737 eachDiagnostic ( context , errorCodes , diag => importAdder . addImportFromDiagnostic ( diag , context ) ) ;
3838 return createCombinedCodeActions ( textChanges . ChangeTracker . with ( context , importAdder . writeFixes ) ) ;
3939 } ,
@@ -49,8 +49,8 @@ namespace ts.codefix {
4949 writeFixes : ( changeTracker : textChanges . ChangeTracker ) => void ;
5050 }
5151
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 ) ;
5454 }
5555
5656 interface AddToExistingState {
@@ -59,7 +59,7 @@ namespace ts.codefix {
5959 readonly namedImports : ESMap < string , AddAsTypeOnly > ;
6060 }
6161
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 {
6363 const compilerOptions = program . getCompilerOptions ( ) ;
6464 // Namespace fixes don't conflict, so just build a list.
6565 const addToNamespace : FixUseNamespaceImport [ ] = [ ] ;
@@ -83,9 +83,9 @@ namespace ts.codefix {
8383 const symbolName = getNameForExportedSymbol ( exportedSymbol , getEmitScriptTarget ( compilerOptions ) ) ;
8484 const checker = program . getTypeChecker ( ) ;
8585 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 ) ;
8787 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 ) ;
8989 if ( fix ) {
9090 addImport ( { fix, symbolName, errorIdentifierText : undefined } ) ;
9191 }
@@ -345,11 +345,15 @@ namespace ts.codefix {
345345 formatContext : formatting . FormatContext ,
346346 position : number ,
347347 preferences : UserPreferences ,
348+ cancellationToken : CancellationToken ,
348349 ) : { readonly moduleSpecifier : string , readonly codeAction : CodeAction } {
349350 const compilerOptions = program . getCompilerOptions ( ) ;
351+
350352 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 ) ;
353357 const useRequire = shouldUseRequire ( sourceFile , program ) ;
354358 const isValidTypeOnlyUseSite = isValidTypeOnlyAliasUseSite ( getTokenAtPosition ( sourceFile , position ) ) ;
355359 const fix = Debug . checkDefined ( getImportFixForSymbol ( sourceFile , exportInfos , moduleSymbol , program , { symbolName, position } , isValidTypeOnlyUseSite , useRequire , host , preferences ) ) ;
@@ -383,7 +387,17 @@ namespace ts.codefix {
383387 return { description, changes, commands } ;
384388 }
385389
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 {
387401 const compilerOptions = program . getCompilerOptions ( ) ;
388402 const mainProgramInfo = getInfoWithChecker ( program . getTypeChecker ( ) , /*isFromPackageJson*/ false ) ;
389403 if ( mainProgramInfo ) {
@@ -404,38 +418,6 @@ namespace ts.codefix {
404418 }
405419 }
406420
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-
439421 function getImportFixes (
440422 exportInfos : readonly SymbolExportInfo [ ] ,
441423 useNamespaceInfo : {
@@ -661,6 +643,10 @@ namespace ts.codefix {
661643 return true ;
662644 }
663645
646+ function createGetChecker ( program : Program , host : LanguageServiceHost ) {
647+ return memoizeOne ( ( isFromPackageJson : boolean ) => isFromPackageJson ? host . getPackageJsonAutoImportProvider ! ( ) ! . getTypeChecker ( ) : program . getTypeChecker ( ) ) ;
648+ }
649+
664650 function getNewImportFixes (
665651 program : Program ,
666652 sourceFile : SourceFile ,
@@ -675,7 +661,7 @@ namespace ts.codefix {
675661 const isJs = isSourceFileJS ( sourceFile ) ;
676662 const compilerOptions = program . getCompilerOptions ( ) ;
677663 const moduleSpecifierResolutionHost = createModuleSpecifierResolutionHost ( program , host ) ;
678- const getChecker = memoizeOne ( ( isFromPackageJson : boolean ) => isFromPackageJson ? host . getPackageJsonAutoImportProvider ! ( ) ! . getTypeChecker ( ) : program . getTypeChecker ( ) ) ;
664+ const getChecker = createGetChecker ( program , host ) ;
679665 const rejectNodeModulesRelativePaths = moduleResolutionUsesNodeModules ( getEmitModuleResolutionKind ( compilerOptions ) ) ;
680666 const getModuleSpecifiers = fromCacheOnly
681667 ? ( moduleSymbol : Symbol ) => ( { moduleSpecifiers : moduleSpecifiers . tryGetModuleSpecifiersFromCache ( moduleSymbol , sourceFile , moduleSpecifierResolutionHost , preferences ) , computedWithoutCache : false } )
0 commit comments