do not provide refactoring when it contains this

because this behaves differently in arrow than in function
This commit is contained in:
BigAru
2019-01-22 05:42:01 +01:00
parent 52e94d2b80
commit dbd58599f4
5 changed files with 44 additions and 6 deletions
@@ -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 };
}
@@ -0,0 +1,9 @@
/// <reference path='fourslash.ts' />
//// 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");
@@ -0,0 +1,9 @@
/// <reference path='fourslash.ts' />
//// 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");
@@ -10,6 +10,6 @@ edit.applyRefactor({
actionDescription: "Convert to anonymous function",
newContent: `function doSomething(a){}
doSomething(function() {
return 1 + 1;
});`,
return 1 + 1;
});`,
});
@@ -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;
});`,
});