From b1ad8072534e5ad6f63ed0b762b2dbb13eb4f739 Mon Sep 17 00:00:00 2001 From: fisker Date: Sun, 30 Nov 2025 17:07:54 +0800 Subject: [PATCH 1/2] Improve preprocess --- src/parse/preprocess.ts | 27 +++++++++++---------------- src/utils/content-tag.ts | 16 ---------------- tests/unit-tests/preprocess.test.ts | 22 +++++++++++----------- 3 files changed, 22 insertions(+), 43 deletions(-) diff --git a/src/parse/preprocess.ts b/src/parse/preprocess.ts index 6241f6e2..aa6a2077 100644 --- a/src/parse/preprocess.ts +++ b/src/parse/preprocess.ts @@ -1,8 +1,6 @@ import { - getBuffer, parse, type Range, - replaceContents, sliceByteRange, } from '../utils/content-tag.js'; @@ -17,8 +15,6 @@ export interface Template { }; } -const PLACEHOLDER = '~'; - /** * Replace the template with a parsable placeholder that takes up the same * range. @@ -27,6 +23,9 @@ export function preprocessTemplateRange( template: Template, code: string, ): string { + const { start, end } = template.utf16Range; + const after = code.slice(end); + let prefix: string; let suffix: string; @@ -39,7 +38,7 @@ export function preprocessTemplateRange( prefix = '{/*'; suffix = '*/}'; - const nextToken = sliceByteRange(code, template.range.endByte).match(/\S+/); + const nextToken = after.match(/\S+/); if (nextToken && (nextToken[0] === 'as' || nextToken[0] === 'satisfies')) { // Replace with parenthesized ObjectExpression @@ -48,18 +47,14 @@ export function preprocessTemplateRange( } } - // We need to replace forward slash with _something else_, because - // forward slash breaks the parsed templates. - const contents = template.contents.replaceAll('/', PLACEHOLDER); + const before = code.slice(0, start); + const spaces = code + .slice(start + prefix.length, end - suffix.length) + // Replace everything except `\n` with space, so the line and column remain correct + // Prettier normalized EOL to `\n`, so we don't need worry about `\r` and `\r\n` + .replaceAll(/[^\n]/g, ' '); - const templateLength = template.range.endByte - template.range.startByte; - const spaces = - templateLength - getBuffer(contents).length - prefix.length - suffix.length; - - return replaceContents(code, { - contents: [prefix, contents, ' '.repeat(spaces), suffix].join(''), - range: template.range, - }); + return before + prefix + spaces + suffix + after; } /** Pre-processes the template info, parsing the template content to Glimmer AST. */ diff --git a/src/utils/content-tag.ts b/src/utils/content-tag.ts index 6623444d..24bc586d 100644 --- a/src/utils/content-tag.ts +++ b/src/utils/content-tag.ts @@ -28,22 +28,6 @@ export function parse( return preprocessor.parse(file, options); } -export function replaceContents( - file: string, - options: { - contents: string; - range: Range; - }, -): string { - const { contents, range } = options; - - return [ - sliceByteRange(file, 0, range.startByte), - contents, - sliceByteRange(file, range.endByte), - ].join(''); -} - export function sliceByteRange( string_: string, indexStart: number, diff --git a/tests/unit-tests/preprocess.test.ts b/tests/unit-tests/preprocess.test.ts index f516c030..386ebfb9 100644 --- a/tests/unit-tests/preprocess.test.ts +++ b/tests/unit-tests/preprocess.test.ts @@ -8,40 +8,40 @@ import { const TEST_CASES = [ { code: '', - expected: [`{/*hi */}`], + expected: [`{/* */}`], }, { code: '', - expected: [`{/*~* hi *~ */}`], + expected: [`{/* */}`], }, { code: '', - expected: [`{/*
hi<~div> */}`], + expected: [`{/* */}`], }, { code: '', - expected: [`{/*{{#if true}}hi{{~if}} */}`], + expected: [`{/* */}`], }, { - code: '', - expected: [`{/*~~~~~~~~~~~~~~~~ */}`], + code: '', + expected: [`{/* \n */}`], }, { code: '', - expected: [`{/*💩 */}`], + expected: [`{/* */}`], }, { code: 'const a = ; const b = ;', expected: [ - `const a = {/*foo */}; const b = ;`, - `const a = ; const b = {/*bar */};`, + `const a = {/* */}; const b = ;`, + `const a = ; const b = {/* */};`, ], }, { code: `const a = ; const b = `, expected: [ - `const a = {/*💩💩💩💩💩💩💩 */}; const b = `, - `const a = ; const b = {/*💩 */}`, + `const a = {/* */}; const b = `, + `const a = ; const b = {/* */}`, ], }, ]; From 2ba22ef79b959b203f4ff6739e874e47fd44c5c6 Mon Sep 17 00:00:00 2001 From: fisker Date: Mon, 1 Dec 2025 00:32:32 +0800 Subject: [PATCH 2/2] Format --- src/parse/preprocess.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/parse/preprocess.ts b/src/parse/preprocess.ts index aa6a2077..fade93c4 100644 --- a/src/parse/preprocess.ts +++ b/src/parse/preprocess.ts @@ -1,8 +1,4 @@ -import { - parse, - type Range, - sliceByteRange, -} from '../utils/content-tag.js'; +import { parse, type Range, sliceByteRange } from '../utils/content-tag.js'; export interface Template { contentRange: Range;