@@ -9,43 +9,44 @@ namespace ts.codefix {
99 registerCodeFix ( {
1010 errorCodes,
1111 getCodeActions : ( context ) => {
12- const changes = textChanges . ChangeTracker . with ( context , t => makeChange ( t , context . sourceFile , context . span . start ) ) ;
12+ const changes = textChanges . ChangeTracker . with ( context , t => makeChange ( t , context . sourceFile , context . span . start , context . program ) ) ;
1313 if ( changes . length > 0 ) {
1414 return [ createCodeFixAction ( fixId , changes , Diagnostics . Add_const_to_unresolved_variable , fixId , Diagnostics . Add_const_to_all_unresolved_variables ) ] ;
1515 }
1616 } ,
1717 fixIds : [ fixId ] ,
1818 getAllCodeActions : context => {
1919 const fixedNodes = new NodeSet ( ) ;
20- return codeFixAll ( context , errorCodes , ( changes , diag ) => makeChange ( changes , diag . file , diag . start , fixedNodes ) ) ;
20+ return codeFixAll ( context , errorCodes , ( changes , diag ) => makeChange ( changes , diag . file , diag . start , context . program , fixedNodes ) ) ;
2121 } ,
2222 } ) ;
2323
24- function makeChange ( changeTracker : textChanges . ChangeTracker , sourceFile : SourceFile , pos : number , fixedNodes ?: NodeSet < Node > ) {
24+ function makeChange ( changeTracker : textChanges . ChangeTracker , sourceFile : SourceFile , pos : number , program : Program , fixedNodes ?: NodeSet < Node > ) {
2525 const token = getTokenAtPosition ( sourceFile , pos ) ;
26-
2726 const forInitializer = findAncestor ( token , node =>
28- isForInOrOfStatement ( node . parent ) ? node . parent . initializer === node
29- : isPossiblyPartOfDestructuring ( node ) ? false : "quit" ) ;
27+ isForInOrOfStatement ( node . parent ) ? node . parent . initializer === node :
28+ isPossiblyPartOfDestructuring ( node ) ? false : "quit"
29+ ) ;
3030 if ( forInitializer ) return applyChange ( changeTracker , forInitializer , sourceFile , fixedNodes ) ;
3131
3232 const parent = token . parent ;
33- const standaloneInitializer = isExpressionStatement ( parent . parent ) ;
34- if ( standaloneInitializer ) return applyChange ( changeTracker , parent , sourceFile , fixedNodes ) ;
33+ if ( isBinaryExpression ( parent ) && isExpressionStatement ( parent . parent ) ) {
34+ return applyChange ( changeTracker , token , sourceFile , fixedNodes ) ;
35+ }
3536
36- const arrayLiteralInitializer = isArrayLiteralExpression ( token . parent ) ;
37- if ( arrayLiteralInitializer ) {
38- const availableIdentifiers : string [ ] = [ ] ; // TODO: where to get/gather this information from?
39- const noIdentifiersDeclared = parent . forEachChild ( node => availableIdentifiers . indexOf ( node . getFullText ( ) ) < 0 ) ;
40- if ( ! noIdentifiersDeclared ) return ;
37+ if ( isArrayLiteralExpression ( parent ) ) {
38+ const checker = program . getTypeChecker ( ) ;
39+ if ( ! every ( parent . elements , element => arrayElementCouldBeVariableDeclaration ( element , checker ) ) ) {
40+ return ;
41+ }
4142
4243 return applyChange ( changeTracker , parent , sourceFile , fixedNodes ) ;
4344 }
4445 }
4546
4647 function applyChange ( changeTracker : textChanges . ChangeTracker , initializer : Node , sourceFile : SourceFile , fixedNodes ?: NodeSet < Node > ) {
4748 if ( ! fixedNodes || fixedNodes . tryAdd ( initializer ) ) {
48- changeTracker . insertNodeBefore ( sourceFile , initializer , createToken ( SyntaxKind . ConstKeyword ) ) ;
49+ changeTracker . insertModifierBefore ( sourceFile , SyntaxKind . ConstKeyword , initializer ) ;
4950 }
5051 }
5152
@@ -61,4 +62,12 @@ namespace ts.codefix {
6162 return false ;
6263 }
6364 }
65+
66+ function arrayElementCouldBeVariableDeclaration ( expression : Expression , checker : TypeChecker ) {
67+ const identifier =
68+ isIdentifier ( expression ) ? expression :
69+ isAssignmentExpression ( expression , /*excludeCompoundAssignment*/ true ) && isIdentifier ( expression . left ) ? expression . left :
70+ undefined ;
71+ return ! ! identifier && ! checker . getSymbolAtLocation ( identifier ) ;
72+ }
6473}
0 commit comments