@@ -83,7 +83,7 @@ namespace ts.codefix {
8383 const symbol = checker . getMergedSymbol ( skipAlias ( exportedSymbol , checker ) ) ;
8484 const exportInfo = getAllReExportingModules ( sourceFile , symbol , moduleSymbol , symbolName , /*isJsxTagName*/ false , host , program , preferences , useAutoImportProvider ) ;
8585 const useRequire = shouldUseRequire ( sourceFile , program ) ;
86- const fix = getImportFixForSymbol ( sourceFile , exportInfo , moduleSymbol , symbolName , program , /*position */ undefined , ! ! isValidTypeOnlyUseSite , useRequire , host , preferences ) ;
86+ const fix = getImportFixForSymbol ( sourceFile , exportInfo , moduleSymbol , program , /*useNamespaceInfo */ undefined , ! ! isValidTypeOnlyUseSite , useRequire , host , preferences ) ;
8787 if ( fix ) {
8888 addImport ( { fixes : [ fix ] , symbolName, errorIdentifierText : undefined } ) ;
8989 }
@@ -310,7 +310,7 @@ namespace ts.codefix {
310310 : getAllReExportingModules ( sourceFile , targetSymbol , moduleSymbol , symbolName , isJsxTagName , host , program , preferences , /*useAutoImportProvider*/ true ) ;
311311 const useRequire = shouldUseRequire ( sourceFile , program ) ;
312312 const isValidTypeOnlyUseSite = isValidTypeOnlyAliasUseSite ( getTokenAtPosition ( sourceFile , position ) ) ;
313- const fix = Debug . checkDefined ( getImportFixForSymbol ( sourceFile , exportInfos , moduleSymbol , symbolName , program , position , isValidTypeOnlyUseSite , useRequire , host , preferences ) ) ;
313+ const fix = Debug . checkDefined ( getImportFixForSymbol ( sourceFile , exportInfos , moduleSymbol , program , { symbolName , position } , isValidTypeOnlyUseSite , useRequire , host , preferences ) ) ;
314314 return {
315315 moduleSpecifier : fix . moduleSpecifier ,
316316 codeAction : codeFixActionToCodeAction ( codeActionForFix (
@@ -331,10 +331,10 @@ namespace ts.codefix {
331331 return fix && codeFixActionToCodeAction ( codeActionForFix ( { host, formatContext, preferences } , sourceFile , symbolName , fix , includeSymbolNameInDescription , QuotePreference . Double , compilerOptions ) ) ;
332332 }
333333
334- function getImportFixForSymbol ( sourceFile : SourceFile , exportInfos : readonly SymbolExportInfo [ ] , moduleSymbol : Symbol , symbolName : string , program : Program , position : number | undefined , isValidTypeOnlyUseSite : boolean , useRequire : boolean , host : LanguageServiceHost , preferences : UserPreferences ) {
334+ function getImportFixForSymbol ( sourceFile : SourceFile , exportInfos : readonly SymbolExportInfo [ ] , moduleSymbol : Symbol , program : Program , useNamespaceInfo : { position : number , symbolName : string } | undefined , isValidTypeOnlyUseSite : boolean , useRequire : boolean , host : LanguageServiceHost , preferences : UserPreferences ) {
335335 Debug . assert ( exportInfos . some ( info => info . moduleSymbol === moduleSymbol || info . symbol . parent === moduleSymbol ) , "Some exportInfo should match the specified moduleSymbol" ) ;
336336 const packageJsonImportFilter = createPackageJsonImportFilter ( sourceFile , preferences , host ) ;
337- return getBestFix ( getImportFixes ( exportInfos , symbolName , position , isValidTypeOnlyUseSite , useRequire , program , sourceFile , host , preferences ) , sourceFile , program , packageJsonImportFilter , host ) ;
337+ return getBestFix ( getImportFixes ( exportInfos , useNamespaceInfo , isValidTypeOnlyUseSite , useRequire , program , sourceFile , host , preferences ) . fixes , sourceFile , program , packageJsonImportFilter , host ) ;
338338 }
339339
340340 function codeFixActionToCodeAction ( { description, changes, commands } : CodeFixAction ) : CodeAction {
@@ -396,20 +396,23 @@ namespace ts.codefix {
396396
397397 export function getModuleSpecifierForBestExportInfo (
398398 exportInfo : readonly SymbolExportInfo [ ] ,
399+ symbolName : string ,
400+ position : number ,
401+ isValidTypeOnlyUseSite : boolean ,
399402 importingFile : SourceFile ,
400403 program : Program ,
401404 host : LanguageServiceHost ,
402405 preferences : UserPreferences ,
403406 packageJsonImportFilter ?: PackageJsonImportFilter ,
404407 fromCacheOnly ?: boolean ,
405408 ) : { exportInfo ?: SymbolExportInfo , moduleSpecifier : string , computedWithoutCacheCount : number } | undefined {
406- const { fixes, computedWithoutCacheCount } = getNewImportFixes (
409+ const { fixes, computedWithoutCacheCount } = getImportFixes (
410+ exportInfo ,
411+ { symbolName, position } ,
412+ isValidTypeOnlyUseSite ,
413+ /*useRequire*/ false ,
407414 program ,
408415 importingFile ,
409- /*position*/ undefined ,
410- /*isValidTypeOnlyUseSite*/ false ,
411- /*useRequire*/ false ,
412- exportInfo ,
413416 host ,
414417 preferences ,
415418 fromCacheOnly ) ;
@@ -419,23 +422,46 @@ namespace ts.codefix {
419422
420423 function getImportFixes (
421424 exportInfos : readonly SymbolExportInfo [ ] ,
422- symbolName : string ,
425+ useNamespaceInfo : {
426+ symbolName : string ,
427+ position : number ,
428+ } | undefined ,
423429 /** undefined only for missing JSX namespace */
424- position : number | undefined ,
425430 isValidTypeOnlyUseSite : boolean ,
426431 useRequire : boolean ,
427432 program : Program ,
428433 sourceFile : SourceFile ,
429434 host : LanguageServiceHost ,
430435 preferences : UserPreferences ,
431- ) : readonly ImportFixWithModuleSpecifier [ ] {
436+ fromCacheOnly ?: boolean ,
437+ ) : { computedWithoutCacheCount : number , fixes : readonly ImportFixWithModuleSpecifier [ ] } {
432438 const checker = program . getTypeChecker ( ) ;
433439 const existingImports = flatMap ( exportInfos , info => getExistingImportDeclarations ( info , checker , sourceFile , program . getCompilerOptions ( ) ) ) ;
434- const useNamespace = position === undefined ? undefined : tryUseExistingNamespaceImport ( existingImports , symbolName , position , checker ) ;
440+ const useNamespace = useNamespaceInfo && tryUseExistingNamespaceImport ( existingImports , useNamespaceInfo . symbolName , useNamespaceInfo . position , checker ) ;
435441 const addToExisting = tryAddToExistingImport ( existingImports , isValidTypeOnlyUseSite , checker , program . getCompilerOptions ( ) ) ;
436- // Don't bother providing an action to add a new import if we can add to an existing one.
437- const addImport = addToExisting ? [ addToExisting ] : getFixesForAddImport ( exportInfos , existingImports , program , sourceFile , position , isValidTypeOnlyUseSite , useRequire , host , preferences ) ;
438- return [ ...( useNamespace ? [ useNamespace ] : emptyArray ) , ...addImport ] ;
442+ if ( addToExisting ) {
443+ // Don't bother providing an action to add a new import if we can add to an existing one.
444+ return {
445+ computedWithoutCacheCount : 0 ,
446+ fixes : [ ...( useNamespace ? [ useNamespace ] : emptyArray ) , addToExisting ] ,
447+ } ;
448+ }
449+
450+ const { fixes, computedWithoutCacheCount = 0 } = getFixesForAddImport (
451+ exportInfos ,
452+ existingImports ,
453+ program ,
454+ sourceFile ,
455+ useNamespaceInfo ?. position ,
456+ isValidTypeOnlyUseSite ,
457+ useRequire ,
458+ host ,
459+ preferences ,
460+ fromCacheOnly ) ;
461+ return {
462+ computedWithoutCacheCount,
463+ fixes : [ ...( useNamespace ? [ useNamespace ] : emptyArray ) , ...fixes ] ,
464+ } ;
439465 }
440466
441467 function tryUseExistingNamespaceImport ( existingImports : readonly FixAddToExistingImportInfo [ ] , symbolName : string , position : number , checker : TypeChecker ) : FixUseNamespaceImport | undefined {
@@ -658,9 +684,10 @@ namespace ts.codefix {
658684 useRequire : boolean ,
659685 host : LanguageServiceHost ,
660686 preferences : UserPreferences ,
661- ) : readonly ( FixAddNewImport | FixAddJsdocTypeImport ) [ ] {
687+ fromCacheOnly ?: boolean ,
688+ ) : { computedWithoutCacheCount ?: number , fixes : readonly ( FixAddNewImport | FixAddJsdocTypeImport ) [ ] } {
662689 const existingDeclaration = firstDefined ( existingImports , info => newImportInfoFromExistingSpecifier ( info , isValidTypeOnlyUseSite , useRequire , program . getTypeChecker ( ) , program . getCompilerOptions ( ) ) ) ;
663- return existingDeclaration ? [ existingDeclaration ] : getNewImportFixes ( program , sourceFile , position , isValidTypeOnlyUseSite , useRequire , exportInfos , host , preferences ) . fixes ;
690+ return existingDeclaration ? { fixes : [ existingDeclaration ] } : getNewImportFixes ( program , sourceFile , position , isValidTypeOnlyUseSite , useRequire , exportInfos , host , preferences , fromCacheOnly ) ;
664691 }
665692
666693 function newImportInfoFromExistingSpecifier (
@@ -782,7 +809,8 @@ namespace ts.codefix {
782809 const symbolName = umdSymbol . name ;
783810 const exportInfo : readonly SymbolExportInfo [ ] = [ { symbol : umdSymbol , moduleSymbol : symbol , moduleFileName : undefined , exportKind : ExportKind . UMD , targetFlags : symbol . flags , isFromPackageJson : false } ] ;
784811 const useRequire = shouldUseRequire ( sourceFile , program ) ;
785- const fixes = getImportFixes ( exportInfo , symbolName , isIdentifier ( token ) ? token . getStart ( sourceFile ) : undefined , /*isValidTypeOnlyUseSite*/ false , useRequire , program , sourceFile , host , preferences ) ;
812+ const position = isIdentifier ( token ) ? token . getStart ( sourceFile ) : undefined ;
813+ const fixes = getImportFixes ( exportInfo , position ? { position, symbolName } : undefined , /*isValidTypeOnlyUseSite*/ false , useRequire , program , sourceFile , host , preferences ) . fixes ;
786814 return { fixes, symbolName, errorIdentifierText : tryCast ( token , isIdentifier ) ?. text } ;
787815 }
788816 function getUmdSymbol ( token : Node , checker : TypeChecker ) : Symbol | undefined {
@@ -855,7 +883,7 @@ namespace ts.codefix {
855883 const useRequire = shouldUseRequire ( sourceFile , program ) ;
856884 const exportInfo = getExportInfos ( symbolName , isJSXTagName ( symbolToken ) , getMeaningFromLocation ( symbolToken ) , cancellationToken , sourceFile , program , useAutoImportProvider , host , preferences ) ;
857885 const fixes = arrayFrom ( flatMapIterator ( exportInfo . entries ( ) , ( [ _ , exportInfos ] ) =>
858- getImportFixes ( exportInfos , symbolName , symbolToken . getStart ( sourceFile ) , isValidTypeOnlyUseSite , useRequire , program , sourceFile , host , preferences ) ) ) ;
886+ getImportFixes ( exportInfos , { symbolName, position : symbolToken . getStart ( sourceFile ) } , isValidTypeOnlyUseSite , useRequire , program , sourceFile , host , preferences ) . fixes ) ) ;
859887 return { fixes, symbolName, errorIdentifierText : symbolToken . text } ;
860888 }
861889
0 commit comments