@@ -2,7 +2,8 @@ import _ from 'lodash'
2
2
import addMissingProperties from './codeFixes/addMissingProperties'
3
3
import { changeSortingOfAutoImport , getIgnoreAutoImportSetting , isAutoImportEntryShouldBeIgnored } from './adjustAutoImports'
4
4
import { GetConfig } from './types'
5
- import { findChildContainingPosition , getIndentFromPos , patchMethod } from './utils'
5
+ import { findChildContainingPosition , getCancellationToken , getIndentFromPos , patchMethod } from './utils'
6
+ import namespaceAutoImports from './namespaceAutoImports'
6
7
7
8
// codeFixes that I managed to put in files
8
9
const externalCodeFixes = [ addMissingProperties ]
@@ -22,33 +23,61 @@ export default (proxy: ts.LanguageService, languageService: ts.LanguageService,
22
23
[ Diagnostics . Remove_type_from_import_of_0_from_1 , 1 , 0 ] ,
23
24
[ Diagnostics . Remove_type_from_import_declaration_from_0 , 0 ] ,
24
25
]
25
- const oldCreateCodeFixAction = tsFull . codefix . createCodeFixAction
26
+ const addNamespaceImports = [ ] as ts . CodeFixAction [ ]
27
+
26
28
let prior : readonly ts . CodeFixAction [ ]
29
+ let toUnpatch : ( ( ) => void ) [ ] = [ ]
27
30
try {
28
31
const { importFixName } = tsFull . codefix
29
32
const ignoreAutoImportsSetting = getIgnoreAutoImportSetting ( c )
30
33
const sortFn = changeSortingOfAutoImport ( c , ( node as ts . Identifier ) . text )
31
- tsFull . codefix . createCodeFixAction = ( fixName , changes , description , fixId , fixAllDescription , command ) => {
32
- if ( fixName !== importFixName ) return oldCreateCodeFixAction ( fixName , changes , description , fixId , fixAllDescription , command )
33
- const placeholderIndexesInfo = moduleSymbolDescriptionPlaceholders . find ( ( [ diag ] ) => diag === description [ 0 ] )
34
- let sorting = '-1'
35
- if ( placeholderIndexesInfo ) {
36
- const targetModule = description [ placeholderIndexesInfo [ 1 ] + 1 ]
37
- const symbolName = placeholderIndexesInfo [ 2 ] !== undefined ? description [ placeholderIndexesInfo [ 2 ] + 1 ] : ( node as ts . Identifier ) . text
38
- const toIgnore = isAutoImportEntryShouldBeIgnored ( ignoreAutoImportsSetting , targetModule , symbolName )
39
- if ( toIgnore ) {
40
- return {
41
- fixName : 'IGNORE' ,
42
- changes : [ ] ,
43
- description : '' ,
34
+ const unpatch = patchMethod (
35
+ tsFull . codefix ,
36
+ 'createCodeFixAction' ,
37
+ oldCreateCodeFixAction => ( fixName , changes , description , fixId , fixAllDescription , command ) => {
38
+ if ( fixName !== importFixName ) return oldCreateCodeFixAction ( fixName , changes , description , fixId , fixAllDescription , command )
39
+ const placeholderIndexesInfo = moduleSymbolDescriptionPlaceholders . find ( ( [ diag ] ) => diag === description [ 0 ] )
40
+ let sorting = '-1'
41
+ if ( placeholderIndexesInfo ) {
42
+ const targetModule = description [ placeholderIndexesInfo [ 1 ] + 1 ]
43
+ const symbolName = placeholderIndexesInfo [ 2 ] !== undefined ? description [ placeholderIndexesInfo [ 2 ] + 1 ] : ( node as ts . Identifier ) . text
44
+
45
+ const toIgnore = isAutoImportEntryShouldBeIgnored ( ignoreAutoImportsSetting , targetModule , symbolName )
46
+
47
+ const namespaceImportAction =
48
+ ! toIgnore && namespaceAutoImports ( c , sourceFile , targetModule , preferences , formatOptions , start , symbolName )
49
+
50
+ if ( namespaceImportAction ) {
51
+ const { textChanges, description } = namespaceImportAction
52
+ addNamespaceImports . push ( {
53
+ fixName : importFixName ,
54
+ fixAllDescription : 'Add all missing imports' ,
55
+ fixId : 'fixMissingImport' ,
56
+ description,
57
+ changes : [
58
+ {
59
+ fileName,
60
+ textChanges,
61
+ } ,
62
+ ] ,
63
+ } )
64
+ }
65
+ if ( toIgnore /* || namespaceImportAction */ ) {
66
+ return {
67
+ fixName : 'IGNORE' ,
68
+ changes : [ ] ,
69
+ description : '' ,
70
+ }
44
71
}
72
+ sorting = sortFn ( targetModule ) . toString ( )
73
+ // todo this workaround is weird, sort in another way
45
74
}
46
- sorting = sortFn ( targetModule ) . toString ( )
47
- // todo this workaround is weird, sort in another way
48
- }
49
- return oldCreateCodeFixAction ( fixName + sorting , changes , description , fixId , fixAllDescription , command )
50
- }
75
+ return oldCreateCodeFixAction ( fixName + sorting , changes , description , fixId , fixAllDescription , command )
76
+ } ,
77
+ )
78
+ toUnpatch . push ( unpatch )
51
79
prior = languageService . getCodeFixesAtPosition ( fileName , start , end , errorCodes , formatOptions , preferences )
80
+ prior = [ ...addNamespaceImports , ...prior ]
52
81
prior = _ . sortBy ( prior , ( { fixName } ) => {
53
82
if ( fixName . startsWith ( importFixName ) ) {
54
83
return + fixName . slice ( importFixName . length )
@@ -63,7 +92,7 @@ export default (proxy: ts.LanguageService, languageService: ts.LanguageService,
63
92
throw err
64
93
} )
65
94
} finally {
66
- tsFull . codefix . createCodeFixAction = oldCreateCodeFixAction
95
+ toUnpatch . forEach ( x => x ( ) )
67
96
}
68
97
// todo remove when 5.0 is released after 3 months
69
98
// #region fix builtin codefixes/refactorings
@@ -150,12 +179,8 @@ export default (proxy: ts.LanguageService, languageService: ts.LanguageService,
150
179
languageServiceHost as any /* cancellationToken */ ,
151
180
)
152
181
const semanticDiagnostics = languageService . getSemanticDiagnostics ( fileName )
153
- const cancellationToken = languageServiceHost . getCompilerHost ?.( ) ?. getCancellationToken ?.( ) ?? {
154
- isCancellationRequested : ( ) => false ,
155
- throwIfCancellationRequested : ( ) => { } ,
156
- }
157
182
const context : Record < keyof import ( 'typescript-full' ) . CodeFixContextBase , any > = {
158
- cancellationToken,
183
+ cancellationToken : getCancellationToken ( languageServiceHost ) ,
159
184
formatContext : tsFull . formatting . getFormatContext ( formatOptions , languageServiceHost ) ,
160
185
host : languageServiceHost ,
161
186
preferences,
@@ -164,6 +189,7 @@ export default (proxy: ts.LanguageService, languageService: ts.LanguageService,
164
189
}
165
190
const errorCodes = getFixAllErrorCodes ( )
166
191
const ignoreAutoImportsSetting = getIgnoreAutoImportSetting ( c )
192
+ const additionalTextChanges : ts . TextChange [ ] = [ ]
167
193
for ( const diagnostic of semanticDiagnostics ) {
168
194
if ( ! errorCodes . includes ( diagnostic . code ) ) continue
169
195
const toUnpatch : ( ( ) => any ) [ ] = [ ]
@@ -185,6 +211,38 @@ export default (proxy: ts.LanguageService, languageService: ts.LanguageService,
185
211
} ) ,
186
212
( { fix } ) => sortFn ( fix . moduleSpecifier ) ,
187
213
)
214
+ const firstFix = fixes [ 0 ]
215
+ const namespaceImportAction =
216
+ ! ! firstFix &&
217
+ namespaceAutoImports (
218
+ c ,
219
+ sourceFile ,
220
+ firstFix . fix . moduleSpecifier ,
221
+ preferences ,
222
+ formatOptions ,
223
+ diagnostic . start ! ,
224
+ firstFix . symbolName ,
225
+ )
226
+ if ( namespaceImportAction ) {
227
+ fixes = [ ]
228
+ if ( ! namespaceImportAction . namespace ) {
229
+ additionalTextChanges . push ( ...namespaceImportAction . textChanges )
230
+ } else {
231
+ const { namespace, useDefaultImport, textChanges } = namespaceImportAction
232
+ additionalTextChanges . push ( textChanges [ 1 ] ! )
233
+ fixes . unshift ( {
234
+ ...fixes [ 0 ] ! ,
235
+ fix : {
236
+ kind : ImportFixKind . AddNew ,
237
+ moduleSpecifier : firstFix . fix . moduleSpecifier ,
238
+ importKind : useDefaultImport ? tsFull . ImportKind . Default : tsFull . ImportKind . Namespace ,
239
+ addAsTypeOnly : false ,
240
+ useRequire : false ,
241
+ } ,
242
+ symbolName : namespace ,
243
+ } as FixInfo )
244
+ }
245
+ }
188
246
if ( ! fixes [ 0 ] ) throw new Error ( 'No fixes' )
189
247
return fixes [ 0 ]
190
248
} ) as any ,
@@ -209,7 +267,10 @@ export default (proxy: ts.LanguageService, languageService: ts.LanguageService,
209
267
}
210
268
}
211
269
}
212
- return tsFull . codefix . createCombinedCodeActions ( tsFull . textChanges . ChangeTracker . with ( context , importAdder . writeFixes ) )
270
+ return tsFull . codefix . createCombinedCodeActions ( [
271
+ ...tsFull . textChanges . ChangeTracker . with ( context , importAdder . writeFixes ) ,
272
+ { fileName, textChanges : additionalTextChanges } ,
273
+ ] )
213
274
}
214
275
return languageService . getCombinedCodeFix ( scope , fixId , formatOptions , preferences )
215
276
}
0 commit comments