diff --git a/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts b/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts
index d79a0561bd5..78d2127ac01 100644
--- a/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts
+++ b/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts
@@ -93,16 +93,36 @@ namespace ts.refactor.convertArrowFunctionOrFunctionExpression {
return { renameFilename: undefined, renameLocation: undefined, edits };
}
+ function containingThis(node: Node): boolean {
+ let containsThis = false;
+ node.forEachChild(function checkThis(child) {
+
+ if (isThis(child)) {
+ containsThis = true;
+ return;
+ }
+
+ forEachChild(child, checkThis);
+ });
+
+ return containsThis;
+ }
+
function getFunctionInfo(file: SourceFile, startPosition: number, program: Program): FunctionInfo | undefined {
const token = getTokenAtPosition(file, startPosition);
const arrowFunc = getArrowFunctionFromVariableDeclaration(token.parent);
- if (arrowFunc) return { selectedVariableDeclaration: true, func: arrowFunc };
+ if (arrowFunc && !containingThis(arrowFunc.body)) return { selectedVariableDeclaration: true, func: arrowFunc };
const maybeFunc = getContainingFunction(token);
const typeChecker = program.getTypeChecker();
- if (maybeFunc && (isFunctionExpression(maybeFunc) || isArrowFunction(maybeFunc)) && !rangeContainsRange(maybeFunc.body, token)) {
+ if (
+ maybeFunc &&
+ (isFunctionExpression(maybeFunc) || isArrowFunction(maybeFunc)) &&
+ !rangeContainsRange(maybeFunc.body, token) &&
+ !containingThis(maybeFunc.body)
+ ) {
if ((isFunctionExpression(maybeFunc) && maybeFunc.name && FindAllReferences.Core.isSymbolReferencedInFile(maybeFunc.name, typeChecker, file))) return undefined;
return { selectedVariableDeclaration: false, func: maybeFunc };
}
diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_this.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_this.ts
new file mode 100644
index 00000000000..5ea85798bdd
--- /dev/null
+++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_this.ts
@@ -0,0 +1,9 @@
+///
+
+//// const bar = 42;
+//// const foo = /*x*/f/*w*/unction() {return this.bar;};
+
+goTo.select("x", "w");
+verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function");
+verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function");
+verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function");
diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow_this.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow_this.ts
new file mode 100644
index 00000000000..d1905c48f35
--- /dev/null
+++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow_this.ts
@@ -0,0 +1,9 @@
+///
+
+//// const bar = 42;
+//// const foo = /*x*/(/*w*/) => this.bar;
+
+goTo.select("x", "w");
+verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function");
+verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function");
+verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function");
diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_FnArgument.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_FnArgument.ts
index 28ad1354991..c07a741f1ab 100644
--- a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_FnArgument.ts
+++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_FnArgument.ts
@@ -10,6 +10,6 @@ edit.applyRefactor({
actionDescription: "Convert to anonymous function",
newContent: `function doSomething(a){}
doSomething(function() {
- return 1 + 1;
-});`,
+ return 1 + 1;
+ });`,
});
diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_MapArgument.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_MapArgument.ts
index d1919cf5d7c..8d53517d7ea 100644
--- a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_MapArgument.ts
+++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_MapArgument.ts
@@ -8,6 +8,6 @@ edit.applyRefactor({
actionName: "Convert to anonymous function",
actionDescription: "Convert to anonymous function",
newContent: `[9,8,7].map(function(n) {
- return n + 418;
-});`,
+ return n + 418;
+ });`,
});