@@ -25,16 +25,15 @@ namespace ts.codefix {
25
25
numberOfAssignmentsOriginal : number ;
26
26
}
27
27
28
- interface SymbolAndIdentifierAndOriginalName {
28
+ interface SymbolAndIdentifier {
29
29
identifier : Identifier ;
30
30
symbol : Symbol ;
31
- originalName : string ;
32
31
}
33
32
34
33
interface Transformer {
35
34
checker : TypeChecker ;
36
35
synthNamesMap : Map < SynthIdentifier > ; // keys are the symbol id of the identifier
37
- allVarNames : SymbolAndIdentifierAndOriginalName [ ] ;
36
+ allVarNames : SymbolAndIdentifier [ ] ;
38
37
setOfExpressionsToReturn : Map < true > ; // keys are the node ids of the expressions
39
38
constIdentifiers : Identifier [ ] ;
40
39
originalTypeMap : Map < Type > ; // keys are the node id of the identifier
@@ -61,7 +60,7 @@ namespace ts.codefix {
61
60
62
61
const synthNamesMap : Map < SynthIdentifier > = createMap ( ) ;
63
62
const originalTypeMap : Map < Type > = createMap ( ) ;
64
- const allVarNames : SymbolAndIdentifierAndOriginalName [ ] = [ ] ;
63
+ const allVarNames : SymbolAndIdentifier [ ] = [ ] ;
65
64
const isInJSFile = isInJavaScriptFile ( functionToConvert ) ;
66
65
const setOfExpressionsToReturn = getAllPromiseExpressionsToReturn ( functionToConvert , checker ) ;
67
66
const functionToConvertRenamed : FunctionLikeDeclaration = renameCollidingVarNames ( functionToConvert , checker , synthNamesMap , context , setOfExpressionsToReturn , originalTypeMap , allVarNames ) ;
@@ -158,9 +157,10 @@ namespace ts.codefix {
158
157
This function collects all existing identifier names and names of identifiers that will be created in the refactor.
159
158
It then checks for any collisions and renames them through getSynthesizedDeepClone
160
159
*/
161
- function renameCollidingVarNames ( nodeToRename : FunctionLikeDeclaration , checker : TypeChecker , synthNamesMap : Map < SynthIdentifier > , context : CodeFixContextBase , setOfAllExpressionsToReturn : Map < true > , originalType : Map < Type > , allVarNames : SymbolAndIdentifierAndOriginalName [ ] ) : FunctionLikeDeclaration {
160
+ function renameCollidingVarNames ( nodeToRename : FunctionLikeDeclaration , checker : TypeChecker , synthNamesMap : Map < SynthIdentifier > , context : CodeFixContextBase , setOfAllExpressionsToReturn : Map < true > , originalType : Map < Type > , allVarNames : SymbolAndIdentifier [ ] ) : FunctionLikeDeclaration {
162
161
163
162
const identsToRenameMap : Map < Identifier > = createMap ( ) ; // key is the symbol id
163
+ const collidingSymbolMap : Map < Symbol [ ] > = createMap ( ) ;
164
164
forEachChild ( nodeToRename , function visit ( node : Node ) {
165
165
if ( ! isIdentifier ( node ) ) {
166
166
forEachChild ( node , visit ) ;
@@ -180,27 +180,31 @@ namespace ts.codefix {
180
180
if ( lastCallSignature && lastCallSignature . parameters . length && ! synthNamesMap . has ( symbolIdString ) ) {
181
181
const firstParameter = lastCallSignature . parameters [ 0 ] ;
182
182
const ident = isParameter ( firstParameter . valueDeclaration ) && tryCast ( firstParameter . valueDeclaration . name , isIdentifier ) || createOptimisticUniqueName ( "result" ) ;
183
- const synthName = getNewNameIfConflict ( ident , allVarNames ) ;
183
+ const synthName = getNewNameIfConflict ( ident , collidingSymbolMap ) ;
184
184
synthNamesMap . set ( symbolIdString , synthName ) ;
185
- allVarNames . push ( { identifier : synthName . identifier , symbol, originalName : ident . text } ) ;
185
+ allVarNames . push ( { identifier : synthName . identifier , symbol } ) ;
186
+ addNameToFrequencyMap ( collidingSymbolMap , ident . text , symbol ) ;
186
187
}
187
188
// we only care about identifiers that are parameters and declarations (don't care about other uses)
188
189
else if ( node . parent && ( isParameter ( node . parent ) || isVariableDeclaration ( node . parent ) ) ) {
189
190
const originalName = node . text ;
191
+ const collidingSymbols = collidingSymbolMap . get ( originalName ) ;
190
192
191
193
// if the identifier name conflicts with a different identifier that we've already seen
192
- if ( allVarNames . some ( ident => ident . originalName === node . text && ident . symbol !== symbol ) ) {
193
- const newName = getNewNameIfConflict ( node , allVarNames ) ;
194
+ if ( collidingSymbols && collidingSymbols . some ( prevSymbol => prevSymbol !== symbol ) ) {
195
+ const newName = getNewNameIfConflict ( node , collidingSymbolMap ) ;
194
196
identsToRenameMap . set ( symbolIdString , newName . identifier ) ;
195
197
synthNamesMap . set ( symbolIdString , newName ) ;
196
- allVarNames . push ( { identifier : newName . identifier , symbol, originalName } ) ;
198
+ allVarNames . push ( { identifier : newName . identifier , symbol } ) ;
199
+ addNameToFrequencyMap ( collidingSymbolMap , originalName , symbol ) ;
197
200
}
198
201
else {
199
202
const identifier = getSynthesizedDeepClone ( node ) ;
200
203
identsToRenameMap . set ( symbolIdString , identifier ) ;
201
204
synthNamesMap . set ( symbolIdString , { identifier, types : [ ] , numberOfAssignmentsOriginal : allVarNames . filter ( elem => elem . identifier . text === node . text ) . length /*, numberOfAssignmentsSynthesized: 0*/ } ) ;
202
205
if ( ( isParameter ( node . parent ) && isExpressionOrCallOnTypePromise ( node . parent . parent ) ) || isVariableDeclaration ( node . parent ) ) {
203
- allVarNames . push ( { identifier, symbol, originalName } ) ;
206
+ allVarNames . push ( { identifier, symbol } ) ;
207
+ addNameToFrequencyMap ( collidingSymbolMap , originalName , symbol ) ;
204
208
}
205
209
}
206
210
}
@@ -243,8 +247,17 @@ namespace ts.codefix {
243
247
244
248
}
245
249
246
- function getNewNameIfConflict ( name : Identifier , allVarNames : SymbolAndIdentifierAndOriginalName [ ] ) : SynthIdentifier {
247
- const numVarsSameName = allVarNames . filter ( elem => elem . originalName === name . text ) . length ;
250
+ function addNameToFrequencyMap ( renamedVarNameFrequencyMap : Map < Symbol [ ] > , originalName : string , symbol : Symbol ) {
251
+ if ( renamedVarNameFrequencyMap . has ( originalName ) ) {
252
+ renamedVarNameFrequencyMap . get ( originalName ) ! . push ( symbol ) ;
253
+ }
254
+ else {
255
+ renamedVarNameFrequencyMap . set ( originalName , [ symbol ] ) ;
256
+ }
257
+ }
258
+
259
+ function getNewNameIfConflict ( name : Identifier , originalNames : Map < Symbol [ ] > ) : SynthIdentifier {
260
+ const numVarsSameName = ( originalNames . get ( name . text ) || [ ] ) . length ;
248
261
const numberOfAssignmentsOriginal = 0 ;
249
262
const identifier = numVarsSameName === 0 ? name : createIdentifier ( name . text + "_" + numVarsSameName ) ;
250
263
return { identifier, types : [ ] , numberOfAssignmentsOriginal } ;
@@ -289,13 +302,14 @@ namespace ts.codefix {
289
302
prevArgName . numberOfAssignmentsOriginal = 2 ; // Try block and catch block
290
303
transformer . synthNamesMap . forEach ( ( val , key ) => {
291
304
if ( val . identifier . text === prevArgName . identifier . text ) {
292
- transformer . synthNamesMap . set ( key , getNewNameIfConflict ( prevArgName . identifier , transformer . allVarNames ) ) ;
305
+ const newSynthName = createUniqueSynthName ( prevArgName ) ;
306
+ transformer . synthNamesMap . set ( key , newSynthName ) ;
293
307
}
294
308
} ) ;
295
309
296
310
// update the constIdentifiers list
297
311
if ( transformer . constIdentifiers . some ( elem => elem . text === prevArgName . identifier . text ) ) {
298
- transformer . constIdentifiers . push ( getNewNameIfConflict ( prevArgName . identifier , transformer . allVarNames ) . identifier ) ;
312
+ transformer . constIdentifiers . push ( createUniqueSynthName ( prevArgName ) . identifier ) ;
299
313
}
300
314
}
301
315
@@ -321,6 +335,12 @@ namespace ts.codefix {
321
335
return varDeclList ? [ varDeclList , tryStatement ] : [ tryStatement ] ;
322
336
}
323
337
338
+ function createUniqueSynthName ( prevArgName : SynthIdentifier ) {
339
+ const renamedPrevArg = createOptimisticUniqueName ( prevArgName . identifier . text ) ;
340
+ const newSynthName = { identifier : renamedPrevArg , types : [ ] , numberOfAssignmentsOriginal : 0 } ;
341
+ return newSynthName ;
342
+ }
343
+
324
344
function transformThen ( node : CallExpression , transformer : Transformer , outermostParent : CallExpression , prevArgName ?: SynthIdentifier ) : Statement [ ] {
325
345
const [ res , rej ] = node . arguments ;
326
346
0 commit comments