1+ import type { NodePath } from '@babel/core' ;
12import { traverse } from '@babel/core' ;
23import type { Node } from '@babel/types' ;
34import {
45 isBinaryExpression ,
56 isMemberExpression ,
67 isTaggedTemplateExpression ,
78} from '@babel/types' ;
8- // @ts -expect-error FIXME: TS7016 Is this a hack? IDK!
9- import { defineAliasedType } from '@babel/types/lib/definitions/utils' ;
109import { getTemplateLocals } from '@glimmer/syntax' ;
1110import { preprocessEmbeddedTemplates } from 'ember-template-imports/lib/preprocess-embedded-templates' ;
1211import type { Parser } from 'prettier' ;
1312import { parsers as babelParsers } from 'prettier/parser-babel' ;
1413
1514import {
16- GLIMMER_EXPRESSION_TYPE ,
1715 PRINTER_NAME ,
1816 TEMPLATE_TAG_NAME ,
1917 TEMPLATE_TAG_PLACEHOLDER ,
2018} from './config' ;
2119import type { Options } from './options' ;
2220import { definePrinter } from './print/index' ;
2321import type { BaseNode } from './types/ast' ;
24- import { extractGlimmerExpression } from './types/glimmer' ;
2522import {
2623 hasGlimmerArrayExpression ,
2724 isRawGlimmerArrayExpression ,
@@ -33,11 +30,6 @@ import { assert } from './utils/index';
3330
3431const typescript = babelParsers [ 'babel-ts' ] as Parser < BaseNode > ;
3532
36- // FIXME: This is necessary for babel to not freak out with the custom type.
37- // If we keep this code long-term we should augment the babel types
38- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
39- const defineType = defineAliasedType ( 'Glimmer' ) ;
40-
4133const preprocess : Required < Parser < BaseNode > > [ 'preprocess' ] = (
4234 text ,
4335 options
@@ -73,81 +65,58 @@ export const parser: Parser<BaseNode> = {
7365 options : Options
7466 ) : BaseNode {
7567 const ast = typescript . parse ( text , parsers , options ) ;
76- // FIXME: This is necessary for babel to not freak out with the custom type.
77- // If we keep this code long-term we should augment the babel types
78- // eslint-disable-next-line @typescript-eslint/no-unsafe-call
79- defineType ( GLIMMER_EXPRESSION_TYPE , {
80- inherits : 'TemplateExpression' ,
81- aliases : [ 'Expression' ] ,
82- } ) ;
8368 traverse ( ast as Node , {
84- enter ( path ) {
85- const node = path . node ;
86- const parentNode = path . parentPath ?. node ;
87-
88- if (
89- parentNode &&
90- 'property' in parentNode &&
91- isRawGlimmerCallExpression ( parentNode . property )
92- ) {
93- throw new SyntaxError (
94- 'Ember <template> tag used as an object property.'
95- ) ;
96- } else if (
97- isBinaryExpression ( node ) &&
98- ( hasGlimmerArrayExpression ( node . left ) ||
99- hasGlimmerArrayExpression ( node . right ) )
100- ) {
101- throw new SyntaxError (
102- 'Ember <template> tag used in binary expression.'
103- ) ;
104- } else if (
105- isTaggedTemplateExpression ( node ) &&
106- hasGlimmerArrayExpression ( node . tag )
107- ) {
108- throw new SyntaxError (
109- 'Ember <template> tag used as tagged template expression.'
110- ) ;
111- } else if (
112- isMemberExpression ( node ) &&
113- hasGlimmerArrayExpression ( node . object )
114- ) {
115- throw new SyntaxError (
116- 'Ember <template> tag used as member expression.'
117- ) ;
118- }
119- } ,
120- ArrayExpression ( path ) {
121- const node = path . node ;
122- if ( isRawGlimmerArrayExpression ( node ) ) {
123- const newNode = extractGlimmerExpression (
124- node . elements [ 0 ] . arguments [ 0 ] ,
125- node ,
126- hasAmbiguousNextLine ( path , options )
127- ) ;
128- // HACK: Babel types don't allow this
129- path . replaceWith ( newNode as unknown as Node ) ;
130- }
131- } ,
132- ClassProperty ( path ) {
133- const node = path . node ;
134- if ( isRawGlimmerClassProperty ( node ) ) {
135- const newNode = extractGlimmerExpression ( node . key . arguments [ 0 ] , node ) ;
136- // HACK: Babel types don't allow this
137- path . replaceWith ( newNode as unknown as Node ) ;
138- }
139- } ,
140- CallExpression ( path ) {
141- const node = path . node ;
142- if ( isRawGlimmerCallExpression ( node ) ) {
143- throw new SyntaxError ( 'Found unhandled RawGlimmerCallExpression' ) ;
144- }
145- } ,
69+ enter : makeEnter ( options ) ,
14670 } ) ;
14771 return ast ;
14872 } ,
14973} ;
15074
75+ function makeEnter ( options : Options ) {
76+ return ( path : NodePath ) => {
77+ const node = path . node ;
78+ const parentNode = path . parentPath ?. node ;
79+
80+ if (
81+ parentNode &&
82+ 'property' in parentNode &&
83+ isRawGlimmerCallExpression ( parentNode . property )
84+ ) {
85+ throw new SyntaxError ( 'Ember <template> tag used as an object property.' ) ;
86+ } else if (
87+ isBinaryExpression ( node ) &&
88+ ( hasGlimmerArrayExpression ( node . left ) ||
89+ hasGlimmerArrayExpression ( node . right ) )
90+ ) {
91+ throw new SyntaxError ( 'Ember <template> tag used in binary expression.' ) ;
92+ } else if (
93+ isTaggedTemplateExpression ( node ) &&
94+ hasGlimmerArrayExpression ( node . tag )
95+ ) {
96+ throw new SyntaxError (
97+ 'Ember <template> tag used as tagged template expression.'
98+ ) ;
99+ } else if (
100+ isMemberExpression ( node ) &&
101+ hasGlimmerArrayExpression ( node . object )
102+ ) {
103+ throw new SyntaxError ( 'Ember <template> tag used as member expression.' ) ;
104+ }
105+
106+ if ( isRawGlimmerArrayExpression ( node ) || isRawGlimmerClassProperty ( node ) ) {
107+ const extra = {
108+ hasGlimmerExpression : true ,
109+ forceSemi : hasAmbiguousNextLine ( path , options ) ,
110+ } ;
111+ if ( typeof node . extra === 'object' ) {
112+ node . extra = { ...node . extra , ...extra } ;
113+ } else {
114+ node . extra = extra ;
115+ }
116+ }
117+ } ;
118+ }
119+
151120/**
152121 * Desugar template tag default exports because they parse as
153122 * ExpressionStatement, which has a bunch of irrelevant custom semicolon
0 commit comments