diff --git a/.changeset/eleven-planets-camp.md b/.changeset/eleven-planets-camp.md new file mode 100644 index 00000000..03b0d871 --- /dev/null +++ b/.changeset/eleven-planets-camp.md @@ -0,0 +1,5 @@ +--- +"@astrojs/compiler": patch +--- + +Fixes sourcemapping for CRLF line endings wrongfully including the last character diff --git a/internal/printer/printer.go b/internal/printer/printer.go index 6e2af9f3..32d2797d 100644 --- a/internal/printer/printer.go +++ b/internal/printer/printer.go @@ -107,14 +107,22 @@ func (p *printer) addTSXStyle(start int, end int, content string, styleType stri func (p *printer) printTextWithSourcemap(text string, l loc.Loc) { start := l.Start + skipNext := false for pos, c := range text { - // Handle Windows-specific "\r\n" newlines + if skipNext { + skipNext = false + continue + } + + // If we encounter a CRLF, map both characters to the same location if c == '\r' && len(text[pos:]) > 1 && text[pos+1] == '\n' { - // tiny optimization: avoid calling `utf8.DecodeRuneInString` - // if we know the next char is `\n` - start++ + p.addSourceMapping(loc.Loc{Start: start}) + p.print("\r\n") + start += 2 + skipNext = true continue } + _, nextCharByteSize := utf8.DecodeRuneInString(text[pos:]) p.addSourceMapping(loc.Loc{Start: start}) p.print(string(c)) @@ -124,12 +132,19 @@ func (p *printer) printTextWithSourcemap(text string, l loc.Loc) { func (p *printer) printEscapedJSXTextWithSourcemap(text string, l loc.Loc) { start := l.Start + skipNext := false for pos, c := range text { - // Handle Windows-specific "\r\n" newlines + if skipNext { + skipNext = false + continue + } + + // If we encounter a CRLF, map both characters to the same location if c == '\r' && len(text[pos:]) > 1 && text[pos+1] == '\n' { - // tiny optimization: avoid calling `utf8.DecodeRuneInString` - // if we know the next char is `\n` - start++ + p.addSourceMapping(loc.Loc{Start: start}) + p.print("\r\n") + start += 2 + skipNext = true continue } diff --git a/packages/compiler/test/tsx-sourcemaps/template-windows.ts b/packages/compiler/test/tsx-sourcemaps/template-windows.ts index b0d7a995..59498ee8 100644 --- a/packages/compiler/test/tsx-sourcemaps/template-windows.ts +++ b/packages/compiler/test/tsx-sourcemaps/template-windows.ts @@ -3,6 +3,17 @@ import { test } from 'uvu'; import * as assert from 'uvu/assert'; import { testTSXSourcemap } from '../utils.js'; +test('last character does not end up in middle of CRLF', async () => { + const input = "---\r\nimport { Meta } from '$lib/components/Meta.astro';\r\n---\r\n"; + const output = await testTSXSourcemap(input, ';'); + assert.equal(output, { + source: 'index.astro', + line: 2, + column: 50, + name: null, + }); +}); + test('template expression basic', async () => { const input = '