add support to convert lambda to function and vice-versa (#28250)

* add skeleton

* add getAvailableActions

* add working getEditsForAction

* add multi vardecl

* fix multi decl bug

* change refactor name

* add tests for ToAnon, ToArrow and available arrow

* add tests for ToNamed and available anon

* add tests for ReturnType and available Arrow as FnParam

* fix bug modifiers by toNamed

* add tests for modifiers

* fix for tslint error

* adapt one test case

* refactor getInfo getAvailableActions

* refactor small progress

* extract creation of block

* extract creation of funcDeclaration

* make guideline compliant

* apply feedback from pr

* add testcase and apply feedback from pr

* apply feedback from pr

* add newline

* rename testcases

* Make conditions more expressive

* fix for unnecessary duplication of comment

* apply feedback from pr

* update getAvailableActions

* check if functionExpression name is used

* add more testcases

* do not provide refactoring when it contains this
because this behaves differently in arrow than in function

* exclude nested functions and classes at containingThis check

* fix linting error

* fix line endings

Co-authored-by: BigAru <arooran@indikon.ch>
Co-authored-by: bigaru <bigaru@users.noreply.github.com>
Co-authored-by: Jesse Trinity <42591254+jessetrinity@users.noreply.github.com>
Co-authored-by: Jesse Trinity <jetrinit@microsoft.com>
This commit is contained in:
Jesse Trinity 2020-06-01 15:26:45 -07:00 committed by GitHub
commit 1d1c1673bf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
47 changed files with 1010 additions and 0 deletions

View file

@ -5717,6 +5717,22 @@
"category": "Message",
"code": 95121
},
"Convert arrow function or function expression": {
"category": "Message",
"code": 95122
},
"Convert to anonymous function": {
"category": "Message",
"code": 95123
},
"Convert to named function": {
"category": "Message",
"code": 95124
},
"Convert to arrow function": {
"category": "Message",
"code": 95125
},
"No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer.": {
"category": "Error",

View file

@ -0,0 +1,216 @@
/* @internal */
namespace ts.refactor.convertArrowFunctionOrFunctionExpression {
const refactorName = "Convert arrow function or function expression";
const refactorDescription = getLocaleSpecificMessage(Diagnostics.Convert_arrow_function_or_function_expression);
const toAnonymousFunctionActionName = "Convert to anonymous function";
const toNamedFunctionActionName = "Convert to named function";
const toArrowFunctionActionName = "Convert to arrow function";
const toAnonymousFunctionActionDescription = getLocaleSpecificMessage(Diagnostics.Convert_to_anonymous_function);
const toNamedFunctionActionDescription = getLocaleSpecificMessage(Diagnostics.Convert_to_named_function);
const toArrowFunctionActionDescription = getLocaleSpecificMessage(Diagnostics.Convert_to_arrow_function);
registerRefactor(refactorName, { getEditsForAction, getAvailableActions });
interface FunctionInfo {
readonly selectedVariableDeclaration: boolean;
readonly func: FunctionExpression | ArrowFunction;
}
interface VariableInfo {
readonly variableDeclaration: VariableDeclaration;
readonly variableDeclarationList: VariableDeclarationList;
readonly statement: VariableStatement;
readonly name: Identifier;
}
function getAvailableActions(context: RefactorContext): readonly ApplicableRefactorInfo[] {
const { file, startPosition, program } = context;
const info = getFunctionInfo(file, startPosition, program);
if (!info) return emptyArray;
const { selectedVariableDeclaration, func } = info;
const possibleActions: RefactorActionInfo[] = [];
if (selectedVariableDeclaration || (isArrowFunction(func) && isVariableDeclaration(func.parent))) {
possibleActions.push({
name: toNamedFunctionActionName,
description: toNamedFunctionActionDescription
});
}
if (!selectedVariableDeclaration && isArrowFunction(func)) {
possibleActions.push({
name: toAnonymousFunctionActionName,
description: toAnonymousFunctionActionDescription
});
}
if (isFunctionExpression(func)) {
possibleActions.push({
name: toArrowFunctionActionName,
description: toArrowFunctionActionDescription
});
}
return [{
name: refactorName,
description: refactorDescription,
actions: possibleActions
}];
}
function getEditsForAction(context: RefactorContext, actionName: string): RefactorEditInfo | undefined {
const { file, startPosition, program } = context;
const info = getFunctionInfo(file, startPosition, program);
if (!info) return undefined;
const { func } = info;
const edits: FileTextChanges[] = [];
switch (actionName) {
case toAnonymousFunctionActionName:
edits.push(...getEditInfoForConvertToAnonymousFunction(context, func));
break;
case toNamedFunctionActionName:
const variableInfo = getVariableInfo(func);
if (!variableInfo) return undefined;
edits.push(...getEditInfoForConvertToNamedFunction(context, func, variableInfo));
break;
case toArrowFunctionActionName:
if (!isFunctionExpression(func)) return undefined;
edits.push(...getEditInfoForConvertToArrowFunction(context, func));
break;
default:
return Debug.fail("invalid action");
}
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;
}
if (!isClassLike(child) && !isFunctionDeclaration(child) && !isFunctionExpression(child)) {
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 && !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) &&
!containingThis(maybeFunc.body)
) {
if ((isFunctionExpression(maybeFunc) && maybeFunc.name && FindAllReferences.Core.isSymbolReferencedInFile(maybeFunc.name, typeChecker, file))) return undefined;
return { selectedVariableDeclaration: false, func: maybeFunc };
}
return undefined;
}
function isSingleVariableDeclaration(parent: Node): parent is VariableDeclarationList {
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];
const initializer = variableDeclaration.initializer;
if (!initializer || !isArrowFunction(initializer)) return undefined;
return initializer;
}
function convertToBlock(body: ConciseBody): Block {
if (isExpression(body)) {
return createBlock([createReturn(body)], /* multiLine */ true);
}
else {
return body;
}
}
function getVariableInfo(func: FunctionExpression | ArrowFunction): VariableInfo | undefined {
const variableDeclaration = func.parent;
if (!isVariableDeclaration(variableDeclaration) || !isVariableDeclarationInVariableStatement(variableDeclaration)) return undefined;
const variableDeclarationList = variableDeclaration.parent;
const statement = variableDeclarationList.parent;
if (!isVariableDeclarationList(variableDeclarationList) || !isVariableStatement(statement) || !isIdentifier(variableDeclaration.name)) return undefined;
return { variableDeclaration, variableDeclarationList, statement, name: variableDeclaration.name };
}
function getEditInfoForConvertToAnonymousFunction(context: RefactorContext, func: FunctionExpression | ArrowFunction): FileTextChanges[] {
const { file } = context;
const body = convertToBlock(func.body);
const newNode = createFunctionExpression(func.modifiers, func.asteriskToken, /* name */ undefined, func.typeParameters, func.parameters, func.type, body);
return textChanges.ChangeTracker.with(context, t => t.replaceNode(file, func, newNode));
}
function getEditInfoForConvertToNamedFunction(context: RefactorContext, func: FunctionExpression | ArrowFunction, variableInfo: VariableInfo): FileTextChanges[] {
const { file } = context;
const body = convertToBlock(func.body);
const { variableDeclaration, variableDeclarationList, statement, name } = variableInfo;
suppressLeadingTrivia(statement);
const newNode = createFunctionDeclaration(func.decorators, statement.modifiers, func.asteriskToken, name, func.typeParameters, func.parameters, func.type, body);
if (variableDeclarationList.declarations.length === 1) {
return textChanges.ChangeTracker.with(context, t => t.replaceNode(file, statement, newNode));
}
else {
return textChanges.ChangeTracker.with(context, t => {
t.delete(file, variableDeclaration);
t.insertNodeAfter(file, statement, newNode);
});
}
}
function getEditInfoForConvertToArrowFunction(context: RefactorContext, func: FunctionExpression): FileTextChanges[] {
const { file } = context;
const statements = func.body.statements;
const head = statements[0];
let body: ConciseBody;
if (canBeConvertedToExpression(func.body, head)) {
body = head.expression!;
suppressLeadingAndTrailingTrivia(body);
copyComments(head, body);
}
else {
body = func.body;
}
const newNode = createArrowFunction(func.modifiers, func.typeParameters, func.parameters, func.type, createToken(SyntaxKind.EqualsGreaterThanToken), body);
return textChanges.ChangeTracker.with(context, t => t.replaceNode(file, func, newNode));
}
function canBeConvertedToExpression(body: Block, head: Statement): head is ReturnStatement {
return body.statements.length === 1 && ((isReturnStatement(head) && !!head.expression));
}
}

View file

@ -113,6 +113,7 @@
"refactors/addOrRemoveBracesToArrowFunction.ts",
"refactors/convertParamsToDestructuredObject.ts",
"refactors/convertStringOrTemplateLiteral.ts",
"refactors/convertArrowFunctionOrFunctionExpression.ts",
"services.ts",
"breakpoints.ts",
"transform.ts",

View file

@ -0,0 +1,28 @@
/// <reference path='fourslash.ts' />
//// /*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");
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");
goTo.select("v", "u");
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.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function");
goTo.select("t", "s");
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");
goTo.select("r", "q");
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");

View file

@ -0,0 +1,34 @@
/// <reference path='fourslash.ts' />
//// function foo(a){}
//// /*z*/f/*y*/oo/*x*/(/*w*//*v*/f/*u*/unction/*t*/(/*s*//*r*/b/*q*/,c){/*p*/r/*o*/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");
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");
goTo.select("v", "u");
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.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function");
goTo.select("t", "s");
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.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function");
goTo.select("r", "q");
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.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function");
goTo.select("p", "o");
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");

View file

@ -0,0 +1,19 @@
/// <reference path='fourslash.ts' />
//// const zoo = /*x*/f/*w*/unction () {
//// class Animal {
//// weight = 42
//// askWeight() { return this.weight }
//// }
//// const Insect = class {
//// weight = 42
//// askWeight() { return this.weight }
//// }
//// function callTaxi() { this.no = "054 xxx xx xx" }
//// const callPizzaDelivery = function() { this.phone = "064 yyy yy yy"}
//// };
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.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function");

View file

@ -0,0 +1,11 @@
/// <reference path='fourslash.ts' />
//// const foo = /*x*/f/*w*/unction() {
//// this.bar = "F-Express";
//// 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");

View file

@ -0,0 +1,28 @@
/// <reference path='fourslash.ts' />
//// /*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");
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");
goTo.select("v", "u");
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.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function");
goTo.select("t", "s");
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");
goTo.select("r", "q");
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");

View file

@ -0,0 +1,28 @@
/// <reference path='fourslash.ts' />
//// /*z*/c/*y*/onst /*x*/f/*w*/oo = /*v*/f/*u*/unction isEven(n) /*t*/{/*s*/ /*r*/r/*q*/eturn n === 0 ? true : n === 1 ? false : isEven(n - 2);};
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");
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");
goTo.select("v", "u");
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");
goTo.select("t", "s");
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");
goTo.select("r", "q");
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");

View file

@ -0,0 +1,33 @@
/// <reference path='fourslash.ts' />
//// /*z*/c/*y*/onst /*x*/f/*w*/oo = /*v*/(/*u*//*t*/a/*s*/, b) /*r*/=/*q*/> /*p*/4/*o*/2;
goTo.select("z", "y");
verify.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");
goTo.select("x", "w");
verify.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");
goTo.select("v", "u");
verify.refactorAvailable("Convert arrow function or function expression", "Convert to named function");
verify.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function");
verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function");
goTo.select("t", "s");
verify.refactorAvailable("Convert arrow function or function expression", "Convert to named function");
verify.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function");
verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function");
goTo.select("r", "q");
verify.refactorAvailable("Convert arrow function or function expression", "Convert to named function");
verify.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function");
verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function");
goTo.select("p", "o");
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");

View file

@ -0,0 +1,30 @@
/// <reference path='fourslash.ts' />
//// function foo(a){}
//// /*z*/f/*y*/oo/*x*/(/*w*//*v*/(/*u*//*t*/a/*s*/, b) => /*r*/a/*q*/ + b)
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");
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");
goTo.select("v", "u");
verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function");
verify.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function");
verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function");
goTo.select("t", "s");
verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to named function");
verify.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function");
verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function");
goTo.select("r", "q");
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");

View file

@ -0,0 +1,23 @@
/// <reference path='fourslash.ts' />
//// /*z*/l/*y*/et /*x*/f/*w*/oo, /*v*/b/*u*/ar = /*t*/(/*s*/) => 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");
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");
goTo.select("v", "u");
verify.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");
goTo.select("t", "s");
verify.refactorAvailable("Convert arrow function or function expression", "Convert to named function");
verify.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function");
verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function");

View file

@ -0,0 +1,19 @@
/// <reference path='fourslash.ts' />
//// const zoo = /*x*/(/*w*/) => {
//// class Animal {
//// weight = 42
//// askWeight() { return this.weight }
//// }
//// const Insect = class {
//// weight = 42
//// askWeight() { return this.weight }
//// }
//// function callTaxi() { this.no = "054 xxx xx xx" }
//// const callPizzaDelivery = function() { this.phone = "064 yyy yy yy"}
//// };
goTo.select("x", "w");
verify.refactorAvailable("Convert arrow function or function expression", "Convert to named function");
verify.refactorAvailable("Convert arrow function or function expression", "Convert to anonymous function");
verify.not.refactorAvailable("Convert arrow function or function expression", "Convert to arrow function");

View file

@ -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");

View file

@ -0,0 +1,23 @@
/// <reference path='fourslash.ts' />
//// const foo = /*x*/a/*y*/ => {
//// // secret word
//// return a + 1;
//// /*
//// hidden msg
//// */
//// };
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to anonymous function",
actionDescription: "Convert to anonymous function",
newContent: `const foo = function(a) {
// secret word
return a + 1;
/*
hidden msg
*/
};`,
});

View file

@ -0,0 +1,15 @@
/// <reference path='fourslash.ts' />
//// function doSomething(a){}
//// doSomething(/*x*/(/*y*/) => 1 + 1);
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to anonymous function",
actionDescription: "Convert to anonymous function",
newContent: `function doSomething(a){}
doSomething(function() {
return 1 + 1;
});`,
});

View file

@ -0,0 +1,13 @@
/// <reference path='fourslash.ts' />
//// [9,8,7].map(/*x*/n/*y*/ => n + 418);
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to anonymous function",
actionDescription: "Convert to anonymous function",
newContent: `[9,8,7].map(function(n) {
return n + 418;
});`,
});

View file

@ -0,0 +1,17 @@
/// <reference path='fourslash.ts' />
//// const foo = /*x*/a/*y*/ => {
//// let b = 1;
//// return a + b;
//// };
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to anonymous function",
actionDescription: "Convert to anonymous function",
newContent: `const foo = function(a) {
let b = 1;
return a + b;
};`,
});

View file

@ -0,0 +1,13 @@
/// <reference path='fourslash.ts' />
//// const foo = /*x*/(/*y*/a,b,c) => a + 1;
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to anonymous function",
actionDescription: "Convert to anonymous function",
newContent: `const foo = function(a, b, c) {
return a + 1;
};`,
});

View file

@ -0,0 +1,13 @@
/// <reference path='fourslash.ts' />
//// const foo = /*x*/(/*y*/) => 1 + 1;
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to anonymous function",
actionDescription: "Convert to anonymous function",
newContent: `const foo = function() {
return 1 + 1;
};`,
});

View file

@ -0,0 +1,13 @@
/// <reference path='fourslash.ts' />
//// const increment = /*x*/(/*y*/a: number): number => a + 1;
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to anonymous function",
actionDescription: "Convert to anonymous function",
newContent: `const increment = function(a: number): number {
return a + 1;
};`,
});

View file

@ -0,0 +1,15 @@
/// <reference path='fourslash.ts' />
//// const foo = /*x*/f/*y*/unction() {
//// return;
//// };
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to arrow function",
actionDescription: "Convert to arrow function",
newContent: `const foo = () => {
return;
};`,
});

View file

@ -0,0 +1,15 @@
/// <reference path='fourslash.ts' />
//// function foo(lambda){}
//// foo(function /*x*/is/*y*/Even(n) {
//// return n % 2 === 0;
//// });
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to arrow function",
actionDescription: "Convert to arrow function",
newContent: `function foo(lambda){}
foo((n) => n % 2 === 0);`,
});

View file

@ -0,0 +1,13 @@
/// <reference path='fourslash.ts' />
//// [4,5,6,7].map(function /*x*/is/*y*/Even(n) {
//// return n % 2 === 0;
//// });
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to arrow function",
actionDescription: "Convert to arrow function",
newContent: `[4,5,6,7].map((n) => n % 2 === 0);`,
});

View file

@ -0,0 +1,17 @@
/// <reference path='fourslash.ts' />
//// const foo = /*x*/f/*y*/unction() {
//// let a = 41;
//// return a + 1;
//// };
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to arrow function",
actionDescription: "Convert to arrow function",
newContent: `const foo = () => {
let a = 41;
return a + 1;
};`,
});

View file

@ -0,0 +1,25 @@
/// <reference path='fourslash.ts' />
//// const foo = /*x*/f/*y*/unction() {
//// // secret
//// let a = 41;
//// /*
//// msg
//// */
//// return a + 1;
//// };
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to arrow function",
actionDescription: "Convert to arrow function",
newContent: `const foo = () => {
// secret
let a = 41;
/*
msg
*/
return a + 1;
};`,
});

View file

@ -0,0 +1,13 @@
/// <reference path='fourslash.ts' />
//// const foo = /*x*/f/*y*/unction(a, b, c) {
//// return a + b + c;
//// };
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to arrow function",
actionDescription: "Convert to arrow function",
newContent: `const foo = (a, b, c) => a + b + c;`,
});

View file

@ -0,0 +1,17 @@
/// <reference path='fourslash.ts' />
//// let bar;
//// const foo = /*x*/f/*y*/unction() {
//// bar = 42;
//// };
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to arrow function",
actionDescription: "Convert to arrow function",
newContent: `let bar;
const foo = () => {
bar = 42;
};`,
});

View file

@ -0,0 +1,15 @@
/// <reference path='fourslash.ts' />
//// const foo = /*x*/f/*y*/unction() {
//// let bar;
//// };
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to arrow function",
actionDescription: "Convert to arrow function",
newContent: `const foo = () => {
let bar;
};`,
});

View file

@ -0,0 +1,17 @@
/// <reference path='fourslash.ts' />
//// function s(){}
//// const foo = /*x*/f/*y*/unction() {
//// s();
//// };
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to arrow function",
actionDescription: "Convert to arrow function",
newContent: `function s(){}
const foo = () => {
s();
};`,
});

View file

@ -0,0 +1,15 @@
/// <reference path='fourslash.ts' />
//// const foo = /*x*/f/*y*/unction() {
//// for (let i = 0; i < 5; i++) { }
//// };
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to arrow function",
actionDescription: "Convert to arrow function",
newContent: `const foo = () => {
for (let i = 0; i < 5; i++) { }
};`,
});

View file

@ -0,0 +1,15 @@
/// <reference path='fourslash.ts' />
//// const foo = /*x*/f/*y*/unction() {
//// if (true) { }
//// };
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to arrow function",
actionDescription: "Convert to arrow function",
newContent: `const foo = () => {
if (true) { }
};`,
});

View file

@ -0,0 +1,13 @@
/// <reference path='fourslash.ts' />
//// const foo = /*x*/f/*y*/unction() {
//// return 42;
//// };
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to arrow function",
actionDescription: "Convert to arrow function",
newContent: `const foo = () => 42;`,
});

View file

@ -0,0 +1,15 @@
/// <reference path='fourslash.ts' />
//// const foo = /*x*/f/*y*/unction() {
//// while (true) { }
//// };
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to arrow function",
actionDescription: "Convert to arrow function",
newContent: `const foo = () => {
while (true) { }
};`,
});

View file

@ -0,0 +1,13 @@
/// <reference path='fourslash.ts' />
//// const concat = /*x*/f/*y*/unction(a: string, b: string): string {
//// return a + b;
//// };
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to arrow function",
actionDescription: "Convert to arrow function",
newContent: `const concat = (a: string, b: string): string => a + b;`,
});

View file

@ -0,0 +1,23 @@
/// <reference path='fourslash.ts' />
//// const foo = /*x*/a/*y*/ => {
//// // secret word
//// return a + 1;
//// /*
//// hidden msg
//// */
//// };
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to named function",
actionDescription: "Convert to named function",
newContent: `function foo(a) {
// secret word
return a + 1;
/*
hidden msg
*/
}`,
});

View file

@ -0,0 +1,17 @@
/// <reference path='fourslash.ts' />
//// export let foo = /*x*/a/*y*/ => {
//// let b = 1;
//// return a + b;
//// };
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to named function",
actionDescription: "Convert to named function",
newContent: `export function foo(a) {
let b = 1;
return a + b;
}`,
});

View file

@ -0,0 +1,19 @@
/// <reference path='fourslash.ts' />
//// // Do not add me second time
//// export let foo = /*x*/a/*y*/ => {
//// let b = 1;
//// return a + b;
//// };
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to named function",
actionDescription: "Convert to named function",
newContent: `// Do not add me second time
export function foo(a) {
let b = 1;
return a + b;
}`,
});

View file

@ -0,0 +1,15 @@
/// <reference path='fourslash.ts' />
//// let foo, bar = /*x*/(/*y*/) => 1 + 1, magicNo;
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to named function",
actionDescription: "Convert to named function",
newContent: `let foo, magicNo;
function bar() {
return 1 + 1;
}
`,
});

View file

@ -0,0 +1,15 @@
/// <reference path='fourslash.ts' />
//// export let foo, bar = /*x*/(/*y*/) => 1 + 1;
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to named function",
actionDescription: "Convert to named function",
newContent: `export let foo;
export function bar() {
return 1 + 1;
}
`,
});

View file

@ -0,0 +1,17 @@
/// <reference path='fourslash.ts' />
//// // Do not add me second time
//// export let foo, bar = /*x*/(/*y*/) => 1 + 1;
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to named function",
actionDescription: "Convert to named function",
newContent: `// Do not add me second time
export let foo;
export function bar() {
return 1 + 1;
}
`,
});

View file

@ -0,0 +1,15 @@
/// <reference path='fourslash.ts' />
//// let foo, /*x*/b/*y*/ar = a => 1 + a;
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to named function",
actionDescription: "Convert to named function",
newContent: `let foo;
function bar(a) {
return 1 + a;
}
`,
});

View file

@ -0,0 +1,17 @@
/// <reference path='fourslash.ts' />
//// let foo = /*x*/a/*y*/ => {
//// let b = 1;
//// return a + b;
//// };
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to named function",
actionDescription: "Convert to named function",
newContent: `function foo(a) {
let b = 1;
return a + b;
}`,
});

View file

@ -0,0 +1,13 @@
/// <reference path='fourslash.ts' />
//// let foo = /*x*/(/*y*/a,b,c) => a + 1;
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to named function",
actionDescription: "Convert to named function",
newContent: `function foo(a, b, c) {
return a + 1;
}`,
});

View file

@ -0,0 +1,13 @@
/// <reference path='fourslash.ts' />
//// let foo = /*x*/(/*y*/) => 1 + 1;
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to named function",
actionDescription: "Convert to named function",
newContent: `function foo() {
return 1 + 1;
}`,
});

View file

@ -0,0 +1,13 @@
/// <reference path='fourslash.ts' />
//// let isFoo = /*x*/(/*y*/n: number): boolean => n === 42;
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to named function",
actionDescription: "Convert to named function",
newContent: `function isFoo(n: number): boolean {
return n === 42;
}`,
});

View file

@ -0,0 +1,13 @@
/// <reference path='fourslash.ts' />
//// /*x*/let/*y*/ foo = a => 1 + a;
goTo.select("x", "y");
edit.applyRefactor({
refactorName: "Convert arrow function or function expression",
actionName: "Convert to named function",
actionDescription: "Convert to named function",
newContent: `function foo(a) {
return 1 + a;
}`,
});