diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 5e53605decf..570dfc99653 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1026,7 +1026,7 @@ namespace ts { // SyntaxKind.UnparsedSource function emitUnparsedSource(unparsed: UnparsedSource) { - write(unparsed.text); + writer.rawWrite(unparsed.text); } // diff --git a/src/compiler/sourcemap.ts b/src/compiler/sourcemap.ts index 1f8723b9c80..a93aedebf27 100644 --- a/src/compiler/sourcemap.ts +++ b/src/compiler/sourcemap.ts @@ -151,8 +151,8 @@ namespace ts { // Initialize source map data completedSections = []; - sectionStartLine = 0; - sectionStartColumn = 0; + sectionStartLine = 1; + sectionStartColumn = 1; sourceMapData = { sourceMapFilePath, jsSourceMappingURL: !compilerOptions.inlineSourceMap ? getBaseFileName(normalizeSlashes(sourceMapFilePath)) : undefined!, // TODO: GH#18217 @@ -270,14 +270,11 @@ namespace ts { function generateMap(): SourceMap { if (completedSections.length) { - const last = { - offset: { line: sectionStartLine, column: sectionStartColumn }, - map: captureSection() - }; + captureSectionalSpanIfNeeded(/*reset*/ false); return { version: 3, - file: last.map.file, - sections: [...completedSections, last] + file: sourceMapData.sourceMapFile, + sections: completedSections }; } else { @@ -353,8 +350,8 @@ namespace ts { sourceLinePos.line++; sourceLinePos.character++; - const emittedLine = writer.getLine() - sectionStartLine; - const emittedColumn = emittedLine === 0 ? writer.getColumn() - sectionStartColumn : writer.getColumn(); + const emittedLine = writer.getLine() - sectionStartLine + 1; + const emittedColumn = emittedLine === 0 ? (writer.getColumn() - sectionStartColumn + 1) : writer.getColumn(); // If this location wasn't recorded or the location in source is going backwards, record the span if (!lastRecordedSourceMapSpan || @@ -389,6 +386,15 @@ namespace ts { } } + function captureSectionalSpanIfNeeded(reset: boolean) { + if (lastRecordedSourceMapSpan && lastRecordedSourceMapSpan === lastEncodedSourceMapSpan) { // If we've recorded some spans, save them + completedSections.push({ offset: { line: sectionStartLine - 1, column: sectionStartColumn - 1 }, map: captureSection() }); + if (reset) { + resetSectionalData(); + } + } + } + /** * Emits a node with possible leading and trailing source maps. * @@ -403,10 +409,7 @@ namespace ts { if (node) { if (isUnparsedSource(node) && node.sourceMapText !== undefined) { - if (lastRecordedSourceMapSpan && lastRecordedSourceMapSpan === lastEncodedSourceMapSpan) { // If we've recorded some spans, save them - completedSections.push({ offset: { line: sectionStartLine, column: sectionStartColumn }, map: captureSection() }); - resetSectionalData(); - } + captureSectionalSpanIfNeeded(/*reset*/ true); const text = node.sourceMapText; let parsed: {} | undefined; try { @@ -415,7 +418,7 @@ namespace ts { catch { // empty } - const offset = { line: writer.getLine(), column: writer.getColumn() }; + const offset = { line: writer.getLine() - 1, column: writer.getColumn() - 1 }; completedSections.push(parsed ? { offset, @@ -431,7 +434,7 @@ namespace ts { sectionStartLine = writer.getLine(); sectionStartColumn = writer.getColumn(); lastRecordedSourceMapSpan = undefined!; - lastEncodedSourceMapSpan = undefined!; + lastEncodedSourceMapSpan = defaultLastEncodedSourceMapSpan; return emitResult; } const emitNode = node.emitNode; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 48289a43836..70fafe8fb66 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2825,13 +2825,26 @@ namespace ts { let lineCount: number; let linePos: number; + function updateLineCountAndPosFor(s: string) { + const lineStartsOfS = computeLineStarts(s); + if (lineStartsOfS.length > 1) { + lineCount = lineCount + lineStartsOfS.length - 1; + linePos = output.length - s.length + last(lineStartsOfS); + lineStart = (linePos - output.length) === 0; + } + else { + lineStart = false; + } + } + function write(s: string) { if (s && s.length) { if (lineStart) { - output += getIndentString(indent); + s = getIndentString(indent) + s; lineStart = false; } output += s; + updateLineCountAndPosFor(s); } } @@ -2845,21 +2858,14 @@ namespace ts { function rawWrite(s: string) { if (s !== undefined) { - if (lineStart) { - lineStart = false; - } output += s; + updateLineCountAndPosFor(s); } } function writeLiteral(s: string) { if (s && s.length) { write(s); - const lineStartsOfS = computeLineStarts(s); - if (lineStartsOfS.length > 1) { - lineCount = lineCount + lineStartsOfS.length - 1; - linePos = output.length - s.length + last(lineStartsOfS); - } } } @@ -2873,7 +2879,9 @@ namespace ts { } function writeTextOfNode(text: string, node: Node) { - write(getTextOfNodeFromSourceText(text, node)); + const s = getTextOfNodeFromSourceText(text, node); + write(s); + updateLineCountAndPosFor(s); } reset(); diff --git a/tests/baselines/reference/tsxErrorRecovery1.js b/tests/baselines/reference/tsxErrorRecovery1.js index 7abf1346c35..d91c464c6f9 100644 --- a/tests/baselines/reference/tsxErrorRecovery1.js +++ b/tests/baselines/reference/tsxErrorRecovery1.js @@ -14,5 +14,5 @@ function foo() { } // Shouldn't see any errors down here var y = {a} 1 }; -; + ; } diff --git a/tests/baselines/reference/tsxStatelessFunctionComponents3.js b/tests/baselines/reference/tsxStatelessFunctionComponents3.js index e7bfc980229..152c7e6ba4f 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponents3.js +++ b/tests/baselines/reference/tsxStatelessFunctionComponents3.js @@ -27,7 +27,7 @@ define(["require", "exports", "react"], function (require, exports, React) { // Should be OK var MainMenu = function (props) { return (

Main Menu

-
); }; + ); }; var App = function (_a) { var children = _a.children; return (