diff --git a/src/services/outliningElementsCollector.ts b/src/services/outliningElementsCollector.ts index 6830a6e0b407e..a001d9c68f261 100644 --- a/src/services/outliningElementsCollector.ts +++ b/src/services/outliningElementsCollector.ts @@ -227,6 +227,31 @@ namespace ts.OutliningElementsCollector { return spanForTemplateLiteral(n); case SyntaxKind.ArrayBindingPattern: return spanForNode(n, /*autoCollapse*/ false, /*useFullStart*/ !isBindingElement(n.parent), SyntaxKind.OpenBracketToken); + case SyntaxKind.ArrowFunction: + return spanForArrowFunction(n); + case SyntaxKind.CallExpression: + return spanForCallExpression(n); + } + + function spanForCallExpression(node: CallExpression): OutliningSpan | undefined { + if (!node.arguments.length) { + return undefined; + } + const openToken = findChildOfKind(node, SyntaxKind.OpenParenToken, sourceFile); + const closeToken = findChildOfKind(node, SyntaxKind.CloseParenToken, sourceFile); + if (!openToken || !closeToken || positionsAreOnSameLine(openToken.pos, closeToken.pos, sourceFile)) { + return undefined; + } + + return spanBetweenTokens(openToken, closeToken, node, sourceFile, /*autoCollapse*/ false, /*useFullStart*/ true); + } + + function spanForArrowFunction(node: ArrowFunction): OutliningSpan | undefined { + if (isBlock(node.body) || positionsAreOnSameLine(node.body.getFullStart(), node.body.getEnd(), sourceFile)) { + return undefined; + } + const textSpan = createTextSpanFromBounds(node.body.getFullStart(), node.body.getEnd()); + return createOutliningSpan(textSpan, OutliningSpanKind.Code, createTextSpanFromNode(node)); } function spanForJSXElement(node: JsxElement): OutliningSpan | undefined { diff --git a/tests/cases/fourslash/getOutliningSpans.ts b/tests/cases/fourslash/getOutliningSpans.ts index bec0f4f0d3b29..f8bc10ad95544 100644 --- a/tests/cases/fourslash/getOutliningSpans.ts +++ b/tests/cases/fourslash/getOutliningSpans.ts @@ -106,14 +106,14 @@ ////function f(x: number[], y: number[])[| { //// return 3; ////}|] -////f( +////f[|( ////// single line array literal span won't render in VS //// [|[0]|], //// [|[ //// 1, //// 2 //// ]|] -////); +////)|]; verify.outliningSpansInCurrentFile(test.ranges(), "code"); diff --git a/tests/cases/fourslash/getOutliningSpansDepthChainedCalls.ts b/tests/cases/fourslash/getOutliningSpansDepthChainedCalls.ts index 9fc8c50dd7044..2dc01223c9a1d 100644 --- a/tests/cases/fourslash/getOutliningSpansDepthChainedCalls.ts +++ b/tests/cases/fourslash/getOutliningSpansDepthChainedCalls.ts @@ -4,113 +4,113 @@ ////declare var router: any; ////router -//// .get("/", async(ctx) =>[|{ +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) +//// }|])|] verify.outliningSpansInCurrentFile(test.ranges()); diff --git a/tests/cases/fourslash/outliningSpansForArguments.ts b/tests/cases/fourslash/outliningSpansForArguments.ts new file mode 100644 index 0000000000000..56c3c21e77a8b --- /dev/null +++ b/tests/cases/fourslash/outliningSpansForArguments.ts @@ -0,0 +1,18 @@ +/// + +//// console.log(123, 456)l; +//// console.log( +//// ); +//// console.log[|( +//// 123, 456 +//// )|]; +//// console.log[|( +//// 123, +//// 456 +//// )|]; +//// () =>[| console.log[|( +//// 123, +//// 456 +//// )|]|]; + +verify.outliningSpansInCurrentFile(test.ranges()); diff --git a/tests/cases/fourslash/outliningSpansForArrowFunctionBody.ts b/tests/cases/fourslash/outliningSpansForArrowFunctionBody.ts new file mode 100644 index 0000000000000..7dfc6e8ec2735 --- /dev/null +++ b/tests/cases/fourslash/outliningSpansForArrowFunctionBody.ts @@ -0,0 +1,15 @@ +/// + +//// () => 42; +//// () => ( 42 ); +//// () =>[| { +//// 42 +//// }|]; +//// () =>[| ( +//// 42 +//// )|]; +//// () =>[| "foo" + +//// "bar" + +//// "baz"|]; + +verify.outliningSpansInCurrentFile(test.ranges()); diff --git a/tests/cases/fourslash/outliningSpansForFunction.ts b/tests/cases/fourslash/outliningSpansForFunction.ts index f46886b73068d..e89ecd6f843ab 100644 --- a/tests/cases/fourslash/outliningSpansForFunction.ts +++ b/tests/cases/fourslash/outliningSpansForFunction.ts @@ -5,9 +5,9 @@ //// b: number ////) => { //// return a + b; -////}|] -///// -////(a: number, b: number) => [|{ +////}|]; +//// +////(a: number, b: number) =>[| { //// return a + b; ////}|] //// @@ -55,30 +55,30 @@ ////}|] //// ////declare function foo(props: any): void; -////foo( +////foo[|( //// a =>[| { //// //// }|] -////) +////)|] //// -////foo( +////foo[|( //// (a) =>[| { //// //// }|] -////) +////)|] //// -////foo( +////foo[|( //// (a, b, c) =>[| { //// //// }|] -////) +////)|] //// -////foo([| +////foo[|([| //// (a, //// b, //// c) => { //// //// }|] -////) +////)|] verify.outliningSpansInCurrentFile(test.ranges());