1- import { Preprocessor } from 'content-tag' ;
1+ import {
2+ getBuffer ,
3+ parse ,
4+ type Range ,
5+ replaceContents ,
6+ sliceByteRange ,
7+ } from '../utils/content-tag.js' ;
28
39export interface Template {
410 contents : string ;
11+ range : Range ;
512 type : string ;
6- range : {
7- start : number ;
8- end : number ;
9- } ;
1013 utf16Range : {
11- start : number ;
1214 end : number ;
15+ start : number ;
1316 } ;
1417}
1518
16- const BufferMap : Map < string , Buffer > = new Map ( ) ;
17-
1819const PLACEHOLDER = '~' ;
1920
20- function getBuffer ( s : string ) : Buffer {
21- let buf = BufferMap . get ( s ) ;
22- if ( ! buf ) {
23- buf = Buffer . from ( s ) ;
24- BufferMap . set ( s , buf ) ;
25- }
26- return buf ;
27- }
28-
29- /** Slice string using byte range */
30- function sliceByteRange ( s : string , a : number , b ?: number ) : string {
31- const buf = getBuffer ( s ) ;
32- return buf . subarray ( a , b ) . toString ( ) ;
33- }
34-
35- /** Converts byte index to js char index (utf16) */
36- function byteToCharIndex ( s : string , byteOffset : number ) : number {
37- const buf = getBuffer ( s ) ;
38- return buf . subarray ( 0 , byteOffset ) . toString ( ) . length ;
39- }
40-
41- /** Calculate byte length */
42- function byteLength ( s : string ) : number {
43- return getBuffer ( s ) . length ;
44- }
45-
46- function replaceRange (
47- s : string ,
48- start : number ,
49- end : number ,
50- substitute : string ,
51- ) : string {
52- return sliceByteRange ( s , 0 , start ) + substitute + sliceByteRange ( s , end ) ;
53- }
54-
5521/**
5622 * Replace the template with a parsable placeholder that takes up the same
5723 * range.
@@ -72,7 +38,7 @@ export function preprocessTemplateRange(
7238 prefix = '{/*' ;
7339 suffix = '*/}' ;
7440
75- const nextToken = code . slice ( template . range . end ) . toString ( ) . match ( / \S + / ) ;
41+ const nextToken = sliceByteRange ( code , template . range . end ) . match ( / \S + / ) ;
7642
7743 if ( nextToken && ( nextToken [ 0 ] === 'as' || nextToken [ 0 ] === 'satisfies' ) ) {
7844 // Replace with parenthesized ObjectExpression
@@ -83,32 +49,38 @@ export function preprocessTemplateRange(
8349
8450 // We need to replace forward slash with _something else_, because
8551 // forward slash breaks the parsed templates.
86- const content = template . contents . replaceAll ( '/' , PLACEHOLDER ) ;
52+ const contents = template . contents . replaceAll ( '/' , PLACEHOLDER ) ;
8753
88- const tplLength = template . range . end - template . range . start ;
54+ const templateLength = template . range . end - template . range . start ;
8955 const spaces =
90- tplLength - byteLength ( content ) - prefix . length - suffix . length ;
91- const total = prefix + content + ' ' . repeat ( spaces ) + suffix ;
56+ templateLength - getBuffer ( contents ) . length - prefix . length - suffix . length ;
9257
93- return replaceRange ( code , template . range . start , template . range . end , total ) ;
58+ return replaceContents ( code , {
59+ contents : [ prefix , contents , ' ' . repeat ( spaces ) , suffix ] . join ( '' ) ,
60+ range : template . range ,
61+ } ) ;
9462}
9563
96- const p = new Preprocessor ( ) ;
97-
9864/** Pre-processes the template info, parsing the template content to Glimmer AST. */
9965export function codeToGlimmerAst ( code : string , filename : string ) : Template [ ] {
100- const rawTemplates = p . parse ( code , { filename } ) ;
101-
102- const templates : Template [ ] = rawTemplates . map ( ( r ) => ( {
103- type : r . type ,
104- range : r . range ,
105- contentRange : r . contentRange ,
106- contents : r . contents ,
107- utf16Range : {
108- start : byteToCharIndex ( code , r . range . start ) ,
109- end : byteToCharIndex ( code , r . range . end ) ,
110- } ,
111- } ) ) ;
66+ const contentTags = parse ( code , { filename } ) ;
67+
68+ const templates : Template [ ] = contentTags . map ( ( contentTag ) => {
69+ const { contentRange, contents, range, type } = contentTag ;
70+
71+ const utf16Range = {
72+ end : sliceByteRange ( code , 0 , range . end ) . length ,
73+ start : sliceByteRange ( code , 0 , range . start ) . length ,
74+ } ;
75+
76+ return {
77+ contentRange,
78+ contents,
79+ range,
80+ type,
81+ utf16Range,
82+ } ;
83+ } ) ;
11284
11385 return templates ;
11486}
@@ -131,5 +103,5 @@ export function preprocess(
131103 code = preprocessTemplateRange ( template , code ) ;
132104 }
133105
134- return { templates , code } ;
106+ return { code , templates } ;
135107}
0 commit comments