diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 8c6c8f6fc698b..be51d89ed6df9 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -405,6 +405,20 @@ namespace ts.refactor.extractSymbol { rangeFacts |= RangeFacts.UsesThis; } break; + case SyntaxKind.ArrowFunction: + // check if arrow function uses this + forEachChild(node, function check(n) { + if (isThis(n)) { + rangeFacts |= RangeFacts.UsesThis; + } + else if (isClassLike(n) || (isFunctionLike(n) && !isArrowFunction(n))) { + return false; + } + else { + forEachChild(n, check); + } + }); + // falls through case SyntaxKind.ClassDeclaration: case SyntaxKind.FunctionDeclaration: if (isSourceFile(node.parent) && node.parent.externalModuleIndicator === undefined) { @@ -418,7 +432,7 @@ namespace ts.refactor.extractSymbol { case SyntaxKind.Constructor: case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: - // do not dive into functions (except arrow functions) or classes + // do not dive into functions or classes return false; } diff --git a/tests/cases/fourslash/extract-method40.ts b/tests/cases/fourslash/extract-method40.ts new file mode 100644 index 0000000000000..e59c56fe352c3 --- /dev/null +++ b/tests/cases/fourslash/extract-method40.ts @@ -0,0 +1,23 @@ +/// + +////const foo = /*start*/{ +//// a: 1, +//// b: () => { return 1; } +////}/*end*/ + +goTo.select("start", "end"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "function_scope_0", + actionDescription: "Extract to function in global scope", + newContent: +`const foo = /*RENAME*/newFunction() + +function newFunction() { + return { + a: 1, + b: () => { return 1; } + }; +} +` +}); diff --git a/tests/cases/fourslash/extract-method41.ts b/tests/cases/fourslash/extract-method41.ts new file mode 100644 index 0000000000000..d90ee90eeacaf --- /dev/null +++ b/tests/cases/fourslash/extract-method41.ts @@ -0,0 +1,20 @@ +/// + +////function bar(fn: () => void) {} +//// +////class Foo { +//// x: number; +//// foo() { +//// /*start*/bar(() => { +//// () => { +//// () => { +//// this.x; +//// } +//// } +//// });/*end*/ +//// } +////} + +goTo.select("start", "end"); +verify.refactorAvailable("Extract Symbol", "function_scope_1"); +verify.not.refactorAvailable("Extract Symbol", "function_scope_2");