This commit is contained in:
Oliver Joseph Ash
2021-06-10 14:12:33 -07:00
committed by GitHub
parent 7c293c8d46
commit 69cc9ba5e4
23 changed files with 291 additions and 6 deletions
+1 -5
View File
@@ -215,7 +215,6 @@ namespace ts.refactor.extractSymbol {
export const cannotExtractReadonlyPropertyInitializerOutsideConstructor = createMessage("Cannot move initialization of read-only class property outside of the constructor");
export const cannotExtractAmbientBlock = createMessage("Cannot extract code from ambient contexts");
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");
}
@@ -1624,10 +1623,7 @@ namespace ts.refactor.extractSymbol {
usagesPerScope.push({ usages: new Map<string, UsageEntry>(), typeParameterUsages: new Map<string, TypeParameter>(), substitutions: new Map<string, Expression>() });
substitutionsPerScope.push(new Map<string, Expression>());
functionErrorsPerScope.push(
isFunctionLikeDeclaration(scope) && scope.kind !== SyntaxKind.FunctionDeclaration
? [createDiagnosticForNode(scope, Messages.cannotExtractToOtherFunctionLike)]
: []);
functionErrorsPerScope.push([]);
const constantErrors = [];
if (expressionDiagnostic) {
@@ -352,6 +352,11 @@ function parsePrimaryExpression(): any {
`function F() {
[#|function G() { }|]
}`);
// Arrow function
testExtractFunction("extractFunction34",
`const F = () => {
[#|function G() { }|]
};`);
testExtractFunction("extractFunction_RepeatedSubstitution",
`namespace X {
@@ -9,6 +9,21 @@ namespace A {
}
}
}
// ==SCOPE::Extract to inner function in method 'a'==
namespace A {
export interface I { x: number };
class C {
a() {
let z = 1;
return /*RENAME*/newFunction();
function newFunction() {
let a1: I = { x: 1 };
return a1.x + 10;
}
}
}
}
// ==SCOPE::Extract to method in class 'C'==
namespace A {
export interface I { x: number };
@@ -11,6 +11,23 @@ namespace A {
}
}
}
// ==SCOPE::Extract to inner function in method 'a'==
namespace A {
let y = 1;
class C {
a() {
let z = 1;
return /*RENAME*/newFunction();
function newFunction() {
let a1 = { x: 1 };
y = 10;
z = 42;
return a1.x + 10;
}
}
}
}
// ==SCOPE::Extract to method in class 'C'==
namespace A {
let y = 1;
@@ -13,6 +13,25 @@ namespace A {
}
}
}
// ==SCOPE::Extract to inner function in method 'a'==
namespace A {
let y = 1;
class C {
b() {}
a() {
let z = 1;
return /*RENAME*/newFunction();
function newFunction() {
let a1 = { x: 1 };
y = 10;
z = 42;
this.b();
return a1.x + 10;
}
}
}
}
// ==SCOPE::Extract to method in class 'C'==
namespace A {
let y = 1;
@@ -14,6 +14,26 @@
}
}
}
// ==SCOPE::Extract to inner function in arrow function==
<U1a, U1b>(u1a: U1a, u1b: U1b) => {
function F1<T1a, T1b>(t1a: T1a, t1b: T1b) {
<U2a, U2b>(u2a: U2a, u2b: U2b) => {
function F2<T2a, T2b>(t2a: T2a, t2b: T2b) {
<U3a, U3b>(u3a: U3a, u3b: U3b) => {
/*RENAME*/newFunction();
function newFunction() {
t1a.toString();
t2a.toString();
u1a.toString();
u2a.toString();
u3a.toString();
}
}
}
}
}
}
// ==SCOPE::Extract to inner function in function 'F2'==
<U1a, U1b>(u1a: U1a, u1b: U1b) => {
function F1<T1a, T1b>(t1a: T1a, t1b: T1b) {
@@ -4,6 +4,16 @@ class C<T1, T2> {
/*[#|*/t1.toString()/*|]*/;
}
}
// ==SCOPE::Extract to inner function in method 'M'==
class C<T1, T2> {
M(t1: T1, t2: T2) {
/*RENAME*/newFunction();
function newFunction() {
t1.toString();
}
}
}
// ==SCOPE::Extract to method in class 'C'==
class C<T1, T2> {
M(t1: T1, t2: T2) {
@@ -4,6 +4,16 @@ class C {
/*[#|*/t1.toString()/*|]*/;
}
}
// ==SCOPE::Extract to inner function in method 'M'==
class C {
M<T1, T2>(t1: T1, t2: T2) {
/*RENAME*/newFunction();
function newFunction() {
t1.toString();
}
}
}
// ==SCOPE::Extract to method in class 'C'==
class C {
M<T1, T2>(t1: T1, t2: T2) {
@@ -5,6 +5,17 @@ const _ = class {
return a1.x + 10;/*|]*/
}
}
// ==SCOPE::Extract to inner function in method 'a'==
const _ = class {
a() {
return /*RENAME*/newFunction();
function newFunction() {
let a1 = { x: 1 };
return a1.x + 10;
}
}
}
// ==SCOPE::Extract to method in anonymous class expression==
const _ = class {
a() {
@@ -5,6 +5,17 @@ const _ = class {
return a1.x + 10;/*|]*/
}
}
// ==SCOPE::Extract to inner function in method 'a'==
const _ = class {
a() {
return /*RENAME*/newFunction();
function newFunction() {
let a1 = { x: 1 };
return a1.x + 10;
}
}
}
// ==SCOPE::Extract to method in anonymous class expression==
const _ = class {
a() {
@@ -6,6 +6,18 @@ class C {
}
M3() { }
}
// ==SCOPE::Extract to inner function in method 'M2'==
class C {
M1() { }
M2() {
return /*RENAME*/newFunction();
function newFunction() {
return 1;
}
}
M3() { }
}
// ==SCOPE::Extract to method in class 'C'==
class C {
M1() { }
@@ -6,6 +6,18 @@ class C {
}
M3() { }
}
// ==SCOPE::Extract to inner function in method 'M2'==
class C {
M1() { }
M2() {
return /*RENAME*/newFunction();
function newFunction() {
return 1;
}
}
M3() { }
}
// ==SCOPE::Extract to method in class 'C'==
class C {
M1() { }
@@ -7,6 +7,19 @@ class C {
constructor() { }
M3() { }
}
// ==SCOPE::Extract to inner function in method 'M2'==
class C {
M1() { }
M2() {
return /*RENAME*/newFunction();
function newFunction() {
return 1;
}
}
constructor() { }
M3() { }
}
// ==SCOPE::Extract to method in class 'C'==
class C {
M1() { }
@@ -7,6 +7,19 @@ class C {
constructor() { }
M3() { }
}
// ==SCOPE::Extract to inner function in method 'M2'==
class C {
M1() { }
M2() {
return /*RENAME*/newFunction();
function newFunction() {
return 1;
}
}
constructor() { }
M3() { }
}
// ==SCOPE::Extract to method in class 'C'==
class C {
M1() { }
@@ -7,6 +7,19 @@ class C {
M3() { }
constructor() { }
}
// ==SCOPE::Extract to inner function in method 'M2'==
class C {
M1() { }
M2() {
return /*RENAME*/newFunction();
function newFunction() {
return 1;
}
}
M3() { }
constructor() { }
}
// ==SCOPE::Extract to method in class 'C'==
class C {
M1() { }
@@ -7,6 +7,19 @@ class C {
M3() { }
constructor() { }
}
// ==SCOPE::Extract to inner function in method 'M2'==
class C {
M1() { }
M2() {
return /*RENAME*/newFunction();
function newFunction() {
return 1;
}
}
M3() { }
constructor() { }
}
// ==SCOPE::Extract to method in class 'C'==
class C {
M1() { }
@@ -10,6 +10,22 @@ namespace N {
}/*|]*/
}
}
// ==SCOPE::Extract to inner function in arrow function==
namespace N {
export const value = 1;
() => {
var f: () => number;
/*RENAME*/newFunction();
function newFunction() {
f = function(): number {
return value;
};
}
}
}
// ==SCOPE::Extract to function in namespace 'N'==
namespace N {
@@ -11,6 +11,23 @@ namespace N {
}/*|]*/
}
}
// ==SCOPE::Extract to inner function in arrow function==
namespace N {
export const value = 1;
() => {
var c = /*RENAME*/newFunction()
function newFunction() {
return class {
M() {
return value;
}
};
}
}
}
// ==SCOPE::Extract to function in namespace 'N'==
namespace N {
@@ -0,0 +1,20 @@
// ==ORIGINAL==
const F = () => {
/*[#|*/function G() { }/*|]*/
};
// ==SCOPE::Extract to inner function in arrow function==
const F = () => {
/*RENAME*/newFunction();
function newFunction() {
function G() { }
}
};
// ==SCOPE::Extract to function in global scope==
const F = () => {
/*RENAME*/newFunction();
};
function newFunction() {
function G() { }
}
@@ -0,0 +1,20 @@
// ==ORIGINAL==
const F = () => {
/*[#|*/function G() { }/*|]*/
};
// ==SCOPE::Extract to inner function in arrow function==
const F = () => {
/*RENAME*/newFunction();
function newFunction() {
function G() { }
}
};
// ==SCOPE::Extract to function in global scope==
const F = () => {
/*RENAME*/newFunction();
};
function newFunction() {
function G() { }
}
@@ -5,6 +5,17 @@ export default class {
/*[#|*/1 + 1/*|]*/;
}
}
// ==SCOPE::Extract to inner function in method 'M'==
export default class {
M() {
/*RENAME*/newFunction();
function newFunction() {
1 + 1;
}
}
}
// ==SCOPE::Extract to method in anonymous class declaration==
export default class {
@@ -5,6 +5,17 @@ export default class {
/*[#|*/1 + 1/*|]*/;
}
}
// ==SCOPE::Extract to inner function in method 'M'==
export default class {
M() {
/*RENAME*/newFunction();
function newFunction() {
1 + 1;
}
}
}
// ==SCOPE::Extract to method in anonymous class declaration==
export default class {
+1 -1
View File
@@ -10,6 +10,6 @@
//// }
goTo.select('a', 'b')
verify.not.refactorAvailable('Extract Symbol', 'function_scope_0');
verify.refactorAvailable('Extract Symbol', 'function_scope_0');
verify.refactorAvailable('Extract Symbol', 'function_scope_1');
verify.not.refactorAvailable('Extract Symbol', 'function_scope_2');