From f273448925f5dd40136df414ecdc7fad56614d96 Mon Sep 17 00:00:00 2001 From: Florian Regensburger Date: Wed, 10 Jul 2019 02:11:02 +0200 Subject: [PATCH] Added addMissingConst codefix for comma separated initializers --- src/services/codefixes/addMissingConst.ts | 38 ++++++++++++++++++- ...issingConstToCommaSeparatedInitializer1.ts | 9 +++++ ...issingConstToCommaSeparatedInitializer2.ts | 11 ++++++ ...issingConstToCommaSeparatedInitializer3.ts | 15 ++++++++ ...ssingConstToCommaSeparatedInitializer4.ts} | 1 + 5 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/codeFixAddMissingConstToCommaSeparatedInitializer1.ts create mode 100644 tests/cases/fourslash/codeFixAddMissingConstToCommaSeparatedInitializer2.ts create mode 100644 tests/cases/fourslash/codeFixAddMissingConstToCommaSeparatedInitializer3.ts rename tests/cases/fourslash/{codeFixAddMissingConstToStandaloneIdentifier2.ts => codeFixAddMissingConstToCommaSeparatedInitializer4.ts} (80%) diff --git a/src/services/codefixes/addMissingConst.ts b/src/services/codefixes/addMissingConst.ts index fa353cc5b83..10dba5d9444 100644 --- a/src/services/codefixes/addMissingConst.ts +++ b/src/services/codefixes/addMissingConst.ts @@ -42,6 +42,19 @@ namespace ts.codefix { return applyChange(changeTracker, parent, sourceFile, fixedNodes); } + + const commaExpression = findAncestor(token, node => + isExpressionStatement(node.parent) ? true : + isPossiblyPartOfCommaSeperatedInitializer(node) ? false : "quit" + ); + if (commaExpression) { + const checker = program.getTypeChecker(); + if (!expressionCouldBeVariableDeclaration(commaExpression, checker)) { + return; + } + + return applyChange(changeTracker, commaExpression, sourceFile, fixedNodes); + } } function applyChange(changeTracker: textChanges.ChangeTracker, initializer: Node, sourceFile: SourceFile, fixedNodes?: NodeSet) { @@ -63,11 +76,34 @@ namespace ts.codefix { } } - function arrayElementCouldBeVariableDeclaration(expression: Expression, checker: TypeChecker) { + function arrayElementCouldBeVariableDeclaration(expression: Expression, checker: TypeChecker): boolean { const identifier = isIdentifier(expression) ? expression : isAssignmentExpression(expression, /*excludeCompoundAssignment*/ true) && isIdentifier(expression.left) ? expression.left : undefined; return !!identifier && !checker.getSymbolAtLocation(identifier); } + + function isPossiblyPartOfCommaSeperatedInitializer(node: Node): boolean { + switch (node.kind) { + case SyntaxKind.Identifier: + case SyntaxKind.BinaryExpression: + case SyntaxKind.CommaToken: + return true; + default: + return false; + } + } + + function expressionCouldBeVariableDeclaration(expression: Node, checker: TypeChecker): boolean { + if (!isBinaryExpression(expression)) { + return false; + } + + if (expression.operatorToken.kind === SyntaxKind.CommaToken) { + return every([expression.left, expression.right], expression => expressionCouldBeVariableDeclaration(expression, checker)); + } + + return isIdentifier(expression.left) && !checker.getSymbolAtLocation(expression.left); + } } diff --git a/tests/cases/fourslash/codeFixAddMissingConstToCommaSeparatedInitializer1.ts b/tests/cases/fourslash/codeFixAddMissingConstToCommaSeparatedInitializer1.ts new file mode 100644 index 00000000000..c5bb309698d --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingConstToCommaSeparatedInitializer1.ts @@ -0,0 +1,9 @@ +/// + +////x = 0, y = 0; + +verify.codeFixAll({ + fixId: "addMissingConst", + fixAllDescription: "Add 'const' to all unresolved variables", + newFileContent: "const x = 0, y = 0;" +}); diff --git a/tests/cases/fourslash/codeFixAddMissingConstToCommaSeparatedInitializer2.ts b/tests/cases/fourslash/codeFixAddMissingConstToCommaSeparatedInitializer2.ts new file mode 100644 index 00000000000..1a60b16489d --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingConstToCommaSeparatedInitializer2.ts @@ -0,0 +1,11 @@ +/// + +////x = 0, +////y = 0; + +verify.codeFixAll({ + fixId: "addMissingConst", + fixAllDescription: "Add 'const' to all unresolved variables", + newFileContent: `const x = 0, +y = 0;` +}); diff --git a/tests/cases/fourslash/codeFixAddMissingConstToCommaSeparatedInitializer3.ts b/tests/cases/fourslash/codeFixAddMissingConstToCommaSeparatedInitializer3.ts new file mode 100644 index 00000000000..d39388af335 --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingConstToCommaSeparatedInitializer3.ts @@ -0,0 +1,15 @@ +/// + +////function f() { return 42; } +////x = 0, y = f() +//// +////, z = 0; + +verify.codeFixAll({ + fixId: "addMissingConst", + fixAllDescription: "Add 'const' to all unresolved variables", + newFileContent: `function f() { return 42; } +const x = 0, y = f() + +, z = 0;` +}); diff --git a/tests/cases/fourslash/codeFixAddMissingConstToStandaloneIdentifier2.ts b/tests/cases/fourslash/codeFixAddMissingConstToCommaSeparatedInitializer4.ts similarity index 80% rename from tests/cases/fourslash/codeFixAddMissingConstToStandaloneIdentifier2.ts rename to tests/cases/fourslash/codeFixAddMissingConstToCommaSeparatedInitializer4.ts index aa08f4e9196..263ed33231a 100644 --- a/tests/cases/fourslash/codeFixAddMissingConstToStandaloneIdentifier2.ts +++ b/tests/cases/fourslash/codeFixAddMissingConstToCommaSeparatedInitializer4.ts @@ -1,5 +1,6 @@ /// +////let y: any; ////x = 0, y = 0; verify.not.codeFixAvailable();