diff --git a/internal/printer/utilities.go b/internal/printer/utilities.go index cc3839cba5..9fdcb764d4 100644 --- a/internal/printer/utilities.go +++ b/internal/printer/utilities.go @@ -909,6 +909,12 @@ func newLineCharacterCache(source sourcemap.Source) *lineCharacterCache { // getLineAndCharacter returns the 0-based line number and UTF-16 code unit // offset from the start of that line for the given byte position. func (c *lineCharacterCache) getLineAndCharacter(pos int) (line int, character core.UTF16Offset) { + // Synthetic tokens (e.g. auto-inserted '}' for an unclosed block) can have + // positions beyond the end of the source text. Clamp to match JS semantics + // where string.slice(start, end) silently caps end at string.length. + if pos > len(c.text) { + pos = len(c.text) + } line = scanner.ComputeLineOfPosition(c.lineMap, pos) if c.hasCached && line == c.cachedLine && pos >= c.cachedPos { // Incremental: only count UTF-16 code units from the last cached position. diff --git a/testdata/baselines/reference/compiler/sourceMapEmitUnclosedBlock.errors.txt b/testdata/baselines/reference/compiler/sourceMapEmitUnclosedBlock.errors.txt new file mode 100644 index 0000000000..3342b22839 --- /dev/null +++ b/testdata/baselines/reference/compiler/sourceMapEmitUnclosedBlock.errors.txt @@ -0,0 +1,9 @@ +sourceMapEmitUnclosedBlock.ts(2,1): error TS1005: '}' expected. + + +==== sourceMapEmitUnclosedBlock.ts (1 errors) ==== + { + + +!!! error TS1005: '}' expected. +!!! related TS1007 sourceMapEmitUnclosedBlock.ts:1:1: The parser expected to find a '}' to match the '{' token here. \ No newline at end of file diff --git a/testdata/baselines/reference/compiler/sourceMapEmitUnclosedBlock.js b/testdata/baselines/reference/compiler/sourceMapEmitUnclosedBlock.js new file mode 100644 index 0000000000..1e211f0ebb --- /dev/null +++ b/testdata/baselines/reference/compiler/sourceMapEmitUnclosedBlock.js @@ -0,0 +1,11 @@ +//// [tests/cases/compiler/sourceMapEmitUnclosedBlock.ts] //// + +//// [sourceMapEmitUnclosedBlock.ts] +{ + + +//// [sourceMapEmitUnclosedBlock.js] +"use strict"; +{ +} +//# sourceMappingURL=sourceMapEmitUnclosedBlock.js.map \ No newline at end of file diff --git a/testdata/baselines/reference/compiler/sourceMapEmitUnclosedBlock.js.map b/testdata/baselines/reference/compiler/sourceMapEmitUnclosedBlock.js.map new file mode 100644 index 0000000000..361cf33207 --- /dev/null +++ b/testdata/baselines/reference/compiler/sourceMapEmitUnclosedBlock.js.map @@ -0,0 +1,3 @@ +//// [sourceMapEmitUnclosedBlock.js.map] +{"version":3,"file":"sourceMapEmitUnclosedBlock.js","sourceRoot":"","sources":["sourceMapEmitUnclosedBlock.ts"],"names":[],"mappings":";AAAA,CAAC;AACD,CAAA,AADC"} +//// https://sokra.github.io/source-map-visualization#base64,InVzZSBzdHJpY3QiOw0Kew0KfQ0KLy8jIHNvdXJjZU1hcHBpbmdVUkw9c291cmNlTWFwRW1pdFVuY2xvc2VkQmxvY2suanMubWFw,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic291cmNlTWFwRW1pdFVuY2xvc2VkQmxvY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJzb3VyY2VNYXBFbWl0VW5jbG9zZWRCbG9jay50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsQ0FBQztBQUNELENBQUEsQUFEQyJ9,ewo= diff --git a/testdata/baselines/reference/compiler/sourceMapEmitUnclosedBlock.sourcemap.txt b/testdata/baselines/reference/compiler/sourceMapEmitUnclosedBlock.sourcemap.txt new file mode 100644 index 0000000000..f7979924df --- /dev/null +++ b/testdata/baselines/reference/compiler/sourceMapEmitUnclosedBlock.sourcemap.txt @@ -0,0 +1,34 @@ +=================================================================== +JsFile: sourceMapEmitUnclosedBlock.js +mapUrl: sourceMapEmitUnclosedBlock.js.map +sourceRoot: +sources: sourceMapEmitUnclosedBlock.ts +=================================================================== +------------------------------------------------------------------- +emittedFile:sourceMapEmitUnclosedBlock.js +sourceFile:sourceMapEmitUnclosedBlock.ts +------------------------------------------------------------------- +>>>"use strict"; +>>>{ +1 > +2 >^ +3 > ^-> +1 > +2 >{ +1 >Emitted(2, 1) Source(1, 1) + SourceIndex(0) +2 >Emitted(2, 2) Source(1, 2) + SourceIndex(0) +--- +>>>} +1-> +2 >^ +3 > +4 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-> +1-> + > +2 > +3 > +1->Emitted(3, 1) Source(2, 1) + SourceIndex(0) +2 >Emitted(3, 2) Source(2, 1) + SourceIndex(0) +3 >Emitted(3, 2) Source(1, 2) + SourceIndex(0) +--- +>>>//# sourceMappingURL=sourceMapEmitUnclosedBlock.js.map \ No newline at end of file diff --git a/testdata/baselines/reference/compiler/sourceMapEmitUnclosedBlock.symbols b/testdata/baselines/reference/compiler/sourceMapEmitUnclosedBlock.symbols new file mode 100644 index 0000000000..ada130f0aa --- /dev/null +++ b/testdata/baselines/reference/compiler/sourceMapEmitUnclosedBlock.symbols @@ -0,0 +1,5 @@ +//// [tests/cases/compiler/sourceMapEmitUnclosedBlock.ts] //// + +=== sourceMapEmitUnclosedBlock.ts === +{ + diff --git a/testdata/baselines/reference/compiler/sourceMapEmitUnclosedBlock.types b/testdata/baselines/reference/compiler/sourceMapEmitUnclosedBlock.types new file mode 100644 index 0000000000..ada130f0aa --- /dev/null +++ b/testdata/baselines/reference/compiler/sourceMapEmitUnclosedBlock.types @@ -0,0 +1,5 @@ +//// [tests/cases/compiler/sourceMapEmitUnclosedBlock.ts] //// + +=== sourceMapEmitUnclosedBlock.ts === +{ + diff --git a/testdata/tests/cases/compiler/sourceMapEmitUnclosedBlock.ts b/testdata/tests/cases/compiler/sourceMapEmitUnclosedBlock.ts new file mode 100644 index 0000000000..f4e9b063f4 --- /dev/null +++ b/testdata/tests/cases/compiler/sourceMapEmitUnclosedBlock.ts @@ -0,0 +1,3 @@ +// @sourceMap: true + +{