diff --git a/src/services/outliningElementsCollector.ts b/src/services/outliningElementsCollector.ts
index 59f8e9f5549..748085bd041 100644
--- a/src/services/outliningElementsCollector.ts
+++ b/src/services/outliningElementsCollector.ts
@@ -2,14 +2,14 @@
namespace ts.OutliningElementsCollector {
const collapseText = "...";
const maxDepth = 20;
+ const regionText = "#region";
+ const regionStart = new RegExp("^\\s*//\\s*#region(\\s+.*)?$");
+ const regionEnd = new RegExp("^\\s*//\\s*#endregion(\\s|$)");
export function collectElements(sourceFile: SourceFile, cancellationToken: CancellationToken): OutliningSpan[] {
const elements: OutliningSpan[] = [];
let depth = 0;
const regions: RegionRange[] = [];
- const regionText = "#region";
- const regionStart = new RegExp("^\\s*//\\s*#region(\\s+.*)?$", "gm");
- const regionEnd = new RegExp("^\\s*//\\s*#endregion(\\s|$)", "gm");
walk(sourceFile);
gatherRegions();
@@ -42,9 +42,10 @@ namespace ts.OutliningElementsCollector {
function addOutliningSpanRegions(regionSpan: RegionRange) {
if (regionSpan) {
+ const textSpan = createTextSpanFromBounds(regionSpan.pos, regionSpan.end);
const span: OutliningSpan = {
- textSpan: createTextSpanFromBounds(regionSpan.pos, regionSpan.end),
- hintSpan: createTextSpanFromBounds(regionSpan.pos, regionSpan.end),
+ textSpan,
+ hintSpan: textSpan,
bannerText: regionSpan.name,
autoCollapse: false,
};
@@ -106,29 +107,18 @@ namespace ts.OutliningElementsCollector {
return isFunctionBlock(node) && node.parent.kind !== SyntaxKind.ArrowFunction;
}
- function isRegionStart(start: number, end: number) {
+ function getRegionName(start: number, end: number) {
if (!ts.formatting.getRangeOfEnclosingComment(sourceFile, start, /*onlyMultiLine*/ true)) {
const comment = sourceFile.text.substring(start, end);
const result = comment.match(regionStart);
if (result && result.length > 0) {
- const sections = result[0].split(" ").filter(function (s) { return s !== ""; });
-
- if (sections[0] === "//") {
- if (sections.length > 2) {
- return result[0].substring(result[0].indexOf(sections[2]));
- }
- else {
- return regionText;
- }
+ const label = result.pop();
+ if (label) {
+ return label.trim();
}
else {
- if (sections.length > 1) {
- return result[0].substring(result[0].indexOf(sections[1]));
- }
- else {
- return regionText;
- }
+ return regionText;
}
}
}
@@ -146,13 +136,15 @@ namespace ts.OutliningElementsCollector {
function gatherRegions(): void {
const lineStarts = sourceFile.getLineStarts();
- for (const currentLineStart of lineStarts) {
- const lineEnd = sourceFile.getLineEndOfPosition(currentLineStart);
+ for (let i = 0; i < lineStarts.length; i++) {
+ const currentLineStart = lineStarts[i];
+ const lineEnd = lineStarts[i + 1] - 1 || sourceFile.getEnd();
- const name = isRegionStart(currentLineStart, lineEnd);
+ const name = getRegionName(currentLineStart, lineEnd);
if (name) {
+ const start = sourceFile.getFullText().indexOf("//", currentLineStart);
const region: RegionRange = {
- pos: currentLineStart,
+ pos: start,
end: lineEnd,
name,
};
diff --git a/tests/cases/fourslash/getOutliningSpansForRegions.ts b/tests/cases/fourslash/getOutliningSpansForRegions.ts
index 73202fb9c9c..80e1c3113cf 100644
--- a/tests/cases/fourslash/getOutliningSpansForRegions.ts
+++ b/tests/cases/fourslash/getOutliningSpansForRegions.ts
@@ -11,7 +11,7 @@
////// #endregion|]
////
////// region with extra whitespace in all valid locations
-////[| // #region label2 label3
+//// [|// #region label2 label3
////
//// // #endregion|]
////
diff --git a/tests/cases/fourslash/getOutliningSpansForUnbalancedEndRegion.ts b/tests/cases/fourslash/getOutliningSpansForUnbalancedEndRegion.ts
new file mode 100644
index 00000000000..c15e23eba75
--- /dev/null
+++ b/tests/cases/fourslash/getOutliningSpansForUnbalancedEndRegion.ts
@@ -0,0 +1,10 @@
+///
+
+////// bottom-heavy region balance
+////[|// #region matched
+////
+////// #endregion matched|]
+////
+////// #endregion unmatched
+
+verify.outliningSpansInCurrentFile(test.ranges());
\ No newline at end of file
diff --git a/tests/cases/fourslash/getOutliningSpansForUnbalancedRegion.ts b/tests/cases/fourslash/getOutliningSpansForUnbalancedRegion.ts
new file mode 100644
index 00000000000..f50aae713a5
--- /dev/null
+++ b/tests/cases/fourslash/getOutliningSpansForUnbalancedRegion.ts
@@ -0,0 +1,11 @@
+///
+
+////// top-heavy region balance
+////// #region unmatched
+////
+////[|// #region matched
+////
+////// #endregion matched|]
+
+debugger;
+verify.outliningSpansInCurrentFile(test.ranges());
\ No newline at end of file