From 599e36a0685fbeebddc00e8cb36b76fb52b9f0c8 Mon Sep 17 00:00:00 2001 From: Jesse Trinity <42591254+jessetrinity@users.noreply.github.com> Date: Thu, 25 Jul 2019 21:29:12 -0700 Subject: [PATCH] Decrement line ends if they end with a carriage return. (#31220) * Decrement line ends if they end with a carriage return. * Changed handling of newlines and inlined regex operation. * fixed misname of hintSpan * added tests * revert inline of regex match and use getLineEndOfPosition * fixed lint error and changed a silly thing in tests --- src/services/outliningElementsCollector.ts | 5 ++--- .../unittests/services/hostNewLineSupport.ts | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/services/outliningElementsCollector.ts b/src/services/outliningElementsCollector.ts index a23eddf0628..6e5e2b963e8 100644 --- a/src/services/outliningElementsCollector.ts +++ b/src/services/outliningElementsCollector.ts @@ -71,9 +71,8 @@ namespace ts.OutliningElementsCollector { function addRegionOutliningSpans(sourceFile: SourceFile, out: Push): void { const regions: OutliningSpan[] = []; const lineStarts = sourceFile.getLineStarts(); - for (let i = 0; i < lineStarts.length; i++) { - const currentLineStart = lineStarts[i]; - const lineEnd = i + 1 === lineStarts.length ? sourceFile.getEnd() : lineStarts[i + 1] - 1; + for (const currentLineStart of lineStarts) { + const lineEnd = sourceFile.getLineEndOfPosition(currentLineStart); const lineText = sourceFile.text.substring(currentLineStart, lineEnd); const result = isRegionDelimiter(lineText); if (!result || isInComment(sourceFile, currentLineStart)) { diff --git a/src/testRunner/unittests/services/hostNewLineSupport.ts b/src/testRunner/unittests/services/hostNewLineSupport.ts index cafe4813431..48bc124f3bc 100644 --- a/src/testRunner/unittests/services/hostNewLineSupport.ts +++ b/src/testRunner/unittests/services/hostNewLineSupport.ts @@ -38,6 +38,18 @@ namespace ts { verifyNewLines(content, { newLine: NewLineKind.LineFeed }); } + function verifyOutliningSpanNewLines(content: string, options: CompilerOptions) { + const ls = testLSWithFiles(options, [{ + content, + fileOptions: {}, + unitName: "input.ts" + }]); + const span = ls.getOutliningSpans("input.ts")[0]; + const textAfterSpanCollapse = content.substring(span.textSpan.start + span.textSpan.length); + assert(textAfterSpanCollapse.match(options.newLine === NewLineKind.CarriageReturnLineFeed ? /\r\n/ : /[^\r]\n/), "expected to find appropriate newlines"); + assert(!textAfterSpanCollapse.match(options.newLine === NewLineKind.CarriageReturnLineFeed ? /[^\r]\n/ : /\r\n/), "expected not to find inappropriate newlines"); + } + it("should exist and respect provided compiler options", () => { verifyBothNewLines(` function foo() { @@ -45,5 +57,15 @@ namespace ts { } `); }); + + it("should respect CRLF line endings around outlining spans", () => { + verifyOutliningSpanNewLines("// comment not included\r\n// #region name\r\nlet x: string = \"x\";\r\n// #endregion name\r\n", + { newLine: NewLineKind.CarriageReturnLineFeed }); + }); + + it("should respect LF line endings around outlining spans", () => { + verifyOutliningSpanNewLines("// comment not included\n// #region name\nlet x: string = \"x\";\n// #endregion name\n\n", + { newLine: NewLineKind.LineFeed }); + }); }); }