From 7b1147fbcefbd67fb0a790e6ac54a7e93c94d8f8 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Tue, 3 Oct 2017 12:23:32 -0700 Subject: [PATCH] Stop inadvertently exempting expression statements from check --- src/harness/unittests/extractConstants.ts | 7 +++++++ src/services/refactors/extractSymbol.ts | 15 +++++++-------- ...ctConstant_ExpressionStatementConsumesLocal.js | 14 ++++++++++++++ ...ctConstant_ExpressionStatementConsumesLocal.ts | 14 ++++++++++++++ 4 files changed, 42 insertions(+), 8 deletions(-) create mode 100644 tests/baselines/reference/extractConstant/extractConstant_ExpressionStatementConsumesLocal.js create mode 100644 tests/baselines/reference/extractConstant/extractConstant_ExpressionStatementConsumesLocal.ts diff --git a/src/harness/unittests/extractConstants.ts b/src/harness/unittests/extractConstants.ts index b58016cd56f..63a150856f5 100644 --- a/src/harness/unittests/extractConstants.ts +++ b/src/harness/unittests/extractConstants.ts @@ -40,6 +40,13 @@ function F() { } `); + testExtractConstant("extractConstant_ExpressionStatementConsumesLocal", ` +function F() { + let i = 0; + [#|i++|]; +} + `); + testExtractConstant("extractConstant_BlockScopes_NoDependencies", `for (let i = 0; i < 10; i++) { for (let j = 0; j < 10; j++) { diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index a7646f6234e..9e2ca3da4f7 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -1351,14 +1351,13 @@ namespace ts.refactor.extractSymbol { } for (let i = 0; i < scopes.length; i++) { - if (!isReadonlyArray(targetRange.range)) { - const scopeUsages = usagesPerScope[i]; - // Special case: in the innermost scope, all usages are available. - // (The computed value reflects the value at the top-level of the scope, but the - // local will actually be declared at the same level as the extracted expression). - if (i > 0 && (scopeUsages.usages.size > 0 || scopeUsages.typeParameterUsages.size > 0)) { - constantErrorsPerScope[i].push(createDiagnosticForNode(targetRange.range, Messages.CannotAccessVariablesFromNestedScopes)); - } + const scopeUsages = usagesPerScope[i]; + // Special case: in the innermost scope, all usages are available. + // (The computed value reflects the value at the top-level of the scope, but the + // local will actually be declared at the same level as the extracted expression). + if (i > 0 && (scopeUsages.usages.size > 0 || scopeUsages.typeParameterUsages.size > 0)) { + const errorNode = isReadonlyArray(targetRange.range) ? targetRange.range[0] : targetRange.range; + constantErrorsPerScope[i].push(createDiagnosticForNode(errorNode, Messages.CannotAccessVariablesFromNestedScopes)); } let hasWrite = false; diff --git a/tests/baselines/reference/extractConstant/extractConstant_ExpressionStatementConsumesLocal.js b/tests/baselines/reference/extractConstant/extractConstant_ExpressionStatementConsumesLocal.js new file mode 100644 index 00000000000..b57da0d8e8c --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_ExpressionStatementConsumesLocal.js @@ -0,0 +1,14 @@ +// ==ORIGINAL== + +function F() { + let i = 0; + i++; +} + +// ==SCOPE::Extract to constant in enclosing scope== + +function F() { + let i = 0; + const /*RENAME*/newLocal = i++; +} + \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_ExpressionStatementConsumesLocal.ts b/tests/baselines/reference/extractConstant/extractConstant_ExpressionStatementConsumesLocal.ts new file mode 100644 index 00000000000..b57da0d8e8c --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_ExpressionStatementConsumesLocal.ts @@ -0,0 +1,14 @@ +// ==ORIGINAL== + +function F() { + let i = 0; + i++; +} + +// ==SCOPE::Extract to constant in enclosing scope== + +function F() { + let i = 0; + const /*RENAME*/newLocal = i++; +} + \ No newline at end of file