diff --git a/src/services/codefixes/addMissingConstInForLoop.ts b/src/services/codefixes/addMissingConst.ts similarity index 55% rename from src/services/codefixes/addMissingConstInForLoop.ts rename to src/services/codefixes/addMissingConst.ts index 9110fb31a10..857d7fb4282 100644 --- a/src/services/codefixes/addMissingConstInForLoop.ts +++ b/src/services/codefixes/addMissingConst.ts @@ -1,6 +1,6 @@ /* @internal */ namespace ts.codefix { - const fixId = "addMissingConstInForLoop"; + const fixId = "addMissingConst"; const errorCodes = [ Diagnostics.Cannot_find_name_0.code, Diagnostics.No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer.code @@ -22,12 +22,30 @@ namespace ts.codefix { }); function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number, fixedNodes?: NodeSet) { - const forInitializer = findAncestor(getTokenAtPosition(sourceFile, pos), node => + const token = getTokenAtPosition(sourceFile, pos); + + const forInitializer = findAncestor(token, node => isForInOrOfStatement(node.parent) ? node.parent.initializer === node : isPossiblyPartOfDestructuring(node) ? false : "quit"); - if (!forInitializer) return; - if (!fixedNodes || fixedNodes.tryAdd(forInitializer)) { - changeTracker.insertNodeBefore(sourceFile, forInitializer, createToken(SyntaxKind.ConstKeyword)); + if (forInitializer) return applyChange(changeTracker, forInitializer, sourceFile, fixedNodes); + + const parent = token.parent; + const standaloneInitializer = isExpressionStatement(parent.parent); + if (standaloneInitializer) return applyChange(changeTracker, parent, sourceFile, fixedNodes); + + const arrayLiteralInitializer = isArrayLiteralExpression(token.parent); + if (arrayLiteralInitializer) { + const availableIdentifiers: string[] = []; // TODO: where to get/gather this information from? + const noIdentifiersDeclared = parent.forEachChild(node => availableIdentifiers.indexOf(node.getFullText()) < 0); + if (!noIdentifiersDeclared) return; + + return applyChange(changeTracker, parent, sourceFile, fixedNodes); + } + } + + function applyChange(changeTracker: textChanges.ChangeTracker, initializer: Node, sourceFile: SourceFile, fixedNodes?: NodeSet) { + if (!fixedNodes || fixedNodes.tryAdd(initializer)) { + changeTracker.insertNodeBefore(sourceFile, initializer, createToken(SyntaxKind.ConstKeyword)); } } diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index b48f27cf1c6..5e6de0f15ca 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -45,7 +45,7 @@ "codeFixProvider.ts", "refactorProvider.ts", "codefixes/addConvertToUnknownForNonOverlappingTypes.ts", - "codefixes/addMissingConstInForLoop.ts", + "codefixes/addMissingConst.ts", "codefixes/addMissingInvocationForDecorator.ts", "codefixes/addNameToNamelessParameter.ts", "codefixes/annotateWithTypeFromJSDoc.ts", diff --git a/tests/cases/fourslash/codeFixAddMissingConstInForInLoop2.ts b/tests/cases/fourslash/codeFixAddMissingConstInForInLoop2.ts index d101f384044..03fb12f5d7e 100644 --- a/tests/cases/fourslash/codeFixAddMissingConstInForInLoop2.ts +++ b/tests/cases/fourslash/codeFixAddMissingConstInForInLoop2.ts @@ -4,7 +4,7 @@ ////for (y in []) {} verify.codeFixAll({ - fixId: "addMissingConstInForLoop", + fixId: "addMissingConst", fixAllDescription: "Add 'const' to all unresolved variables", newFileContent: `for (const x in []) {} diff --git a/tests/cases/fourslash/codeFixAddMissingConstInForLoopWithArrayDestructuring2.ts b/tests/cases/fourslash/codeFixAddMissingConstInForLoopWithArrayDestructuring2.ts index 734b53ed4fb..c0f8b733aec 100644 --- a/tests/cases/fourslash/codeFixAddMissingConstInForLoopWithArrayDestructuring2.ts +++ b/tests/cases/fourslash/codeFixAddMissingConstInForLoopWithArrayDestructuring2.ts @@ -4,7 +4,7 @@ ////for ([x] of [[1,2]]) {} verify.codeFixAll({ - fixId: "addMissingConstInForLoop", + fixId: "addMissingConst", fixAllDescription: "Add 'const' to all unresolved variables", newFileContent: `for (const [x, y] of [[1,2]]) {} diff --git a/tests/cases/fourslash/codeFixAddMissingConstInForLoopWithObjectDestructuring2.ts b/tests/cases/fourslash/codeFixAddMissingConstInForLoopWithObjectDestructuring2.ts index 82cd2db6dc2..aa8ec294972 100644 --- a/tests/cases/fourslash/codeFixAddMissingConstInForLoopWithObjectDestructuring2.ts +++ b/tests/cases/fourslash/codeFixAddMissingConstInForLoopWithObjectDestructuring2.ts @@ -4,7 +4,7 @@ ////for ({ x } of [{ x: 0 }]) { } verify.codeFixAll({ - fixId: "addMissingConstInForLoop", + fixId: "addMissingConst", fixAllDescription: "Add 'const' to all unresolved variables", newFileContent: `for (const { x, y } of [{ x: 0, y: 1 }]) { } diff --git a/tests/cases/fourslash/codeFixAddMissingConstInForOfLoop2.ts b/tests/cases/fourslash/codeFixAddMissingConstInForOfLoop2.ts index 3dbab65de32..24f8b48dfc9 100644 --- a/tests/cases/fourslash/codeFixAddMissingConstInForOfLoop2.ts +++ b/tests/cases/fourslash/codeFixAddMissingConstInForOfLoop2.ts @@ -4,7 +4,7 @@ ////for (y of []) {} verify.codeFixAll({ - fixId: "addMissingConstInForLoop", + fixId: "addMissingConst", fixAllDescription: "Add 'const' to all unresolved variables", newFileContent: `for (const x of []) {} diff --git a/tests/cases/fourslash/codeFixAddMissingConstToArrayDestructuring1.ts b/tests/cases/fourslash/codeFixAddMissingConstToArrayDestructuring1.ts new file mode 100644 index 00000000000..8e40466c3ba --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingConstToArrayDestructuring1.ts @@ -0,0 +1,8 @@ +/// + +////[x] = [0]; + +verify.codeFix({ + description: "Add 'const' to unresolved variable", + newFileContent: "const [x] = [0];" +}); diff --git a/tests/cases/fourslash/codeFixAddMissingConstToArrayDestructuring2.ts b/tests/cases/fourslash/codeFixAddMissingConstToArrayDestructuring2.ts new file mode 100644 index 00000000000..57a89076cb2 --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingConstToArrayDestructuring2.ts @@ -0,0 +1,9 @@ +/// + +////[x, y] = [0, 1]; + +verify.codeFixAll({ + fixId: "addMissingConst", + fixAllDescription: "Add 'const' to all unresolved variables", + newFileContent: "const [x, y] = [0, 1];" +}); diff --git a/tests/cases/fourslash/codeFixAddMissingConstToArrayDestructuring3.ts b/tests/cases/fourslash/codeFixAddMissingConstToArrayDestructuring3.ts new file mode 100644 index 00000000000..4099e1fe473 --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingConstToArrayDestructuring3.ts @@ -0,0 +1,6 @@ +/// + +////let x: any; +////[x, y] = [0, 1]; + +verify.not.codeFixAvailable(); diff --git a/tests/cases/fourslash/codeFixAddMissingConstToStandaloneIdentifier1.ts b/tests/cases/fourslash/codeFixAddMissingConstToStandaloneIdentifier1.ts new file mode 100644 index 00000000000..0a603dced30 --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingConstToStandaloneIdentifier1.ts @@ -0,0 +1,8 @@ +/// + +////x = 0; + +verify.codeFix({ + description: "Add 'const' to unresolved variable", + newFileContent: "const x = 0;" +}); diff --git a/tests/cases/fourslash/codeFixAddMissingConstToStandaloneIdentifier2.ts b/tests/cases/fourslash/codeFixAddMissingConstToStandaloneIdentifier2.ts new file mode 100644 index 00000000000..aa08f4e9196 --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingConstToStandaloneIdentifier2.ts @@ -0,0 +1,5 @@ +/// + +////x = 0, y = 0; + +verify.not.codeFixAvailable();