From e52efb04f3f0a7199da08573cffc9aaac6ad373e Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Thu, 3 May 2018 16:28:55 -0700 Subject: [PATCH] Fix #22419: Add `kind` field to `OutliningSpan` --- src/harness/fourslash.ts | 21 +++++++++++++++---- src/server/client.ts | 3 ++- src/server/protocol.ts | 5 +++++ src/server/session.ts | 3 ++- src/services/outliningElementsCollector.ts | 20 +++++++++--------- src/services/types.ts | 11 ++++++++++ .../getOutliningForObjectsInArray.ts | 2 +- tests/cases/fourslash/getOutliningSpans.ts | 2 +- .../fourslash/getOutliningSpansForRegions.ts | 2 +- ...getOutliningSpansForUnbalancedEndRegion.ts | 2 +- .../getOutliningSpansForUnbalancedRegion.ts | 2 +- .../server/getOutliningSpansForComments.ts | 18 ++++++++++++++++ .../server/getOutliningSpansForRegions.ts | 2 +- .../fourslash/shims-pp/getOutliningSpans.ts | 2 +- .../fourslash/shims/getOutliningSpans.ts | 2 +- 15 files changed, 73 insertions(+), 24 deletions(-) create mode 100644 tests/cases/fourslash/server/getOutliningSpansForComments.ts diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 2ab96fe1676..8b9929161e2 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -2461,7 +2461,13 @@ Actual: ${stringify(fullActual)}`); this.verifyClassifications(expected, actual, this.activeFile.content); } - public verifyOutliningSpans(spans: Range[]) { + public printOutliningSpans() { + const spans = this.languageService.getOutliningSpans(this.activeFile.fileName); + Harness.IO.log(`Outlining spans (${spans.length} items)`); + Harness.IO.log(stringify(spans)); + } + + public verifyOutliningSpans(spans: Range[], kind?: "comment" | "region" | "code") { const actual = this.languageService.getOutliningSpans(this.activeFile.fileName); if (actual.length !== spans.length) { @@ -2470,7 +2476,10 @@ Actual: ${stringify(fullActual)}`); ts.zipWith(spans, actual, (expectedSpan, actualSpan, i) => { if (expectedSpan.pos !== actualSpan.textSpan.start || expectedSpan.end !== ts.textSpanEnd(actualSpan.textSpan)) { - this.raiseError(`verifyOutliningSpans failed - span ${(i + 1)} expected: (${expectedSpan.pos},${expectedSpan.end}), actual: (${actualSpan.textSpan.start},${ts.textSpanEnd(actualSpan.textSpan)})`); + return this.raiseError(`verifyOutliningSpans failed - span ${(i + 1)} expected: (${expectedSpan.pos},${expectedSpan.end}), actual: (${actualSpan.textSpan.start},${ts.textSpanEnd(actualSpan.textSpan)})`); + } + if (kind !== undefined && actualSpan.kind !== kind) { + return this.raiseError(`verifyOutliningSpans failed - span ${(i + 1)} expected kind: ('${kind}'), actual: ('${actualSpan.kind}')`); } }); } @@ -4290,8 +4299,8 @@ namespace FourSlashInterface { this.state.verifyCurrentNameOrDottedNameSpanText(text); } - public outliningSpansInCurrentFile(spans: FourSlash.Range[]) { - this.state.verifyOutliningSpans(spans); + public outliningSpansInCurrentFile(spans: FourSlash.Range[], kind?: "comment" | "region" | "code") { + this.state.verifyOutliningSpans(spans, kind); } public todoCommentsInCurrentFile(descriptors: string[]) { @@ -4585,6 +4594,10 @@ namespace FourSlashInterface { public printContext() { this.state.printContext(); } + + public printOutliningSpans() { + this.state.printOutliningSpans(); + } } export class Format { diff --git a/src/server/client.ts b/src/server/client.ts index d7a83ee5320..39231ae878d 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -530,7 +530,8 @@ namespace ts.server { textSpan: this.decodeSpan(item.textSpan, file), hintSpan: this.decodeSpan(item.hintSpan, file), bannerText: item.bannerText, - autoCollapse: item.autoCollapse + autoCollapse: item.autoCollapse, + kind: item.kind })); } diff --git a/src/server/protocol.ts b/src/server/protocol.ts index b933d88af7e..a93d402a3a6 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -326,6 +326,11 @@ namespace ts.server.protocol { * the 'Collapse to Definitions' command is invoked. */ autoCollapse: boolean; + + /** + * Classification of the contents of the span + */ + kind: OutliningSpanKind; } /** diff --git a/src/server/session.ts b/src/server/session.ts index baed5a2dbe3..bb635988755 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1112,7 +1112,8 @@ namespace ts.server { textSpan: this.toLocationTextSpan(s.textSpan, scriptInfo), hintSpan: this.toLocationTextSpan(s.hintSpan, scriptInfo), bannerText: s.bannerText, - autoCollapse: s.autoCollapse + autoCollapse: s.autoCollapse, + kind: s.kind })); } else { diff --git a/src/services/outliningElementsCollector.ts b/src/services/outliningElementsCollector.ts index 65888305d81..10684c268be 100644 --- a/src/services/outliningElementsCollector.ts +++ b/src/services/outliningElementsCollector.ts @@ -50,7 +50,7 @@ namespace ts.OutliningElementsCollector { if (!result[1]) { const span = createTextSpanFromBounds(sourceFile.text.indexOf("//", currentLineStart), lineEnd); - regions.push(createOutliningSpan(span, span, /*autoCollapse*/ false, result[2] || "#region")); + regions.push(createOutliningSpan(span, OutliningSpanKind.Region, span, /*autoCollapse*/ false, result[2] || "#region")); } else { const region = regions.pop(); @@ -83,7 +83,7 @@ namespace ts.OutliningElementsCollector { break; case SyntaxKind.MultiLineCommentTrivia: combineAndAddMultipleSingleLineComments(); - out.push(createOutliningSpanFromBounds(pos, end)); + out.push(createOutliningSpanFromBounds(pos, end, OutliningSpanKind.Comment)); singleLineCommentCount = 0; break; default: @@ -95,13 +95,13 @@ namespace ts.OutliningElementsCollector { function combineAndAddMultipleSingleLineComments(): void { // Only outline spans of two or more consecutive single line comments if (singleLineCommentCount > 1) { - out.push(createOutliningSpanFromBounds(firstSingleLineCommentStart, lastSingleLineCommentEnd)); + out.push(createOutliningSpanFromBounds(firstSingleLineCommentStart, lastSingleLineCommentEnd, OutliningSpanKind.Comment)); } } } - function createOutliningSpanFromBounds(pos: number, end: number): OutliningSpan { - return createOutliningSpan(createTextSpanFromBounds(pos, end)); + function createOutliningSpanFromBounds(pos: number, end: number, kind: OutliningSpanKind): OutliningSpan { + return createOutliningSpan(createTextSpanFromBounds(pos, end), kind); } function getOutliningSpanForNode(n: Node, sourceFile: SourceFile): OutliningSpan | undefined { @@ -136,7 +136,7 @@ namespace ts.OutliningElementsCollector { default: // Block was a standalone block. In this case we want to only collapse // the span of the block, independent of any parent span. - return createOutliningSpan(createTextSpanFromNode(n, sourceFile)); + return createOutliningSpan(createTextSpanFromNode(n, sourceFile), OutliningSpanKind.Code); } case SyntaxKind.ModuleBlock: return spanForNode(n.parent); @@ -166,11 +166,11 @@ namespace ts.OutliningElementsCollector { return undefined; } const textSpan = createTextSpanFromBounds(useFullStart ? openToken.getFullStart() : openToken.getStart(sourceFile), closeToken.getEnd()); - return createOutliningSpan(textSpan, createTextSpanFromNode(hintSpanNode, sourceFile), autoCollapse); + return createOutliningSpan(textSpan, OutliningSpanKind.Code, createTextSpanFromNode(hintSpanNode, sourceFile), autoCollapse); } } - function createOutliningSpan(textSpan: TextSpan, hintSpan: TextSpan = textSpan, autoCollapse = false, bannerText = "..."): OutliningSpan { - return { textSpan, hintSpan, bannerText, autoCollapse }; + function createOutliningSpan(textSpan: TextSpan, kind: OutliningSpanKind, hintSpan: TextSpan = textSpan, autoCollapse = false, bannerText = "..."): OutliningSpan { + return { textSpan, kind, hintSpan, bannerText, autoCollapse }; } -} \ No newline at end of file +} diff --git a/src/services/types.ts b/src/services/types.ts index 2369db8a0ce..31baf7df399 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -816,6 +816,17 @@ namespace ts { * the 'Collapse to Definitions' command is invoked. */ autoCollapse: boolean; + + /** + * Classification of the contents of the span + */ + kind: OutliningSpanKind; + } + + export const enum OutliningSpanKind { + Comment = "comment", + Region = "region", + Code = "code" } export const enum OutputFileType { diff --git a/tests/cases/fourslash/getOutliningForObjectsInArray.ts b/tests/cases/fourslash/getOutliningForObjectsInArray.ts index 89634224832..5d0a0454f0b 100644 --- a/tests/cases/fourslash/getOutliningForObjectsInArray.ts +++ b/tests/cases/fourslash/getOutliningForObjectsInArray.ts @@ -53,4 +53,4 @@ //// ]|] //// ]|]; -verify.outliningSpansInCurrentFile(test.ranges()); \ No newline at end of file +verify.outliningSpansInCurrentFile(test.ranges(), "code"); \ No newline at end of file diff --git a/tests/cases/fourslash/getOutliningSpans.ts b/tests/cases/fourslash/getOutliningSpans.ts index 63e8becfc4f..f4d1eb33e23 100644 --- a/tests/cases/fourslash/getOutliningSpans.ts +++ b/tests/cases/fourslash/getOutliningSpans.ts @@ -97,4 +97,4 @@ ////class AfterNestedNodes[| { ////}|] -verify.outliningSpansInCurrentFile(test.ranges()); +verify.outliningSpansInCurrentFile(test.ranges(), "code"); diff --git a/tests/cases/fourslash/getOutliningSpansForRegions.ts b/tests/cases/fourslash/getOutliningSpansForRegions.ts index fcd71e29ef1..f6e8b48596d 100644 --- a/tests/cases/fourslash/getOutliningSpansForRegions.ts +++ b/tests/cases/fourslash/getOutliningSpansForRegions.ts @@ -48,4 +48,4 @@ ////// #endregion ////*/ -verify.outliningSpansInCurrentFile(test.ranges()); \ No newline at end of file +verify.outliningSpansInCurrentFile(test.ranges(), "region"); \ No newline at end of file diff --git a/tests/cases/fourslash/getOutliningSpansForUnbalancedEndRegion.ts b/tests/cases/fourslash/getOutliningSpansForUnbalancedEndRegion.ts index c15e23eba75..aa358afd926 100644 --- a/tests/cases/fourslash/getOutliningSpansForUnbalancedEndRegion.ts +++ b/tests/cases/fourslash/getOutliningSpansForUnbalancedEndRegion.ts @@ -7,4 +7,4 @@ //// ////// #endregion unmatched -verify.outliningSpansInCurrentFile(test.ranges()); \ No newline at end of file +verify.outliningSpansInCurrentFile(test.ranges(), "region"); \ No newline at end of file diff --git a/tests/cases/fourslash/getOutliningSpansForUnbalancedRegion.ts b/tests/cases/fourslash/getOutliningSpansForUnbalancedRegion.ts index eaebc906bfb..377197d57e1 100644 --- a/tests/cases/fourslash/getOutliningSpansForUnbalancedRegion.ts +++ b/tests/cases/fourslash/getOutliningSpansForUnbalancedRegion.ts @@ -7,4 +7,4 @@ //// ////// #endregion matched|] -verify.outliningSpansInCurrentFile(test.ranges()); \ No newline at end of file +verify.outliningSpansInCurrentFile(test.ranges(), "region"); \ No newline at end of file diff --git a/tests/cases/fourslash/server/getOutliningSpansForComments.ts b/tests/cases/fourslash/server/getOutliningSpansForComments.ts new file mode 100644 index 00000000000..1c1d38454e7 --- /dev/null +++ b/tests/cases/fourslash/server/getOutliningSpansForComments.ts @@ -0,0 +1,18 @@ +/// + +////[|/* +//// Block comment at the beginning of the file before module: +//// line one of the comment +//// line two of the comment +//// line three +//// line four +//// line five +////*/|] +////declare module "m"; +////[|// Single line comments at the start of the file +////// line 2 +////// line 3 +////// line 4|] +////declare module "n"; + +verify.outliningSpansInCurrentFile(test.ranges(), "comment"); diff --git a/tests/cases/fourslash/server/getOutliningSpansForRegions.ts b/tests/cases/fourslash/server/getOutliningSpansForRegions.ts index 24f515fb8a9..81d2409cf9d 100644 --- a/tests/cases/fourslash/server/getOutliningSpansForRegions.ts +++ b/tests/cases/fourslash/server/getOutliningSpansForRegions.ts @@ -48,4 +48,4 @@ ////// #endregion ////*/ -verify.outliningSpansInCurrentFile(test.ranges()); +verify.outliningSpansInCurrentFile(test.ranges(), "region"); diff --git a/tests/cases/fourslash/shims-pp/getOutliningSpans.ts b/tests/cases/fourslash/shims-pp/getOutliningSpans.ts index 63e8becfc4f..f4d1eb33e23 100644 --- a/tests/cases/fourslash/shims-pp/getOutliningSpans.ts +++ b/tests/cases/fourslash/shims-pp/getOutliningSpans.ts @@ -97,4 +97,4 @@ ////class AfterNestedNodes[| { ////}|] -verify.outliningSpansInCurrentFile(test.ranges()); +verify.outliningSpansInCurrentFile(test.ranges(), "code"); diff --git a/tests/cases/fourslash/shims/getOutliningSpans.ts b/tests/cases/fourslash/shims/getOutliningSpans.ts index 63e8becfc4f..f4d1eb33e23 100644 --- a/tests/cases/fourslash/shims/getOutliningSpans.ts +++ b/tests/cases/fourslash/shims/getOutliningSpans.ts @@ -97,4 +97,4 @@ ////class AfterNestedNodes[| { ////}|] -verify.outliningSpansInCurrentFile(test.ranges()); +verify.outliningSpansInCurrentFile(test.ranges(), "code");