From fbb6cd57c0ab992c1e2fd579c4a5aed90dcf0a04 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 13 Sep 2017 16:42:55 -0700 Subject: [PATCH] Merge pull request #18448 from amcasey/NestedReturn Only introduce return properties at the top level (cherry picked from commit 288a57c16dbf2b55070ed350d139de618953d9ef) --- src/harness/unittests/extractMethods.ts | 27 +++++++++++ src/services/refactors/extractMethod.ts | 9 +++- .../extractMethod/extractMethod31.ts | 45 ++++++++++++++++++ .../extractMethod/extractMethod32.ts | 46 +++++++++++++++++++ 4 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/extractMethod/extractMethod31.ts create mode 100644 tests/baselines/reference/extractMethod/extractMethod32.ts diff --git a/src/harness/unittests/extractMethods.ts b/src/harness/unittests/extractMethods.ts index 727cad66ed2eb..e7d86331a82df 100644 --- a/src/harness/unittests/extractMethods.ts +++ b/src/harness/unittests/extractMethods.ts @@ -667,6 +667,33 @@ function parseUnaryExpression(operator: string): UnaryExpression { function parsePrimaryExpression(): any { throw "Not implemented"; +}`); + // Return in nested function + testExtractMethod("extractMethod31", + `namespace N { + + export const value = 1; + + () => { + var f: () => number; + [#|f = function (): number { + return value; + }|] + } +}`); + // Return in nested class + testExtractMethod("extractMethod32", + `namespace N { + + export const value = 1; + + () => { + [#|var c = class { + M() { + return value; + } + }|] + } }`); }); diff --git a/src/services/refactors/extractMethod.ts b/src/services/refactors/extractMethod.ts index 6f7fd5447c7f5..ebc13dd26967d 100644 --- a/src/services/refactors/extractMethod.ts +++ b/src/services/refactors/extractMethod.ts @@ -830,6 +830,7 @@ namespace ts.refactor.extractMethod { return { body: createBlock(body.statements, /*multLine*/ true), returnValueProperty: undefined }; } let returnValueProperty: string; + let ignoreReturns = false; const statements = createNodeArray(isBlock(body) ? body.statements.slice(0) : [isStatement(body) ? body : createReturn(body)]); // rewrite body if either there are writes that should be propagated back via return statements or there are substitutions if (writes || substitutions.size) { @@ -852,7 +853,7 @@ namespace ts.refactor.extractMethod { } function visitor(node: Node): VisitResult { - if (node.kind === SyntaxKind.ReturnStatement && writes) { + if (!ignoreReturns && node.kind === SyntaxKind.ReturnStatement && writes) { const assignments: ObjectLiteralElementLike[] = getPropertyAssignmentsForWrites(writes); if ((node).expression) { if (!returnValueProperty) { @@ -868,8 +869,12 @@ namespace ts.refactor.extractMethod { } } else { + const oldIgnoreReturns = ignoreReturns; + ignoreReturns = ignoreReturns || isFunctionLike(node) || isClassLike(node); const substitution = substitutions.get(getNodeId(node).toString()); - return substitution || visitEachChild(node, visitor, nullTransformationContext); + const result = substitution || visitEachChild(node, visitor, nullTransformationContext); + ignoreReturns = oldIgnoreReturns; + return result; } } } diff --git a/tests/baselines/reference/extractMethod/extractMethod31.ts b/tests/baselines/reference/extractMethod/extractMethod31.ts new file mode 100644 index 0000000000000..bc5a0f16d57d7 --- /dev/null +++ b/tests/baselines/reference/extractMethod/extractMethod31.ts @@ -0,0 +1,45 @@ +// ==ORIGINAL== +namespace N { + + export const value = 1; + + () => { + var f: () => number; + f = function (): number { + return value; + } + } +} +// ==SCOPE::namespace 'N'== +namespace N { + + export const value = 1; + + () => { + var f: () => number; + f = /*RENAME*/newFunction(f); + } + + function newFunction(f: () => number) { + f = function(): number { + return value; + }; + return f; + } +} +// ==SCOPE::global scope== +namespace N { + + export const value = 1; + + () => { + var f: () => number; + f = /*RENAME*/newFunction(f); + } +} +function newFunction(f: () => number) { + f = function(): number { + return N.value; + }; + return f; +} diff --git a/tests/baselines/reference/extractMethod/extractMethod32.ts b/tests/baselines/reference/extractMethod/extractMethod32.ts new file mode 100644 index 0000000000000..c28aaf2a5a15a --- /dev/null +++ b/tests/baselines/reference/extractMethod/extractMethod32.ts @@ -0,0 +1,46 @@ +// ==ORIGINAL== +namespace N { + + export const value = 1; + + () => { + var c = class { + M() { + return value; + } + } + } +} +// ==SCOPE::namespace 'N'== +namespace N { + + export const value = 1; + + () => { + /*RENAME*/newFunction(); + } + + function newFunction() { + var c = class { + M() { + return value; + } + }; + } +} +// ==SCOPE::global scope== +namespace N { + + export const value = 1; + + () => { + /*RENAME*/newFunction(); + } +} +function newFunction() { + var c = class { + M() { + return N.value; + } + }; +}