diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index be27a8ecc1..1d98e2e6f1 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -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", diff --git a/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts b/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts new file mode 100644 index 0000000000..e469e2ecca --- /dev/null +++ b/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts @@ -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)); + } +} diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index dafc056d33..1fd5ba3058 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -113,6 +113,7 @@ "refactors/addOrRemoveBracesToArrowFunction.ts", "refactors/convertParamsToDestructuredObject.ts", "refactors/convertStringOrTemplateLiteral.ts", + "refactors/convertArrowFunctionOrFunctionExpression.ts", "services.ts", "breakpoints.ts", "transform.ts", diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon.ts new file mode 100644 index 0000000000..0fa3222617 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon.ts @@ -0,0 +1,28 @@ +/// + +//// /*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"); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_FnArgument.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_FnArgument.ts new file mode 100644 index 0000000000..6c017aeeb7 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_FnArgument.ts @@ -0,0 +1,34 @@ +/// + +//// 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"); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_nested_this.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_nested_this.ts new file mode 100644 index 0000000000..cbf5712252 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_nested_this.ts @@ -0,0 +1,19 @@ +/// + +//// 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"); 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 0000000000..a895fea432 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_this.ts @@ -0,0 +1,11 @@ +/// + +//// 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"); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_unusedName.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_unusedName.ts new file mode 100644 index 0000000000..480dd466ec --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_unusedName.ts @@ -0,0 +1,28 @@ +/// + +//// /*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"); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_usedName.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_usedName.ts new file mode 100644 index 0000000000..ff87ca8471 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Anon_usedName.ts @@ -0,0 +1,28 @@ +/// + +//// /*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"); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow.ts new file mode 100644 index 0000000000..619b2af822 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow.ts @@ -0,0 +1,33 @@ +/// + +//// /*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"); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow_FnArgument.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow_FnArgument.ts new file mode 100644 index 0000000000..6d309494da --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow_FnArgument.ts @@ -0,0 +1,30 @@ +/// + +//// 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"); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow_MultiDecl.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow_MultiDecl.ts new file mode 100644 index 0000000000..1e87f8bc0c --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow_MultiDecl.ts @@ -0,0 +1,23 @@ +/// + +//// /*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"); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow_nested_this.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow_nested_this.ts new file mode 100644 index 0000000000..4b5985b9a8 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_Availability_Arrow_nested_this.ts @@ -0,0 +1,19 @@ +/// + +//// 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"); 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 0000000000..d1905c48f3 --- /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_Comment.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_Comment.ts new file mode 100644 index 0000000000..c3a65cbf05 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_Comment.ts @@ -0,0 +1,23 @@ +/// + +//// 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 + */ +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_FnArgument.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_FnArgument.ts new file mode 100644 index 0000000000..c07a741f1a --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_FnArgument.ts @@ -0,0 +1,15 @@ +/// + +//// 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; + });`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_MapArgument.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_MapArgument.ts new file mode 100644 index 0000000000..8d53517d7e --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_MapArgument.ts @@ -0,0 +1,13 @@ +/// + +//// [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; + });`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_MultiLine.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_MultiLine.ts new file mode 100644 index 0000000000..cbaadbf6a8 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_MultiLine.ts @@ -0,0 +1,17 @@ +/// + +//// 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; +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_MultiParam.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_MultiParam.ts new file mode 100644 index 0000000000..38953dbf24 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_MultiParam.ts @@ -0,0 +1,13 @@ +/// + +//// 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; +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_SingleLine.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_SingleLine.ts new file mode 100644 index 0000000000..9870104eb1 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_SingleLine.ts @@ -0,0 +1,13 @@ +/// + +//// 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; +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_Typed.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_Typed.ts new file mode 100644 index 0000000000..0fbea66be0 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToAnon_Typed.ts @@ -0,0 +1,13 @@ +/// + +//// 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; +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_EmptyReturn.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_EmptyReturn.ts new file mode 100644 index 0000000000..e77adca0eb --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_EmptyReturn.ts @@ -0,0 +1,15 @@ +/// + +//// 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; +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_FnArgument.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_FnArgument.ts new file mode 100644 index 0000000000..3dc442e4e5 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_FnArgument.ts @@ -0,0 +1,15 @@ +/// + +//// 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);`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_MapArgument.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_MapArgument.ts new file mode 100644 index 0000000000..4e1c0b2f9f --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_MapArgument.ts @@ -0,0 +1,13 @@ +/// + +//// [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);`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_MultiLine.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_MultiLine.ts new file mode 100644 index 0000000000..71855947b3 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_MultiLine.ts @@ -0,0 +1,17 @@ +/// + +//// 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; +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_MultiLine_Comment.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_MultiLine_Comment.ts new file mode 100644 index 0000000000..470cae1c44 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_MultiLine_Comment.ts @@ -0,0 +1,25 @@ +/// + +//// 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; +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Param.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Param.ts new file mode 100644 index 0000000000..a765908099 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Param.ts @@ -0,0 +1,13 @@ +/// + +//// 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;`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_Assign.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_Assign.ts new file mode 100644 index 0000000000..f5e15ab8ac --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_Assign.ts @@ -0,0 +1,17 @@ +/// + +//// 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; +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_Decl.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_Decl.ts new file mode 100644 index 0000000000..e1f15b78f3 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_Decl.ts @@ -0,0 +1,15 @@ +/// + +//// 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; +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_FnCall.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_FnCall.ts new file mode 100644 index 0000000000..af8068699d --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_FnCall.ts @@ -0,0 +1,17 @@ +/// + +//// 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(); +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_For.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_For.ts new file mode 100644 index 0000000000..a0da4868b0 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_For.ts @@ -0,0 +1,15 @@ +/// + +//// 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++) { } +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_If.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_If.ts new file mode 100644 index 0000000000..65084f0f3a --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_If.ts @@ -0,0 +1,15 @@ +/// + +//// 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) { } +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_Return.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_Return.ts new file mode 100644 index 0000000000..c901046de3 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_Return.ts @@ -0,0 +1,13 @@ +/// + +//// 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;`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_While.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_While.ts new file mode 100644 index 0000000000..830a9b4933 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Single_While.ts @@ -0,0 +1,15 @@ +/// + +//// 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) { } +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Typed.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Typed.ts new file mode 100644 index 0000000000..01d30d1f08 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToArrow_Typed.ts @@ -0,0 +1,13 @@ +/// + +//// 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;`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_Comment.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_Comment.ts new file mode 100644 index 0000000000..8f615da85e --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_Comment.ts @@ -0,0 +1,23 @@ +/// + +//// 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 + */ +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_Modifier.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_Modifier.ts new file mode 100644 index 0000000000..9d60d17239 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_Modifier.ts @@ -0,0 +1,17 @@ +/// + +//// 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; +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_Modifier_Comment.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_Modifier_Comment.ts new file mode 100644 index 0000000000..20bb388559 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_Modifier_Comment.ts @@ -0,0 +1,19 @@ +/// + +//// // 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; +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiDecl.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiDecl.ts new file mode 100644 index 0000000000..789eb98141 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiDecl.ts @@ -0,0 +1,15 @@ +/// + +//// 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; +} +`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiDecl_Modifier.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiDecl_Modifier.ts new file mode 100644 index 0000000000..4044d76ad2 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiDecl_Modifier.ts @@ -0,0 +1,15 @@ +/// + +//// 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; +} +`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiDecl_Modifier_Comment.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiDecl_Modifier_Comment.ts new file mode 100644 index 0000000000..46fc080ebd --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiDecl_Modifier_Comment.ts @@ -0,0 +1,17 @@ +/// + +//// // 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; +} +`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiDecl_VarSelection.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiDecl_VarSelection.ts new file mode 100644 index 0000000000..6757cb1560 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiDecl_VarSelection.ts @@ -0,0 +1,15 @@ +/// + +//// 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; +} +`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiLine.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiLine.ts new file mode 100644 index 0000000000..ef2866f783 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiLine.ts @@ -0,0 +1,17 @@ +/// + +//// 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; +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiParam.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiParam.ts new file mode 100644 index 0000000000..0036f11136 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_MultiParam.ts @@ -0,0 +1,13 @@ +/// + +//// 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; +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_SingleLine.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_SingleLine.ts new file mode 100644 index 0000000000..4952856d87 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_SingleLine.ts @@ -0,0 +1,13 @@ +/// + +//// 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; +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_Typed.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_Typed.ts new file mode 100644 index 0000000000..6a67c390bd --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_Typed.ts @@ -0,0 +1,13 @@ +/// + +//// 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; +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_keywordSelection.ts b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_keywordSelection.ts new file mode 100644 index 0000000000..2e2f1b2b14 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertArrowFunctionOrFunctionExpression_ToNamed_keywordSelection.ts @@ -0,0 +1,13 @@ +/// + +//// /*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; +}`, +});