diff --git a/src/services/refactors/inferFunctionReturnType.ts b/src/services/refactors/inferFunctionReturnType.ts index 4fad099cad029..535e25c330b4d 100644 --- a/src/services/refactors/inferFunctionReturnType.ts +++ b/src/services/refactors/inferFunctionReturnType.ts @@ -59,7 +59,9 @@ namespace ts.refactor.inferFunctionReturnType { if (isInJSFile(context.file) || !refactorKindBeginsWith(inferReturnTypeAction.kind, context.kind)) return; const token = getTokenAtPosition(context.file, context.startPosition); - const declaration = findAncestor(token, isConvertibleDeclaration); + const declaration = findAncestor(token, n => + isBlock(n) || n.parent && isArrowFunction(n.parent) && (n.kind === SyntaxKind.EqualsGreaterThanToken || n.parent.body === n) ? "quit" : + isConvertibleDeclaration(n)) as ConvertibleDeclaration | undefined; if (!declaration || !declaration.body || declaration.type) { return { error: getLocaleSpecificMessage(Diagnostics.Return_type_must_be_inferred_from_a_function) }; } @@ -68,7 +70,7 @@ namespace ts.refactor.inferFunctionReturnType { const returnType = tryGetReturnType(typeChecker, declaration); if (!returnType) { return { error: getLocaleSpecificMessage(Diagnostics.Could_not_determine_function_return_type) }; - }; + } const returnTypeNode = typeChecker.typeToTypeNode(returnType, declaration, NodeBuilderFlags.NoTruncation); if (returnTypeNode) { diff --git a/tests/cases/fourslash/refactorInferFunctionReturnType16.ts b/tests/cases/fourslash/refactorInferFunctionReturnType16.ts new file mode 100644 index 0000000000000..d8d281d546afe --- /dev/null +++ b/tests/cases/fourslash/refactorInferFunctionReturnType16.ts @@ -0,0 +1,32 @@ +/// + +////function /*a*//*b*/f1() { +//// return { x: 1, y: 1 }; +////} +////func/*c*//*d*/tion f2() { +//// return { x: 1, y: 1 }; +////} +////function f3(/*e*//*f*/) { +//// return { x: 1, y: 1 }; +////} +////function f4() {/*g*//*h*/ +//// return { x: 1, y: 1 }; +////} +////function f5() { +//// return { x: 1, y: 1 /*i*//*j*/}; +////} + +goTo.select("a", "b"); +verify.refactorAvailable("Infer function return type"); + +goTo.select("c", "d"); +verify.refactorAvailable("Infer function return type"); + +goTo.select("e", "f"); +verify.refactorAvailable("Infer function return type"); + +goTo.select("g", "h"); +verify.not.refactorAvailable("Infer function return type"); + +goTo.select("i", "j"); +verify.not.refactorAvailable("Infer function return type"); diff --git a/tests/cases/fourslash/refactorInferFunctionReturnType17.ts b/tests/cases/fourslash/refactorInferFunctionReturnType17.ts new file mode 100644 index 0000000000000..421b7aef2abad --- /dev/null +++ b/tests/cases/fourslash/refactorInferFunctionReturnType17.ts @@ -0,0 +1,42 @@ +/// + +////class F1 { +//// /*a*//*b*/method() { +//// return { x: 1, y: 1 }; +//// } +////} +////class F2 { +//// met/*c*//*d*/hod(){ +//// return { x: 1, y: 1 }; +//// } +////} +////class F3 { +//// method(/*e*//*f*/) { +//// return { x: 1, y: 1 }; +//// } +////} +////class F4 { +//// method() { +//// return { x: 1, y: 1 /*g*//*h*/}; +//// } +////} +////class F5 { +//// method() { +//// return { x: 1, y: 1 /*i*//*j*/}; +//// } +////} + +goTo.select("a", "b"); +verify.refactorAvailable("Infer function return type"); + +goTo.select("c", "d"); +verify.refactorAvailable("Infer function return type"); + +goTo.select("e", "f"); +verify.refactorAvailable("Infer function return type"); + +goTo.select("g", "h"); +verify.not.refactorAvailable("Infer function return type"); + +goTo.select("i", "j"); +verify.not.refactorAvailable("Infer function return type"); diff --git a/tests/cases/fourslash/refactorInferFunctionReturnType18.ts b/tests/cases/fourslash/refactorInferFunctionReturnType18.ts new file mode 100644 index 0000000000000..1006eeff534f2 --- /dev/null +++ b/tests/cases/fourslash/refactorInferFunctionReturnType18.ts @@ -0,0 +1,32 @@ +/// + +////const f1 = /*a*//*b*/function () { +//// return { x: 1, y: 1 }; +////} +////const f2 = func/*c*//*d*/tion() { +//// return { x: 1, y: 1 }; +////} +////const f3 = function (/*e*//*f*/) { +//// return { x: 1, y: 1 }; +////} +////const f4 = function () {/*g*//*h*/ +//// return { x: 1, y: 1 }; +////} +////const f5 = function () { +//// return { x: 1, y: 1 /*i*//*j*/}; +////} + +goTo.select("a", "b"); +verify.refactorAvailable("Infer function return type"); + +goTo.select("c", "d"); +verify.refactorAvailable("Infer function return type"); + +goTo.select("e", "f"); +verify.refactorAvailable("Infer function return type"); + +goTo.select("g", "h"); +verify.not.refactorAvailable("Infer function return type"); + +goTo.select("i", "j"); +verify.not.refactorAvailable("Infer function return type"); diff --git a/tests/cases/fourslash/refactorInferFunctionReturnType19.ts b/tests/cases/fourslash/refactorInferFunctionReturnType19.ts new file mode 100644 index 0000000000000..8860c1ac7395e --- /dev/null +++ b/tests/cases/fourslash/refactorInferFunctionReturnType19.ts @@ -0,0 +1,32 @@ +/// + +////const f1 = /*a*//*b*/() =>{ +//// return { x: 1, y: 1 }; +////} +////const f2 = (/*c*//*d*/) => { +//// return { x: 1, y: 1 }; +////} +////const f3 = () => /*e*//*f*/{ +//// return { x: 1, y: 1 }; +////} +////const f4 = () => {/*g*//*h*/ +//// return { x: 1, y: 1 }; +////} +////const f5 = () => { +//// return { x: 1, y: 1/*i*//*j*/ }; +////} + +goTo.select("a", "b"); +verify.refactorAvailable("Infer function return type"); + +goTo.select("c", "d"); +verify.refactorAvailable("Infer function return type"); + +goTo.select("e", "f"); +verify.not.refactorAvailable("Infer function return type"); + +goTo.select("g", "h"); +verify.not.refactorAvailable("Infer function return type"); + +goTo.select("i", "j"); +verify.not.refactorAvailable("Infer function return type"); diff --git a/tests/cases/fourslash/refactorInferFunctionReturnType20.ts b/tests/cases/fourslash/refactorInferFunctionReturnType20.ts new file mode 100644 index 0000000000000..b5b29adc4ca5d --- /dev/null +++ b/tests/cases/fourslash/refactorInferFunctionReturnType20.ts @@ -0,0 +1,20 @@ +/// + +////function f1(/*a*//*b*/x, { y }) { +//// return { x, y: 1 }; +////} +////function f2(x, { /*c*//*d*/y }) { +//// return { x, y: 1 }; +////} +////function f3(x, /*e*//*f*/{ y }) { +//// return { x, y: 1 }; +////} + +goTo.select("a", "b"); +verify.refactorAvailable("Infer function return type"); + +goTo.select("c", "d"); +verify.refactorAvailable("Infer function return type"); + +goTo.select("e", "f"); +verify.refactorAvailable("Infer function return type"); diff --git a/tests/cases/fourslash/refactorInferFunctionReturnType21.ts b/tests/cases/fourslash/refactorInferFunctionReturnType21.ts new file mode 100644 index 0000000000000..544be7bc5c864 --- /dev/null +++ b/tests/cases/fourslash/refactorInferFunctionReturnType21.ts @@ -0,0 +1,18 @@ +/// + +////const f1 = /*a*//*b*/(x: number) => x; +////const f2 = (x: number) /*c*//*d*/=> x; +////const f3 = (x: number) => /*e*//*f*/x +////const f4= (x: number) => x/*g*//*h*/ + +goTo.select("a", "b"); +verify.refactorAvailable("Infer function return type"); + +goTo.select("c", "d"); +verify.not.refactorAvailable("Infer function return type"); + +goTo.select("e", "f"); +verify.not.refactorAvailable("Infer function return type"); + +goTo.select("g", "h"); +verify.not.refactorAvailable("Infer function return type"); diff --git a/tests/cases/fourslash/refactorKind_rewriteFunction.ts b/tests/cases/fourslash/refactorKind_rewriteFunction.ts index 56fe42cd9a449..b6946a99fa31a 100644 --- a/tests/cases/fourslash/refactorKind_rewriteFunction.ts +++ b/tests/cases/fourslash/refactorKind_rewriteFunction.ts @@ -1,10 +1,9 @@ /// -//// const arrow = () /*a*/=>/*b*/ 1; +//// const arrow = /*a*//*b*/() => 1; goTo.select("a", "b"); -verify.refactorKindAvailable("refactor.rewrite", -[ +verify.refactorKindAvailable("refactor.rewrite", [ "refactor.rewrite.arrow.braces.add", "refactor.rewrite.function.named", "refactor.rewrite.function.anonymous",