From 2cb965c2681f5fa2f5452e4675756d0e37233d44 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Tue, 3 Oct 2017 13:34:17 -0700 Subject: [PATCH] Disallow constant extraction into expression-bodied arrow functions ...until https://github.com/Microsoft/TypeScript/issues/18924 is fixed. --- src/harness/unittests/extractConstants.ts | 8 ++++++++ src/services/refactors/extractSymbol.ts | 5 +++++ .../extractConstant_ArrowFunction_Block.js | 18 ++++++++++++++++++ .../extractConstant_ArrowFunction_Block.ts | 18 ++++++++++++++++++ ...extractConstant_ArrowFunction_Expression.js | 6 ++++++ ...extractConstant_ArrowFunction_Expression.ts | 6 ++++++ 6 files changed, 61 insertions(+) create mode 100644 tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Block.js create mode 100644 tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Block.ts create mode 100644 tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Expression.js create mode 100644 tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Expression.ts diff --git a/src/harness/unittests/extractConstants.ts b/src/harness/unittests/extractConstants.ts index 63a150856f5..314790537e3 100644 --- a/src/harness/unittests/extractConstants.ts +++ b/src/harness/unittests/extractConstants.ts @@ -214,6 +214,14 @@ const x = [#|2 + 1|]; /* About x */ const x = [#|2 + 1|]; `); + + testExtractConstant("extractConstant_ArrowFunction_Block", ` +const f = () => { + return [#|2 + 1|]; +};`); + + testExtractConstant("extractConstant_ArrowFunction_Expression", + `const f = () => [#|2 + 1|];`); }); function testExtractConstant(caption: string, text: string) { diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 9e2ca3da4f7..4f722be5edd 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -142,6 +142,7 @@ namespace ts.refactor.extractSymbol { export const CannotAccessVariablesFromNestedScopes = createMessage("Cannot access variables from nested scopes"); export const CannotExtractToOtherFunctionLike = createMessage("Cannot extract method to a function-like scope that is not a function"); export const CannotExtractToJSClass = createMessage("Cannot extract constant to a class scope in JS"); + export const CannotExtractToExpressionArrowFunction = createMessage("Cannot extract constant to an arrow function without a block"); } enum RangeFacts { @@ -1299,6 +1300,10 @@ namespace ts.refactor.extractSymbol { if (isClassLike(scope) && isInJavaScriptFile(scope)) { constantErrors.push(createDiagnosticForNode(scope, Messages.CannotExtractToJSClass)); } + if (isArrowFunction(scope) && !isBlock(scope.body)) { + // TODO (https://github.com/Microsoft/TypeScript/issues/18924): allow this + constantErrors.push(createDiagnosticForNode(scope, Messages.CannotExtractToExpressionArrowFunction)); + } constantErrorsPerScope.push(constantErrors); } diff --git a/tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Block.js b/tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Block.js new file mode 100644 index 00000000000..06dbf2b1751 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Block.js @@ -0,0 +1,18 @@ +// ==ORIGINAL== + +const f = () => { + return 2 + 1; +}; +// ==SCOPE::Extract to constant in enclosing scope== + +const f = () => { + const newLocal = 2 + 1; + + return /*RENAME*/newLocal; +}; +// ==SCOPE::Extract to constant in global scope== +const newLocal = 2 + 1; + +const f = () => { + return /*RENAME*/newLocal; +}; \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Block.ts b/tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Block.ts new file mode 100644 index 00000000000..06dbf2b1751 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Block.ts @@ -0,0 +1,18 @@ +// ==ORIGINAL== + +const f = () => { + return 2 + 1; +}; +// ==SCOPE::Extract to constant in enclosing scope== + +const f = () => { + const newLocal = 2 + 1; + + return /*RENAME*/newLocal; +}; +// ==SCOPE::Extract to constant in global scope== +const newLocal = 2 + 1; + +const f = () => { + return /*RENAME*/newLocal; +}; \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Expression.js b/tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Expression.js new file mode 100644 index 00000000000..d04cdcd3280 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Expression.js @@ -0,0 +1,6 @@ +// ==ORIGINAL== +const f = () => 2 + 1; +// ==SCOPE::Extract to constant in global scope== +const newLocal = 2 + 1; + +const f = () => /*RENAME*/newLocal; \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Expression.ts b/tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Expression.ts new file mode 100644 index 00000000000..d04cdcd3280 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Expression.ts @@ -0,0 +1,6 @@ +// ==ORIGINAL== +const f = () => 2 + 1; +// ==SCOPE::Extract to constant in global scope== +const newLocal = 2 + 1; + +const f = () => /*RENAME*/newLocal; \ No newline at end of file