@@ -17,7 +17,71 @@ import type {
1717 RawNGSpan ,
1818} from './types.js' ;
1919import { NG_PARSE_TEMPLATE_BINDINGS_FAKE_PREFIX } from './parser.js' ;
20- import { toLowerCamelCase , transformSpan } from './utils.js' ;
20+ import { toLowerCamelCase , transformSpan , createNode } from './utils.js' ;
21+
22+ function isExpressionBinding (
23+ templateBinding : ng . TemplateBinding ,
24+ ) : templateBinding is ng . ExpressionBinding {
25+ return templateBinding instanceof NGExpressionBinding ;
26+ }
27+
28+ function isVariableBinding (
29+ templateBinding : ng . TemplateBinding ,
30+ ) : templateBinding is ng . VariableBinding {
31+ return templateBinding instanceof NGVariableBinding ;
32+ }
33+
34+ /**
35+ * - "a" (start=0 end=1) -> (start=0 end=3)
36+ * - '\'' (start=0 end=1) -> (start=0 end=4)
37+ */
38+ function fixSpan ( span : RawNGSpan , text : string ) {
39+ if ( text [ span . start ] !== '"' && text [ span . start ] !== "'" ) {
40+ return ;
41+ }
42+ const quote = text [ span . start ] ;
43+ let hasBackSlash = false ;
44+ for ( let i = span . start + 1 ; i < text . length ; i ++ ) {
45+ switch ( text [ i ] ) {
46+ case quote :
47+ if ( ! hasBackSlash ) {
48+ span . end = i + 1 ;
49+ return ;
50+ }
51+ // fall through
52+ default :
53+ hasBackSlash = false ;
54+ break ;
55+ case '\\' :
56+ hasBackSlash = ! hasBackSlash ;
57+ break ;
58+ }
59+ }
60+ }
61+
62+ /**
63+ * - "as b" (value="NgEstreeParser" key="b") -> (value="$implicit" key="b")
64+ */
65+ function getAsVariableBindingValue (
66+ variableBinding : ng . VariableBinding ,
67+ context : Context ,
68+ ) : ng . VariableBinding [ 'value' ] {
69+ if (
70+ ! variableBinding . value ||
71+ variableBinding . value . source !== NG_PARSE_TEMPLATE_BINDINGS_FAKE_PREFIX
72+ ) {
73+ return variableBinding . value ;
74+ }
75+
76+ const index = context . getCharacterIndex (
77+ / \S / ,
78+ variableBinding . sourceSpan . start ,
79+ ) ;
80+ return {
81+ source : '$implicit' ,
82+ span : { start : index , end : index } ,
83+ } ;
84+ }
2185
2286function transformTemplateBindings ( {
2387 expressions : rawTemplateBindings ,
@@ -53,11 +117,11 @@ function transformTemplateBindings({
53117 templateBinding . value &&
54118 templateBinding . value . source === lastTemplateBinding . key . source
55119 ) {
56- const alias = _c < NGMicrosyntaxKey > (
57- 'NGMicrosyntaxKey' ,
58- { name : templateBinding . key . source } ,
59- templateBinding . key . span ,
60- ) ;
120+ const alias = _c < NGMicrosyntaxKey > ( {
121+ type : 'NGMicrosyntaxKey' ,
122+ name : templateBinding . key . source ,
123+ ... templateBinding . key . span ,
124+ } ) ;
61125 const updateSpanEnd = < T extends NGNode > ( node : T , end : number ) : T => ( {
62126 ...node ,
63127 ...transformSpan ( { start : node . start ! , end } , context . text ) ,
@@ -84,13 +148,13 @@ function transformTemplateBindings({
84148 lastTemplateBinding = templateBinding ;
85149 }
86150
87- return _c < NGMicrosyntax > (
88- 'NGMicrosyntax' ,
89- { body } ,
90- body . length === 0
151+ return _c < NGMicrosyntax > ( {
152+ type : 'NGMicrosyntax' ,
153+ body,
154+ ... ( body . length === 0
91155 ? rawTemplateBindings [ 0 ] . sourceSpan
92- : { start : body [ 0 ] . start , end : body . at ( - 1 ) ! . end } ,
93- ) ;
156+ : { start : body [ 0 ] . start , end : body . at ( - 1 ) ! . end } ) ,
157+ } ) ;
94158
95159 function transformTemplateBinding (
96160 templateBinding : ng . TemplateBinding ,
@@ -99,34 +163,35 @@ function transformTemplateBindings({
99163 if ( isExpressionBinding ( templateBinding ) ) {
100164 const { key, value } = templateBinding ;
101165 if ( ! value ) {
102- return _c < NGMicrosyntaxKey > (
103- 'NGMicrosyntaxKey' ,
104- { name : removePrefix ( key . source ) } ,
105- key . span ,
106- ) ;
166+ return _c < NGMicrosyntaxKey > ( {
167+ type : 'NGMicrosyntaxKey' ,
168+ name : removePrefix ( key . source ) ,
169+ ... key . span ,
170+ } ) ;
107171 } else if ( index === 0 ) {
108- return _c < NGMicrosyntaxExpression > (
109- 'NGMicrosyntaxExpression' ,
110- { expression : _t < NGNode > ( value . ast ) , alias : null } ,
111- value . sourceSpan ,
112- ) ;
172+ return _c < NGMicrosyntaxExpression > ( {
173+ type : 'NGMicrosyntaxExpression' ,
174+ expression : _t < NGNode > ( value . ast ) ,
175+ alias : null ,
176+ ...value . sourceSpan ,
177+ } ) ;
113178 } else {
114- return _c < NGMicrosyntaxKeyedExpression > (
115- 'NGMicrosyntaxKeyedExpression' ,
116- {
117- key : _c < NGMicrosyntaxKey > (
118- 'NGMicrosyntaxKey' ,
119- { name : removePrefix ( key . source ) } ,
120- key . span ,
121- ) ,
122- expression : _c < NGMicrosyntaxExpression > (
123- 'NGMicrosyntaxExpression' ,
124- { expression : _t < NGNode > ( value . ast ) , alias : null } ,
125- value . sourceSpan ,
126- ) ,
127- } ,
128- { start : key . span . start , end : value . sourceSpan . end } ,
129- ) ;
179+ return _c < NGMicrosyntaxKeyedExpression > ( {
180+ type : 'NGMicrosyntaxKeyedExpression' ,
181+ key : _c < NGMicrosyntaxKey > ( {
182+ type : ' NGMicrosyntaxKey' ,
183+ name : removePrefix ( key . source ) ,
184+ ... key . span ,
185+ } ) ,
186+ expression : _c < NGMicrosyntaxExpression > ( {
187+ type : ' NGMicrosyntaxExpression' ,
188+ expression : _t < NGNode > ( value . ast ) ,
189+ alias : null ,
190+ ... value . sourceSpan ,
191+ } ) ,
192+ start : key . span . start ,
193+ end : value . sourceSpan . end ,
194+ } ) ;
130195 }
131196 } else {
132197 const { key, sourceSpan } = templateBinding ;
@@ -135,138 +200,64 @@ function transformTemplateBindings({
135200 ) ;
136201 if ( startsWithLet ) {
137202 const { value } = templateBinding ;
138- return _c < NGMicrosyntaxLet > (
139- 'NGMicrosyntaxLet' ,
140- {
141- key : _c < NGMicrosyntaxKey > (
142- 'NGMicrosyntaxKey' ,
143- { name : key . source } ,
144- key . span ,
145- ) ,
146- value : ! value
147- ? null
148- : _c < NGMicrosyntaxKey > (
149- 'NGMicrosyntaxKey' ,
150- { name : value . source } ,
151- value . span ,
152- ) ,
153- } ,
154- {
155- start : sourceSpan . start ,
156- end : value ? value . span . end : key . span . end ,
157- } ,
158- ) ;
203+ return _c < NGMicrosyntaxLet > ( {
204+ type : 'NGMicrosyntaxLet' ,
205+ key : _c < NGMicrosyntaxKey > ( {
206+ type : 'NGMicrosyntaxKey' ,
207+ name : key . source ,
208+ ...key . span ,
209+ } ) ,
210+ value : ! value
211+ ? null
212+ : _c < NGMicrosyntaxKey > ( {
213+ type : 'NGMicrosyntaxKey' ,
214+ name : value . source ,
215+ ...value . span ,
216+ } ) ,
217+ start : sourceSpan . start ,
218+ end : value ? value . span . end : key . span . end ,
219+ } ) ;
159220 } else {
160- const value = getAsVariableBindingValue ( templateBinding ) ;
161- return _c < NGMicrosyntaxAs > (
162- 'NGMicrosyntaxAs' ,
163- {
164- key : _c < NGMicrosyntaxKey > (
165- 'NGMicrosyntaxKey' ,
166- { name : value ! . source } ,
167- value ! . span ,
168- ) ,
169- alias : _c < NGMicrosyntaxKey > (
170- 'NGMicrosyntaxKey' ,
171- { name : key . source } ,
172- key . span ,
173- ) ,
174- } ,
175- { start : value ! . span . start , end : key . span . end } ,
176- ) ;
221+ const value = getAsVariableBindingValue ( templateBinding , context ) ;
222+ return _c < NGMicrosyntaxAs > ( {
223+ type : 'NGMicrosyntaxAs' ,
224+ key : _c < NGMicrosyntaxKey > ( {
225+ type : 'NGMicrosyntaxKey' ,
226+ name : value ! . source ,
227+ ...value ! . span ,
228+ } ) ,
229+ alias : _c < NGMicrosyntaxKey > ( {
230+ type : 'NGMicrosyntaxKey' ,
231+ name : key . source ,
232+ ...key . span ,
233+ } ) ,
234+ start : value ! . span . start ,
235+ end : key . span . end ,
236+ } ) ;
177237 }
178238 }
179239 }
180240
181- function _t < T extends NGNode > ( n : ng . AST ) {
182- return transformNode ( n , context ) as T ;
241+ function _t < T extends NGNode > ( node : ng . AST ) {
242+ return transformNode ( node , context ) as T ;
183243 }
184244
185245 function _c < T extends NGNode > (
186- t : T [ 'type' ] ,
187- n : Partial < T > ,
188- span : RawNGSpan ,
189- stripSpaces = true ,
246+ properties : Partial < T > & { type : T [ 'type' ] } & RawNGSpan ,
247+ { stripSpaces = true } = { } ,
190248 ) {
191- return {
192- type : t ,
193- ...transformSpan ( span , context . text , { processSpan : stripSpaces } ) ,
194- ...n ,
195- } as T ;
249+ return createNode < T > ( context , properties , { stripSpaces } ) ;
196250 }
197251
198252 function removePrefix ( string : string ) {
199253 return toLowerCamelCase ( string . slice ( prefix . source . length ) ) ;
200254 }
201255
202- function isExpressionBinding (
203- templateBinding : ng . TemplateBinding ,
204- ) : templateBinding is ng . ExpressionBinding {
205- return templateBinding instanceof NGExpressionBinding ;
206- }
207-
208- function isVariableBinding (
209- templateBinding : ng . TemplateBinding ,
210- ) : templateBinding is ng . VariableBinding {
211- return templateBinding instanceof NGVariableBinding ;
212- }
213-
214256 function fixTemplateBindingSpan ( templateBinding : ng . TemplateBinding ) {
215- fixSpan ( templateBinding . key . span ) ;
257+ fixSpan ( templateBinding . key . span , context . text ) ;
216258 if ( isVariableBinding ( templateBinding ) && templateBinding . value ) {
217- fixSpan ( templateBinding . value . span ) ;
218- }
219- }
220-
221- /**
222- * - "a" (start=0 end=1) -> (start=0 end=3)
223- * - '\'' (start=0 end=1) -> (start=0 end=4)
224- */
225- function fixSpan ( span : RawNGSpan ) {
226- if ( context . text [ span . start ] !== '"' && context . text [ span . start ] !== "'" ) {
227- return ;
259+ fixSpan ( templateBinding . value . span , context . text ) ;
228260 }
229- const quote = context . text [ span . start ] ;
230- let hasBackSlash = false ;
231- for ( let i = span . start + 1 ; i < context . text . length ; i ++ ) {
232- switch ( context . text [ i ] ) {
233- case quote :
234- if ( ! hasBackSlash ) {
235- span . end = i + 1 ;
236- return ;
237- }
238- // fall through
239- default :
240- hasBackSlash = false ;
241- break ;
242- case '\\' :
243- hasBackSlash = ! hasBackSlash ;
244- break ;
245- }
246- }
247- }
248-
249- /**
250- * - "as b" (value="NgEstreeParser" key="b") -> (value="$implicit" key="b")
251- */
252- function getAsVariableBindingValue (
253- variableBinding : ng . VariableBinding ,
254- ) : ng . VariableBinding [ 'value' ] {
255- if (
256- ! variableBinding . value ||
257- variableBinding . value . source !== NG_PARSE_TEMPLATE_BINDINGS_FAKE_PREFIX
258- ) {
259- return variableBinding . value ;
260- }
261-
262- const index = context . getCharacterIndex (
263- / \S / ,
264- variableBinding . sourceSpan . start ,
265- ) ;
266- return {
267- source : '$implicit' ,
268- span : { start : index , end : index } ,
269- } ;
270261 }
271262}
272263
0 commit comments