@@ -6,21 +6,15 @@ import type {
66 ObjectExpression ,
77 StaticBlock ,
88} from '@babel/types' ;
9- import { Preprocessor } from 'content-tag' ;
109import type { Parser } from 'prettier' ;
1110import { parsers as babelParsers } from 'prettier/plugins/babel.js' ;
1211
1312import { PRINTER_NAME } from '../config.js' ;
1413import type { Options } from '../options.js' ;
15- import { assert } from '../utils/index.js' ;
16- import {
17- byteToCharIndex ,
18- preprocessTemplateRange ,
19- type Template ,
20- } from './preprocess.js' ;
14+ import { assert } from '../utils/assert.js' ;
15+ import { preprocess , type Template } from './preprocess.js' ;
2116
2217const typescript = babelParsers [ 'babel-ts' ] as Parser < Node | undefined > ;
23- const p = new Preprocessor ( ) ;
2418
2519/** Converts a node into a GlimmerTemplate node */
2620function convertNode (
@@ -36,104 +30,78 @@ function convertNode(
3630
3731/** Traverses the AST and replaces the transformed template parts with other AST */
3832function convertAst ( ast : File , templates : Template [ ] ) : void {
39- const unprocessedTemplates = [ ...templates ] ;
40-
4133 traverse ( ast , {
4234 enter ( path ) {
4335 const { node } = path ;
44- if (
45- node . type === 'BlockStatement' ||
46- node . type === 'ObjectExpression' ||
47- node . type === 'StaticBlock'
48- ) {
49- const { range } = node ;
50- assert ( 'expected range' , range ) ;
51- const [ start , end ] = range ;
52-
53- const templateIndex = unprocessedTemplates . findIndex (
54- ( t ) =>
55- ( t . utf16Range . start === start && t . utf16Range . end === end ) ||
56- ( node . type === 'ObjectExpression' &&
57- t . utf16Range . start === start - 1 &&
58- t . utf16Range . end === end + 1 ) ,
59- ) ;
60- if ( templateIndex > - 1 ) {
61- const rawTemplate = unprocessedTemplates . splice ( templateIndex , 1 ) [ 0 ] ;
36+
37+ // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
38+ switch ( node . type ) {
39+ case 'BlockStatement' :
40+ case 'ObjectExpression' :
41+ case 'StaticBlock' : {
42+ assert ( 'expected range' , node . range ) ;
43+ const [ start , end ] = node . range ;
44+
45+ const templateIndex = templates . findIndex ( ( template ) => {
46+ const { utf16Range } = template ;
47+
48+ if ( utf16Range . start === start && utf16Range . end === end ) {
49+ return true ;
50+ }
51+
52+ return (
53+ node . type === 'ObjectExpression' &&
54+ utf16Range . start === start - 1 &&
55+ utf16Range . end === end + 1
56+ ) ;
57+ } ) ;
58+
59+ if ( templateIndex === - 1 ) {
60+ return null ;
61+ }
62+
63+ const rawTemplate = templates . splice ( templateIndex , 1 ) [ 0 ] ;
64+
6265 if ( ! rawTemplate ) {
6366 throw new Error (
6467 'expected raw template because splice index came from findIndex' ,
6568 ) ;
6669 }
70+
6771 const index =
6872 node . innerComments ?. [ 0 ] &&
6973 ast . comments ?. indexOf ( node . innerComments [ 0 ] ) ;
74+
7075 if ( ast . comments && index !== undefined && index >= 0 ) {
7176 ast . comments . splice ( index , 1 ) ;
7277 }
78+
7379 convertNode ( node , rawTemplate ) ;
74- } else {
75- return null ;
7680 }
7781 }
7882
7983 return null ;
8084 } ,
8185 } ) ;
8286
83- if ( unprocessedTemplates . length > 0 ) {
87+ if ( templates . length > 0 ) {
8488 throw new Error (
85- `failed to process all templates, ${ unprocessedTemplates . length } remaining` ,
89+ `failed to process all templates, ${ templates . length } remaining` ,
8690 ) ;
8791 }
8892}
8993
90- /**
91- * Pre-processes the template info, parsing the template content to Glimmer AST,
92- * fixing the offsets and locations of all nodes also calculates the block
93- * params locations & ranges and adding it to the info
94- */
95- export function preprocess (
96- code : string ,
97- fileName : string ,
98- ) : {
99- code : string ;
100- templates : Template [ ] ;
101- } {
102- const templates = codeToGlimmerAst ( code , fileName ) ;
103-
104- for ( const template of templates ) {
105- code = preprocessTemplateRange ( template , code ) ;
106- }
107-
108- return { templates, code } ;
109- }
110-
11194export const parser : Parser < Node | undefined > = {
11295 ...typescript ,
11396 astFormat : PRINTER_NAME ,
11497
11598 async parse ( code : string , options : Options ) : Promise < Node > {
11699 const preprocessed = preprocess ( code , options . filepath ) ;
100+
117101 const ast = await typescript . parse ( preprocessed . code , options ) ;
118102 assert ( 'expected ast' , ast ) ;
119103 convertAst ( ast as File , preprocessed . templates ) ;
104+
120105 return ast ;
121106 } ,
122107} ;
123-
124- /** Pre-processes the template info, parsing the template content to Glimmer AST. */
125- export function codeToGlimmerAst ( code : string , filename : string ) : Template [ ] {
126- const rawTemplates = p . parse ( code , { filename } ) ;
127- const templates : Template [ ] = rawTemplates . map ( ( r ) => ( {
128- type : r . type ,
129- range : r . range ,
130- contentRange : r . contentRange ,
131- contents : r . contents ,
132- utf16Range : {
133- start : byteToCharIndex ( code , r . range . start ) ,
134- end : byteToCharIndex ( code , r . range . end ) ,
135- } ,
136- } ) ) ;
137-
138- return templates ;
139- }
0 commit comments