From a86178d2f7022b792451af55ca1991db17974ffe Mon Sep 17 00:00:00 2001 From: Alexander T Date: Wed, 22 Apr 2020 12:11:59 +0300 Subject: [PATCH] fix(38073): hide 'Extract to function in global scope' action for arrow functions which use 'this' --- src/services/refactors/extractSymbol.ts | 30 +++++++++++------------ tests/cases/fourslash/extract-method32.ts | 14 +++++++++++ tests/cases/fourslash/extract-method33.ts | 14 +++++++++++ 3 files changed, 43 insertions(+), 15 deletions(-) create mode 100644 tests/cases/fourslash/extract-method32.ts create mode 100644 tests/cases/fourslash/extract-method33.ts diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 30dcaeaebfaf6..26e82596ff2cf 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -405,24 +405,24 @@ namespace ts.refactor.extractSymbol { rangeFacts |= RangeFacts.UsesThis; } break; + case SyntaxKind.ClassDeclaration: + case SyntaxKind.FunctionDeclaration: + if (isSourceFile(node.parent) && node.parent.externalModuleIndicator === undefined) { + // You cannot extract global declarations + (errors || (errors = [] as Diagnostic[])).push(createDiagnosticForNode(node, Messages.functionWillNotBeVisibleInTheNewScope)); + } + // falls through + case SyntaxKind.ClassExpression: + case SyntaxKind.FunctionExpression: + case SyntaxKind.MethodDeclaration: + case SyntaxKind.Constructor: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + // do not dive into functions (except arrow functions) or classes + return false; } - if (isFunctionLikeDeclaration(node) || isClassLike(node)) { - switch (node.kind) { - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.ClassDeclaration: - if (isSourceFile(node.parent) && node.parent.externalModuleIndicator === undefined) { - // You cannot extract global declarations - (errors || (errors = [] as Diagnostic[])).push(createDiagnosticForNode(node, Messages.functionWillNotBeVisibleInTheNewScope)); - } - break; - } - - // do not dive into functions or classes - return false; - } const savedPermittedJumps = permittedJumps; - switch (node.kind) { case SyntaxKind.IfStatement: permittedJumps = PermittedJumps.None; diff --git a/tests/cases/fourslash/extract-method32.ts b/tests/cases/fourslash/extract-method32.ts new file mode 100644 index 0000000000000..075f08ec7f9cf --- /dev/null +++ b/tests/cases/fourslash/extract-method32.ts @@ -0,0 +1,14 @@ +/// + +////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"); diff --git a/tests/cases/fourslash/extract-method33.ts b/tests/cases/fourslash/extract-method33.ts new file mode 100644 index 0000000000000..85b51dcd9c0c1 --- /dev/null +++ b/tests/cases/fourslash/extract-method33.ts @@ -0,0 +1,14 @@ +/// + +////function bar(fn: () => void) {} +//// +////class Foo { +//// x: number; +//// foo() { +//// /*start*/bar(() => {});/*end*/ +//// } +////} + +goTo.select("start", "end"); +verify.refactorAvailable("Extract Symbol", "function_scope_1"); +verify.refactorAvailable("Extract Symbol", "function_scope_2");