@@ -83,7 +83,7 @@ namespace ts.codefix {
83
83
const symbol = checker . getMergedSymbol ( skipAlias ( exportedSymbol , checker ) ) ;
84
84
const exportInfo = getAllReExportingModules ( sourceFile , symbol , moduleSymbol , symbolName , /*isJsxTagName*/ false , host , program , preferences , useAutoImportProvider ) ;
85
85
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 ) ;
87
87
if ( fix ) {
88
88
addImport ( { fixes : [ fix ] , symbolName, errorIdentifierText : undefined } ) ;
89
89
}
@@ -310,7 +310,7 @@ namespace ts.codefix {
310
310
: getAllReExportingModules ( sourceFile , targetSymbol , moduleSymbol , symbolName , isJsxTagName , host , program , preferences , /*useAutoImportProvider*/ true ) ;
311
311
const useRequire = shouldUseRequire ( sourceFile , program ) ;
312
312
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 ) ) ;
314
314
return {
315
315
moduleSpecifier : fix . moduleSpecifier ,
316
316
codeAction : codeFixActionToCodeAction ( codeActionForFix (
@@ -331,10 +331,10 @@ namespace ts.codefix {
331
331
return fix && codeFixActionToCodeAction ( codeActionForFix ( { host, formatContext, preferences } , sourceFile , symbolName , fix , includeSymbolNameInDescription , QuotePreference . Double , compilerOptions ) ) ;
332
332
}
333
333
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 ) {
335
335
Debug . assert ( exportInfos . some ( info => info . moduleSymbol === moduleSymbol || info . symbol . parent === moduleSymbol ) , "Some exportInfo should match the specified moduleSymbol" ) ;
336
336
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 ) ;
338
338
}
339
339
340
340
function codeFixActionToCodeAction ( { description, changes, commands } : CodeFixAction ) : CodeAction {
@@ -396,20 +396,23 @@ namespace ts.codefix {
396
396
397
397
export function getModuleSpecifierForBestExportInfo (
398
398
exportInfo : readonly SymbolExportInfo [ ] ,
399
+ symbolName : string ,
400
+ position : number ,
401
+ isValidTypeOnlyUseSite : boolean ,
399
402
importingFile : SourceFile ,
400
403
program : Program ,
401
404
host : LanguageServiceHost ,
402
405
preferences : UserPreferences ,
403
406
packageJsonImportFilter ?: PackageJsonImportFilter ,
404
407
fromCacheOnly ?: boolean ,
405
408
) : { 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 ,
407
414
program ,
408
415
importingFile ,
409
- /*position*/ undefined ,
410
- /*isValidTypeOnlyUseSite*/ false ,
411
- /*useRequire*/ false ,
412
- exportInfo ,
413
416
host ,
414
417
preferences ,
415
418
fromCacheOnly ) ;
@@ -419,23 +422,46 @@ namespace ts.codefix {
419
422
420
423
function getImportFixes (
421
424
exportInfos : readonly SymbolExportInfo [ ] ,
422
- symbolName : string ,
425
+ useNamespaceInfo : {
426
+ symbolName : string ,
427
+ position : number ,
428
+ } | undefined ,
423
429
/** undefined only for missing JSX namespace */
424
- position : number | undefined ,
425
430
isValidTypeOnlyUseSite : boolean ,
426
431
useRequire : boolean ,
427
432
program : Program ,
428
433
sourceFile : SourceFile ,
429
434
host : LanguageServiceHost ,
430
435
preferences : UserPreferences ,
431
- ) : readonly ImportFixWithModuleSpecifier [ ] {
436
+ fromCacheOnly ?: boolean ,
437
+ ) : { computedWithoutCacheCount : number , fixes : readonly ImportFixWithModuleSpecifier [ ] } {
432
438
const checker = program . getTypeChecker ( ) ;
433
439
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 ) ;
435
441
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
+ } ;
439
465
}
440
466
441
467
function tryUseExistingNamespaceImport ( existingImports : readonly FixAddToExistingImportInfo [ ] , symbolName : string , position : number , checker : TypeChecker ) : FixUseNamespaceImport | undefined {
@@ -658,9 +684,10 @@ namespace ts.codefix {
658
684
useRequire : boolean ,
659
685
host : LanguageServiceHost ,
660
686
preferences : UserPreferences ,
661
- ) : readonly ( FixAddNewImport | FixAddJsdocTypeImport ) [ ] {
687
+ fromCacheOnly ?: boolean ,
688
+ ) : { computedWithoutCacheCount ?: number , fixes : readonly ( FixAddNewImport | FixAddJsdocTypeImport ) [ ] } {
662
689
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 ) ;
664
691
}
665
692
666
693
function newImportInfoFromExistingSpecifier (
@@ -782,7 +809,8 @@ namespace ts.codefix {
782
809
const symbolName = umdSymbol . name ;
783
810
const exportInfo : readonly SymbolExportInfo [ ] = [ { symbol : umdSymbol , moduleSymbol : symbol , moduleFileName : undefined , exportKind : ExportKind . UMD , targetFlags : symbol . flags , isFromPackageJson : false } ] ;
784
811
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 ;
786
814
return { fixes, symbolName, errorIdentifierText : tryCast ( token , isIdentifier ) ?. text } ;
787
815
}
788
816
function getUmdSymbol ( token : Node , checker : TypeChecker ) : Symbol | undefined {
@@ -855,7 +883,7 @@ namespace ts.codefix {
855
883
const useRequire = shouldUseRequire ( sourceFile , program ) ;
856
884
const exportInfo = getExportInfos ( symbolName , isJSXTagName ( symbolToken ) , getMeaningFromLocation ( symbolToken ) , cancellationToken , sourceFile , program , useAutoImportProvider , host , preferences ) ;
857
885
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 ) ) ;
859
887
return { fixes, symbolName, errorIdentifierText : symbolToken . text } ;
860
888
}
861
889
0 commit comments