diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 6660b29fd65..b5cb450bfec 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -4281,7 +4281,7 @@ "category": "Message", "code": 95054 }, - "Convert arrow function": { + "Add or remove braces in an arrow function": { "category": "Message", "code": 95055 }, diff --git a/src/harness/tsconfig.json b/src/harness/tsconfig.json index 4749520822e..22b7f496704 100644 --- a/src/harness/tsconfig.json +++ b/src/harness/tsconfig.json @@ -121,7 +121,7 @@ "../services/refactors/extractSymbol.ts", "../services/refactors/generateGetAccessorAndSetAccessor.ts", "../services/refactors/moveToNewFile.ts", - "../services/refactors/convertArrowFunction.ts", + "../services/refactors/addOrRemoveBracesToArrowFunction.ts", "../services/sourcemaps.ts", "../services/services.ts", "../services/breakpoints.ts", diff --git a/src/server/tsconfig.json b/src/server/tsconfig.json index 7d81e068648..6c5144093ae 100644 --- a/src/server/tsconfig.json +++ b/src/server/tsconfig.json @@ -117,7 +117,7 @@ "../services/refactors/extractSymbol.ts", "../services/refactors/generateGetAccessorAndSetAccessor.ts", "../services/refactors/moveToNewFile.ts", - "../services/refactors/convertArrowFunction.ts", + "../services/refactors/addOrRemoveBracesToArrowFunction.ts", "../services/sourcemaps.ts", "../services/services.ts", "../services/breakpoints.ts", diff --git a/src/server/tsconfig.library.json b/src/server/tsconfig.library.json index df72b37e530..59ff8cc9e83 100644 --- a/src/server/tsconfig.library.json +++ b/src/server/tsconfig.library.json @@ -123,7 +123,7 @@ "../services/refactors/extractSymbol.ts", "../services/refactors/generateGetAccessorAndSetAccessor.ts", "../services/refactors/moveToNewFile.ts", - "../services/refactors/convertArrowFunction.ts", + "../services/refactors/addOrRemoveBracesToArrowFunction.ts", "../services/sourcemaps.ts", "../services/services.ts", "../services/breakpoints.ts", diff --git a/src/services/refactors/convertArrowFunction.ts b/src/services/refactors/addOrRemoveBracesToArrowFunction.ts similarity index 53% rename from src/services/refactors/convertArrowFunction.ts rename to src/services/refactors/addOrRemoveBracesToArrowFunction.ts index af1d232ad3e..df7cacadf3f 100644 --- a/src/services/refactors/convertArrowFunction.ts +++ b/src/services/refactors/addOrRemoveBracesToArrowFunction.ts @@ -1,7 +1,7 @@ /* @internal */ -namespace ts.refactor.convertArrowFunction { - const refactorName = "Convert arrow function"; - const refactorDescription = Diagnostics.Convert_arrow_function.message; +namespace ts.refactor.addOrRemoveBracesToArrowFunction { + const refactorName = "Add or remove braces in an arrow function"; + const refactorDescription = Diagnostics.Add_or_remove_braces_in_an_arrow_function.message; const addBracesActionName = "Add braces to arrow function"; const removeBracesActionName = "Remove braces from arrow function"; const addBracesActionDescription = Diagnostics.Add_braces_to_arrow_function.message; @@ -19,21 +19,19 @@ namespace ts.refactor.convertArrowFunction { const info = getConvertibleArrowFunctionAtPosition(file, startPosition); if (!info) return undefined; - const actions: RefactorActionInfo[] = [ - info.addBraces ? - { - name: addBracesActionName, - description: addBracesActionDescription - } : { - name: removeBracesActionName, - description: removeBracesActionDescription - } - ]; - return [{ name: refactorName, description: refactorDescription, - actions + actions: [ + info.addBraces ? + { + name: addBracesActionName, + description: addBracesActionDescription + } : { + name: removeBracesActionName, + description: removeBracesActionDescription + } + ] }]; } @@ -42,9 +40,18 @@ namespace ts.refactor.convertArrowFunction { const info = getConvertibleArrowFunctionAtPosition(file, startPosition); if (!info) return undefined; - const { addBraces, expression, container } = info; + const { expression, container } = info; const changeTracker = textChanges.ChangeTracker.fromContext(context); - updateBraces(changeTracker, file, container, expression, addBraces); + + if (_actionName === addBracesActionName) { + addBraces(changeTracker, file, container, expression); + } + else if (_actionName === removeBracesActionName) { + removeBraces(changeTracker, file, container, expression); + } + else { + Debug.fail("invalid action"); + } return { renameFilename: undefined, @@ -53,9 +60,18 @@ namespace ts.refactor.convertArrowFunction { }; } - function updateBraces(changeTracker: textChanges.ChangeTracker, file: SourceFile, container: ArrowFunction, expression: Expression, addBraces: boolean) { - const body = addBraces ? createBlock([createReturn(expression)]) : expression; + function addBraces(changeTracker: textChanges.ChangeTracker, file: SourceFile, container: ArrowFunction, expression: Expression) { + updateBraces(changeTracker, file, container, createBlock([createReturn(expression)])); + } + function removeBraces(changeTracker: textChanges.ChangeTracker, file: SourceFile, container: ArrowFunction, expression: Expression) { + if (!isLiteralExpression(expression) && !isIdentifier(expression) && !isParenthesizedExpression(expression) && expression.kind !== SyntaxKind.NullKeyword) { + expression = createParen(expression); + } + updateBraces(changeTracker, file, container, expression); + } + + function updateBraces(changeTracker: textChanges.ChangeTracker, file: SourceFile, container: ArrowFunction, body: ConciseBody) { const arrowFunction = updateArrowFunction( container, container.modifiers, @@ -78,12 +94,15 @@ namespace ts.refactor.convertArrowFunction { expression: container.body }; } - else if (container.body.statements.length === 1 && isReturnStatement(first(container.body.statements))) { - return { - container, - addBraces: false, - expression: (first(container.body.statements)).expression - }; + else if (container.body.statements.length === 1) { + const firstStatement = first(container.body.statements); + if (isReturnStatement(firstStatement)) { + return { + container, + addBraces: false, + expression: firstStatement.expression + }; + } } return undefined; } diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index f425c569e31..4d94facef35 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -114,7 +114,7 @@ "refactors/extractSymbol.ts", "refactors/generateGetAccessorAndSetAccessor.ts", "refactors/moveToNewFile.ts", - "refactors/convertArrowFunction.ts", + "refactors/addOrRemoveBracesToArrowFunction.ts", "sourcemaps.ts", "services.ts", "breakpoints.ts", diff --git a/tests/cases/fourslash/refactorAddBracesToArrowFunction7.ts b/tests/cases/fourslash/refactorAddBracesToArrowFunction7.ts deleted file mode 100644 index 7f7a5207515..00000000000 --- a/tests/cases/fourslash/refactorAddBracesToArrowFunction7.ts +++ /dev/null @@ -1,6 +0,0 @@ -/// - -//// const foo = /*a*/a/*b*/ => { }; - -goTo.select("a", "b"); -verify.not.refactorAvailable("Convert arrow function"); diff --git a/tests/cases/fourslash/refactorAddBracesToArrowFunction1.ts b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction1.ts similarity index 81% rename from tests/cases/fourslash/refactorAddBracesToArrowFunction1.ts rename to tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction1.ts index fde5a54656e..1d8d52e201f 100644 --- a/tests/cases/fourslash/refactorAddBracesToArrowFunction1.ts +++ b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction1.ts @@ -4,7 +4,7 @@ goTo.select("a", "b"); edit.applyRefactor({ - refactorName: "Convert arrow function", + refactorName: "Add or remove braces in an arrow function", actionName: "Add braces to arrow function", actionDescription: "Add braces to arrow function", newContent: `const foo = a => { return a + 1; };`, diff --git a/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction10.ts b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction10.ts new file mode 100644 index 00000000000..373172a2b31 --- /dev/null +++ b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction10.ts @@ -0,0 +1,11 @@ +/// + +//// const foo = /*a*/a/*b*/ => { return (1, 2, 3); }; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Add or remove braces in an arrow function", + actionName: "Remove braces from arrow function", + actionDescription: "Remove braces from arrow function", + newContent: `const foo = a => (1, 2, 3);`, +}); diff --git a/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction11.ts b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction11.ts new file mode 100644 index 00000000000..c634db625cf --- /dev/null +++ b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction11.ts @@ -0,0 +1,11 @@ +/// + +//// const foo = /*a*/a/*b*/ => { return 1, 2, 3; }; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Add or remove braces in an arrow function", + actionName: "Remove braces from arrow function", + actionDescription: "Remove braces from arrow function", + newContent: `const foo = a => (1, 2, 3);`, +}); diff --git a/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction12.ts b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction12.ts new file mode 100644 index 00000000000..aecf37c8b56 --- /dev/null +++ b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction12.ts @@ -0,0 +1,11 @@ +/// + +//// const foo = /*a*/a/*b*/ => { return "foo"; }; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Add or remove braces in an arrow function", + actionName: "Remove braces from arrow function", + actionDescription: "Remove braces from arrow function", + newContent: `const foo = a => "foo";`, +}); diff --git a/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction13.ts b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction13.ts new file mode 100644 index 00000000000..64d1a02db67 --- /dev/null +++ b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction13.ts @@ -0,0 +1,11 @@ +/// + +//// const foo = /*a*/a/*b*/ => { return null; }; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Add or remove braces in an arrow function", + actionName: "Remove braces from arrow function", + actionDescription: "Remove braces from arrow function", + newContent: `const foo = a => null;`, +}); diff --git a/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction14.ts b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction14.ts new file mode 100644 index 00000000000..b15f1cfad31 --- /dev/null +++ b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction14.ts @@ -0,0 +1,11 @@ +/// + +//// const foo = /*a*/a/*b*/ => { return undefined; }; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Add or remove braces in an arrow function", + actionName: "Remove braces from arrow function", + actionDescription: "Remove braces from arrow function", + newContent: `const foo = a => undefined;`, +}); diff --git a/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction15.ts b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction15.ts new file mode 100644 index 00000000000..af2927f8f94 --- /dev/null +++ b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction15.ts @@ -0,0 +1,11 @@ +/// + +//// const foo = /*a*/a/*b*/ => { return void 0; }; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Add or remove braces in an arrow function", + actionName: "Remove braces from arrow function", + actionDescription: "Remove braces from arrow function", + newContent: `const foo = a => (void 0);`, +}); diff --git a/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction16.ts b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction16.ts new file mode 100644 index 00000000000..87bdcfe5752 --- /dev/null +++ b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction16.ts @@ -0,0 +1,11 @@ +/// + +//// const foo = /*a*/a/*b*/ => { return {}; }; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Add or remove braces in an arrow function", + actionName: "Remove braces from arrow function", + actionDescription: "Remove braces from arrow function", + newContent: `const foo = a => ({});`, +}); diff --git a/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction17.ts b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction17.ts new file mode 100644 index 00000000000..e71809ac38f --- /dev/null +++ b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction17.ts @@ -0,0 +1,11 @@ +/// + +//// const foo = /*a*/a/*b*/ => { return `abc{a}`; }; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Add or remove braces in an arrow function", + actionName: "Remove braces from arrow function", + actionDescription: "Remove braces from arrow function", + newContent: `const foo = a => \`abc{a}\`;`, +}); diff --git a/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction18.ts b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction18.ts new file mode 100644 index 00000000000..0e2d85ddd26 --- /dev/null +++ b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction18.ts @@ -0,0 +1,11 @@ +/// + +//// const foo = /*a*/a/*b*/ => { return `abc`; }; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Add or remove braces in an arrow function", + actionName: "Remove braces from arrow function", + actionDescription: "Remove braces from arrow function", + newContent: `const foo = a => \`abc\`;`, +}); diff --git a/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction19.ts b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction19.ts new file mode 100644 index 00000000000..9d56a4d5f66 --- /dev/null +++ b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction19.ts @@ -0,0 +1,11 @@ +/// + +//// const foo = /*a*/a/*b*/ => { return a; }; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Add or remove braces in an arrow function", + actionName: "Remove braces from arrow function", + actionDescription: "Remove braces from arrow function", + newContent: `const foo = a => a;`, +}); diff --git a/tests/cases/fourslash/refactorAddBracesToArrowFunction2.ts b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction2.ts similarity index 82% rename from tests/cases/fourslash/refactorAddBracesToArrowFunction2.ts rename to tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction2.ts index 30f4de0e9a7..d875018c397 100644 --- a/tests/cases/fourslash/refactorAddBracesToArrowFunction2.ts +++ b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction2.ts @@ -4,7 +4,7 @@ goTo.select("a", "b"); edit.applyRefactor({ - refactorName: "Convert arrow function", + refactorName: "Add or remove braces in an arrow function", actionName: "Add braces to arrow function", actionDescription: "Add braces to arrow function", newContent: `const foo = a => { return ({ a: 1 }); };`, diff --git a/tests/cases/fourslash/refactorAddBracesToArrowFunction3.ts b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction3.ts similarity index 81% rename from tests/cases/fourslash/refactorAddBracesToArrowFunction3.ts rename to tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction3.ts index cd2d773449e..ead5867a175 100644 --- a/tests/cases/fourslash/refactorAddBracesToArrowFunction3.ts +++ b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction3.ts @@ -4,7 +4,7 @@ goTo.select("a", "b"); edit.applyRefactor({ - refactorName: "Convert arrow function", + refactorName: "Add or remove braces in an arrow function", actionName: "Add braces to arrow function", actionDescription: "Add braces to arrow function", newContent: `const foo = a => { return 1; };`, diff --git a/tests/cases/fourslash/refactorAddBracesToArrowFunction4.ts b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction4.ts similarity index 70% rename from tests/cases/fourslash/refactorAddBracesToArrowFunction4.ts rename to tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction4.ts index f113d63add4..a2147af1d47 100644 --- a/tests/cases/fourslash/refactorAddBracesToArrowFunction4.ts +++ b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction4.ts @@ -4,8 +4,8 @@ goTo.select("a", "b"); edit.applyRefactor({ - refactorName: "Convert arrow function", + refactorName: "Add or remove braces in an arrow function", actionName: "Remove braces from arrow function", actionDescription: "Remove braces from arrow function", - newContent: `const foo = a => a + 1;`, + newContent: `const foo = a => (a + 1);`, }); diff --git a/tests/cases/fourslash/refactorAddBracesToArrowFunction5.ts b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction5.ts similarity index 82% rename from tests/cases/fourslash/refactorAddBracesToArrowFunction5.ts rename to tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction5.ts index bc0cdfd6484..355f3a8f331 100644 --- a/tests/cases/fourslash/refactorAddBracesToArrowFunction5.ts +++ b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction5.ts @@ -4,7 +4,7 @@ goTo.select("a", "b"); edit.applyRefactor({ - refactorName: "Convert arrow function", + refactorName: "Add or remove braces in an arrow function", actionName: "Remove braces from arrow function", actionDescription: "Remove braces from arrow function", newContent: `const foo = a => ({ a: 1 });`, diff --git a/tests/cases/fourslash/refactorAddBracesToArrowFunction6.ts b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction6.ts similarity index 82% rename from tests/cases/fourslash/refactorAddBracesToArrowFunction6.ts rename to tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction6.ts index 999fba05193..31f865b4394 100644 --- a/tests/cases/fourslash/refactorAddBracesToArrowFunction6.ts +++ b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction6.ts @@ -4,7 +4,7 @@ goTo.select("a", "b"); edit.applyRefactor({ - refactorName: "Convert arrow function", + refactorName: "Add or remove braces in an arrow function", actionName: "Remove braces from arrow function", actionDescription: "Remove braces from arrow function", newContent: `const foo = a => 1;`, diff --git a/tests/cases/fourslash/refactorAddBracesToArrowFunction8.ts b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction8.ts similarity index 66% rename from tests/cases/fourslash/refactorAddBracesToArrowFunction8.ts rename to tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction8.ts index 1c7f0bd954b..a2ec70e1e82 100644 --- a/tests/cases/fourslash/refactorAddBracesToArrowFunction8.ts +++ b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction8.ts @@ -6,4 +6,4 @@ //// }; goTo.select("a", "b"); -verify.not.refactorAvailable("Convert arrow function"); +verify.not.refactorAvailable("Add or remove braces in an arrow function"); diff --git a/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction9.ts b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction9.ts new file mode 100644 index 00000000000..610e19cff45 --- /dev/null +++ b/tests/cases/fourslash/refactorAddOrRemoveBracesToArrowFunction9.ts @@ -0,0 +1,11 @@ +/// + +//// const foo = /*a*/a/*b*/ => (1, 2, 3); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Add or remove braces in an arrow function", + actionName: "Add braces to arrow function", + actionDescription: "Add braces to arrow function", + newContent: `const foo = a => { return (1, 2, 3); };`, +});