fix(40469): suggest QF convert 'Convert to named function' to function expressions (#40476)

This commit is contained in:
Oleksandr T 2020-11-05 20:25:24 +02:00 committed by GitHub
parent 98aaeb7f48
commit 899e2d00e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 20 deletions

View File

@ -112,20 +112,20 @@ namespace ts.refactor.convertArrowFunctionOrFunctionExpression {
function getFunctionInfo(file: SourceFile, startPosition: number, program: Program): FunctionInfo | undefined {
const token = getTokenAtPosition(file, startPosition);
const arrowFunc = getArrowFunctionFromVariableDeclaration(token.parent);
if (arrowFunc && !containingThis(arrowFunc.body)) return { selectedVariableDeclaration: true, func: arrowFunc };
const typeChecker = program.getTypeChecker();
const func = tryGetFunctionFromVariableDeclaration(file, typeChecker, token.parent);
if (func && !containingThis(func.body)) {
return { selectedVariableDeclaration: true, func };
}
const maybeFunc = getContainingFunction(token);
const typeChecker = program.getTypeChecker();
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;
if (isFunctionExpression(maybeFunc) && isFunctionReferencedInFile(file, typeChecker, maybeFunc)) return undefined;
return { selectedVariableDeclaration: false, func: maybeFunc };
}
@ -136,13 +136,16 @@ namespace ts.refactor.convertArrowFunctionOrFunctionExpression {
return isVariableDeclaration(parent) || (isVariableDeclarationList(parent) && parent.declarations.length === 1);
}
function getArrowFunctionFromVariableDeclaration(parent: Node): ArrowFunction | undefined {
if (!isSingleVariableDeclaration(parent)) return undefined;
const variableDeclaration = isVariableDeclaration(parent) ? parent : parent.declarations[0];
function tryGetFunctionFromVariableDeclaration(sourceFile: SourceFile, typeChecker: TypeChecker, parent: Node): ArrowFunction | FunctionExpression | undefined {
if (!isSingleVariableDeclaration(parent)) {
return undefined;
}
const variableDeclaration = isVariableDeclaration(parent) ? parent : first(parent.declarations);
const initializer = variableDeclaration.initializer;
if (!initializer || !isArrowFunction(initializer)) return undefined;
return initializer;
if (initializer && (isArrowFunction(initializer) || isFunctionExpression(initializer) && !isFunctionReferencedInFile(sourceFile, typeChecker, initializer))) {
return initializer;
}
return undefined;
}
function convertToBlock(body: ConciseBody): Block {
@ -213,4 +216,8 @@ namespace ts.refactor.convertArrowFunctionOrFunctionExpression {
function canBeConvertedToExpression(body: Block, head: Statement): head is ReturnStatement {
return body.statements.length === 1 && ((isReturnStatement(head) && !!head.expression));
}
function isFunctionReferencedInFile(sourceFile: SourceFile, typeChecker: TypeChecker, node: FunctionExpression): boolean {
return !!node.name && FindAllReferences.Core.isSymbolReferencedInFile(node.name, typeChecker, sourceFile);
}
}

View File

@ -3,14 +3,14 @@
//// /*z*/c/*y*/onst /*x*/f/*w*/oo = /*v*/f/*u*/unction() /*t*/{/*s*/ /*r*/r/*q*/eturn 42;};
goTo.select("z", "y");
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");
verify.refactorAvailable("Convert arrow function or function expression", "Convert to named function");
verify.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function");
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");
verify.refactorAvailable("Convert arrow function or function expression", "Convert to named function");
verify.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function");
goTo.select("v", "u");
verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function");

View File

@ -3,14 +3,14 @@
//// /*z*/c/*y*/onst /*x*/f/*w*/oo = /*v*/f/*u*/unction bar() /*t*/{/*s*/ /*r*/r/*q*/eturn 42;};
goTo.select("z", "y");
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");
verify.refactorAvailable("Convert arrow function or function expression", "Convert to named function");
verify.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function");
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");
verify.refactorAvailable("Convert arrow function or function expression", "Convert to named function");
verify.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function");
goTo.select("v", "u");
verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function");