Skip to content

Commit 288a57c

Browse files
authored
Merge pull request #18448 from amcasey/NestedReturn
Only introduce return properties at the top level
2 parents 7b64229 + e2d94a2 commit 288a57c

File tree

4 files changed

+125
-2
lines changed

4 files changed

+125
-2
lines changed

src/harness/unittests/extractMethods.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,33 @@ function parsePrimaryExpression(): any {
733733
testExtractMethod("extractMethod30",
734734
`function F<T>() {
735735
[#|let t: T;|]
736+
}`);
737+
// Return in nested function
738+
testExtractMethod("extractMethod31",
739+
`namespace N {
740+
741+
export const value = 1;
742+
743+
() => {
744+
var f: () => number;
745+
[#|f = function (): number {
746+
return value;
747+
}|]
748+
}
749+
}`);
750+
// Return in nested class
751+
testExtractMethod("extractMethod32",
752+
`namespace N {
753+
754+
export const value = 1;
755+
756+
() => {
757+
[#|var c = class {
758+
M() {
759+
return value;
760+
}
761+
}|]
762+
}
736763
}`);
737764
});
738765

src/services/refactors/extractMethod.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,7 @@ namespace ts.refactor.extractMethod {
855855
return { body: createBlock(body.statements, /*multLine*/ true), returnValueProperty: undefined };
856856
}
857857
let returnValueProperty: string;
858+
let ignoreReturns = false;
858859
const statements = createNodeArray(isBlock(body) ? body.statements.slice(0) : [isStatement(body) ? body : createReturn(<Expression>body)]);
859860
// rewrite body if either there are writes that should be propagated back via return statements or there are substitutions
860861
if (writes || substitutions.size) {
@@ -877,7 +878,7 @@ namespace ts.refactor.extractMethod {
877878
}
878879

879880
function visitor(node: Node): VisitResult<Node> {
880-
if (node.kind === SyntaxKind.ReturnStatement && writes) {
881+
if (!ignoreReturns && node.kind === SyntaxKind.ReturnStatement && writes) {
881882
const assignments: ObjectLiteralElementLike[] = getPropertyAssignmentsForWrites(writes);
882883
if ((<ReturnStatement>node).expression) {
883884
if (!returnValueProperty) {
@@ -893,8 +894,12 @@ namespace ts.refactor.extractMethod {
893894
}
894895
}
895896
else {
897+
const oldIgnoreReturns = ignoreReturns;
898+
ignoreReturns = ignoreReturns || isFunctionLike(node) || isClassLike(node);
896899
const substitution = substitutions.get(getNodeId(node).toString());
897-
return substitution || visitEachChild(node, visitor, nullTransformationContext);
900+
const result = substitution || visitEachChild(node, visitor, nullTransformationContext);
901+
ignoreReturns = oldIgnoreReturns;
902+
return result;
898903
}
899904
}
900905
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// ==ORIGINAL==
2+
namespace N {
3+
4+
export const value = 1;
5+
6+
() => {
7+
var f: () => number;
8+
f = function (): number {
9+
return value;
10+
}
11+
}
12+
}
13+
// ==SCOPE::function in namespace 'N'==
14+
namespace N {
15+
16+
export const value = 1;
17+
18+
() => {
19+
var f: () => number;
20+
f = /*RENAME*/newFunction(f);
21+
}
22+
23+
function newFunction(f: () => number) {
24+
f = function(): number {
25+
return value;
26+
};
27+
return f;
28+
}
29+
}
30+
// ==SCOPE::function in global scope==
31+
namespace N {
32+
33+
export const value = 1;
34+
35+
() => {
36+
var f: () => number;
37+
f = /*RENAME*/newFunction(f);
38+
}
39+
}
40+
function newFunction(f: () => number) {
41+
f = function(): number {
42+
return N.value;
43+
};
44+
return f;
45+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// ==ORIGINAL==
2+
namespace N {
3+
4+
export const value = 1;
5+
6+
() => {
7+
var c = class {
8+
M() {
9+
return value;
10+
}
11+
}
12+
}
13+
}
14+
// ==SCOPE::function in namespace 'N'==
15+
namespace N {
16+
17+
export const value = 1;
18+
19+
() => {
20+
/*RENAME*/newFunction();
21+
}
22+
23+
function newFunction() {
24+
var c = class {
25+
M() {
26+
return value;
27+
}
28+
};
29+
}
30+
}
31+
// ==SCOPE::function in global scope==
32+
namespace N {
33+
34+
export const value = 1;
35+
36+
() => {
37+
/*RENAME*/newFunction();
38+
}
39+
}
40+
function newFunction() {
41+
var c = class {
42+
M() {
43+
return N.value;
44+
}
45+
};
46+
}

0 commit comments

Comments
 (0)