Skip to content

Commit 5a53e9b

Browse files
authored
fix(49838): "Extract function" refactoring action is disabled for a wrong reason (#49840)
* fix(49838): allow extracting functions with a break statement inside loop context * remove useless flag * add more tests
1 parent 298b3a4 commit 5a53e9b

File tree

5 files changed

+205
-1
lines changed

5 files changed

+205
-1
lines changed

src/services/refactors/extractSymbol.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ namespace ts.refactor.extractSymbol {
551551
const savedPermittedJumps = permittedJumps;
552552
switch (node.kind) {
553553
case SyntaxKind.IfStatement:
554-
permittedJumps = PermittedJumps.None;
554+
permittedJumps &= ~PermittedJumps.Return;
555555
break;
556556
case SyntaxKind.TryStatement:
557557
// forbid all jumps inside try blocks
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
////export function fn(m: number) {
4+
//// const mode = m >= 0 ? "a" : "b";
5+
//// let result: number = 0;
6+
////
7+
//// if (mode === "a") {
8+
//// /*a*/for (let i = 0; i < 10; i++) {
9+
//// const rand = Math.random();
10+
//// if (rand > 0.5) {
11+
//// result = rand;
12+
//// break;
13+
//// }
14+
//// }/*b*/
15+
//// }
16+
//// else {
17+
//// result = 0;
18+
//// }
19+
////
20+
//// return result;
21+
////}
22+
23+
goTo.select("a", "b");
24+
edit.applyRefactor({
25+
refactorName: "Extract Symbol",
26+
actionName: "function_scope_1",
27+
actionDescription: "Extract to function in module scope",
28+
newContent:
29+
`export function fn(m: number) {
30+
const mode = m >= 0 ? "a" : "b";
31+
let result: number = 0;
32+
33+
if (mode === "a") {
34+
result = /*RENAME*/newFunction(result);
35+
}
36+
else {
37+
result = 0;
38+
}
39+
40+
return result;
41+
}
42+
43+
function newFunction(result: number) {
44+
for (let i = 0; i < 10; i++) {
45+
const rand = Math.random();
46+
if (rand > 0.5) {
47+
result = rand;
48+
break;
49+
}
50+
}
51+
return result;
52+
}
53+
`
54+
});
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
////export function fn(m: number, n: number) {
4+
//// const mode = m >= 0 ? "a" : "b";
5+
//// let result: number = 0;
6+
////
7+
//// if (mode === "a") {
8+
//// /*a*/for (let i = 0; i < n; i++) {
9+
//// const rand = Math.random();
10+
//// if (rand > 0.5) {
11+
//// result = rand;
12+
//// break;
13+
//// }
14+
//// }/*b*/
15+
//// }
16+
//// else {
17+
//// result = 0;
18+
//// }
19+
////
20+
//// return result;
21+
////}
22+
23+
goTo.select("a", "b");
24+
edit.applyRefactor({
25+
refactorName: "Extract Symbol",
26+
actionName: "function_scope_1",
27+
actionDescription: "Extract to function in module scope",
28+
newContent:
29+
`export function fn(m: number, n: number) {
30+
const mode = m >= 0 ? "a" : "b";
31+
let result: number = 0;
32+
33+
if (mode === "a") {
34+
result = /*RENAME*/newFunction(n, result);
35+
}
36+
else {
37+
result = 0;
38+
}
39+
40+
return result;
41+
}
42+
43+
function newFunction(n: number, result: number) {
44+
for (let i = 0; i < n; i++) {
45+
const rand = Math.random();
46+
if (rand > 0.5) {
47+
result = rand;
48+
break;
49+
}
50+
}
51+
return result;
52+
}
53+
`
54+
});
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
////export function fn(m: number, n: number) {
4+
//// const mode = m >= 0 ? "a" : "b";
5+
//// let result: number = 0;
6+
////
7+
//// if (mode === "a") {
8+
//// /*a*/for (let i = 0; i < n; i++) {
9+
//// const rand = Math.random();
10+
//// switch (rand) {
11+
//// case 0.5:
12+
//// result = rand;
13+
//// break;
14+
//// default:
15+
//// result = 1;
16+
//// break;
17+
//// }
18+
//// }/*b*/
19+
//// }
20+
//// else {
21+
//// result = 0;
22+
//// }
23+
//// return result;
24+
////}
25+
26+
goTo.select("a", "b");
27+
edit.applyRefactor({
28+
refactorName: "Extract Symbol",
29+
actionName: "function_scope_1",
30+
actionDescription: "Extract to function in module scope",
31+
newContent:
32+
`export function fn(m: number, n: number) {
33+
const mode = m >= 0 ? "a" : "b";
34+
let result: number = 0;
35+
36+
if (mode === "a") {
37+
result = /*RENAME*/newFunction(n, result);
38+
}
39+
else {
40+
result = 0;
41+
}
42+
return result;
43+
}
44+
45+
function newFunction(n: number, result: number) {
46+
for (let i = 0; i < n; i++) {
47+
const rand = Math.random();
48+
switch (rand) {
49+
case 0.5:
50+
result = rand;
51+
break;
52+
default:
53+
result = 1;
54+
break;
55+
}
56+
}
57+
return result;
58+
}
59+
`
60+
});
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
////export function fn(x: number, y: number) {
4+
//// /*a*/switch (x) {
5+
//// case 1:
6+
//// if (y) {
7+
//// break;
8+
//// }
9+
//// x--;
10+
//// break;
11+
//// }/*b*/
12+
////}
13+
14+
goTo.select("a", "b");
15+
edit.applyRefactor({
16+
refactorName: "Extract Symbol",
17+
actionName: "function_scope_1",
18+
actionDescription: "Extract to function in module scope",
19+
newContent:
20+
`export function fn(x: number, y: number) {
21+
x = /*RENAME*/newFunction(x, y);
22+
}
23+
24+
function newFunction(x: number, y: number) {
25+
switch (x) {
26+
case 1:
27+
if (y) {
28+
break;
29+
}
30+
x--;
31+
break;
32+
}
33+
return x;
34+
}
35+
`
36+
});

0 commit comments

Comments
 (0)