1- import type { NodePath } from '@babel/core' ;
21import { traverse } from '@babel/core' ;
3- import type {
4- BlockStatement ,
5- Node ,
6- ObjectExpression ,
7- StaticBlock ,
8- } from '@babel/types' ;
2+ import type { Node , ObjectExpression , StaticBlock } from '@babel/types' ;
93import type { Parsed as RawGlimmerTemplate } from 'content-tag' ;
104import { Preprocessor } from 'content-tag' ;
115import type { Parser } from 'prettier' ;
126import { parsers as babelParsers } from 'prettier/plugins/babel.js' ;
137
148import { PRINTER_NAME } from '../config.js' ;
159import type { Options } from '../options.js' ;
16- import type { GlimmerTemplate } from '../types/glimmer.js' ;
17- import { isDefaultTemplate } from '../types/glimmer.js' ;
1810import { assert } from '../utils/index.js' ;
1911import { preprocessTemplateRange } from './preprocess.js' ;
2012
@@ -23,60 +15,53 @@ const p = new Preprocessor();
2315
2416/** Converts a node into a GlimmerTemplate node */
2517function convertNode (
26- path : NodePath ,
27- node : BlockStatement | ObjectExpression | StaticBlock ,
18+ node : ObjectExpression | StaticBlock ,
2819 rawTemplate : RawGlimmerTemplate ,
2920) : void {
30- const cast = node as unknown as GlimmerTemplate ;
31- // HACK: Changing the node type here isn't recommended by babel
32- cast . type = 'FunctionDeclaration' ;
33- cast . range = [ rawTemplate . range . start , rawTemplate . range . end ] ;
34- cast . start = rawTemplate . range . start ;
35- cast . end = rawTemplate . range . end ;
36- cast . extra = Object . assign ( node . extra ?? { } , {
21+ node . extra = Object . assign ( node . extra ?? { } , {
3722 isGlimmerTemplate : true as const ,
38- isDefaultTemplate : isDefaultTemplate ( path ) ,
3923 template : rawTemplate ,
4024 } ) ;
4125}
4226
4327/** Traverses the AST and replaces the transformed template parts with other AST */
4428function convertAst ( ast : Node , rawTemplates : RawGlimmerTemplate [ ] ) : void {
45- let counter = 0 ;
29+ const unprocessedTemplates = [ ... rawTemplates ] ;
4630
4731 traverse ( ast , {
4832 enter ( path ) {
4933 const { node } = path ;
50- if (
51- node . type === 'ObjectExpression' ||
52- node . type === 'BlockStatement' ||
53- node . type === 'StaticBlock'
54- ) {
34+ if ( node . type === 'ObjectExpression' || node . type === 'StaticBlock' ) {
5535 const { range } = node ;
5636 assert ( 'expected range' , range ) ;
5737 const [ start , end ] = range ;
5838
59- const rawTemplate = rawTemplates . find (
39+ const templateIndex = unprocessedTemplates . findIndex (
6040 ( t ) =>
61- ( t . range . start === start && t . range . end === end ) ||
62- ( t . range . start === start - 1 && t . range . end === end + 1 ) ||
63- ( t . range . start === start && t . range . end === end + 1 ) ,
41+ ( node . type === 'StaticBlock' &&
42+ t . range . start === start &&
43+ t . range . end === end ) ||
44+ ( node . type === 'ObjectExpression' &&
45+ t . range . start === start - 1 &&
46+ t . range . end === end + 1 ) ,
6447 ) ;
48+ const rawTemplate = unprocessedTemplates . splice ( templateIndex , 1 ) [ 0 ] ;
6549
6650 if ( ! rawTemplate ) {
6751 return null ;
6852 }
6953
70- convertNode ( path , node , rawTemplate ) ;
71-
72- counter ++ ;
54+ convertNode ( node , rawTemplate ) ;
7355 }
56+
7457 return null ;
7558 } ,
7659 } ) ;
7760
78- if ( counter !== rawTemplates . length ) {
79- throw new Error ( 'failed to process all templates' ) ;
61+ if ( unprocessedTemplates . length > 0 ) {
62+ throw new Error (
63+ `failed to process all templates, ${ unprocessedTemplates . length } remaining` ,
64+ ) ;
8065 }
8166}
8267
@@ -85,26 +70,28 @@ function convertAst(ast: Node, rawTemplates: RawGlimmerTemplate[]): void {
8570 * fixing the offsets and locations of all nodes also calculates the block
8671 * params locations & ranges and adding it to the info
8772 */
88- function preprocess ( code : string ) : {
73+ function preprocess (
74+ code : string ,
75+ fileName : string ,
76+ ) : {
8977 code : string ;
9078 rawTemplates : RawGlimmerTemplate [ ] ;
9179} {
92- const rawTemplates = p . parse ( code ) ;
80+ const rawTemplates = p . parse ( code , fileName ) ;
9381
94- let output = code ;
9582 for ( const rawTemplate of rawTemplates ) {
96- output = preprocessTemplateRange ( rawTemplate , code , output ) ;
83+ code = preprocessTemplateRange ( rawTemplate , code ) ;
9784 }
9885
99- return { rawTemplates, code : output } ;
86+ return { rawTemplates, code } ;
10087}
10188
10289export const parser : Parser < Node | undefined > = {
10390 ...typescript ,
10491 astFormat : PRINTER_NAME ,
10592
10693 async parse ( code : string , options : Options ) : Promise < Node > {
107- const preprocessed = preprocess ( code ) ;
94+ const preprocessed = preprocess ( code , options . filepath ) ;
10895 const ast = await typescript . parse ( preprocessed . code , options ) ;
10996 assert ( 'expected ast' , ast ) ;
11097 convertAst ( ast , preprocessed . rawTemplates ) ;
0 commit comments