@@ -25,15 +25,19 @@ function isOptionalObjectOrCallee(node: NGNode): boolean {
2525 ) ;
2626}
2727
28- class TransformerVisitor implements angular . AstVisitor {
28+ type AstVisitor = Required <
29+ Omit < angular . AstVisitor , 'visit' | 'visitASTWithSource' >
30+ > ;
31+
32+ export const transformVisitor : AstVisitor = {
2933 visitUnary ( node : angular . Unary , transformer : Transformer ) {
3034 return transformer . createNode < babel . UnaryExpression > ( {
3135 type : 'UnaryExpression' ,
3236 prefix : true ,
3337 argument : transformer . transformChild < babel . Expression > ( node . expr ) ,
3438 operator : node . operator as '-' | '+' ,
3539 } ) ;
36- }
40+ } ,
3741
3842 visitBinary ( node : angular . Binary , transformer : Transformer ) {
3943 const { operation : operator } = node ;
@@ -66,7 +70,7 @@ class TransformerVisitor implements angular.AstVisitor {
6670 type : 'BinaryExpression' ,
6771 operator : operator as babel . BinaryExpression [ 'operator' ] ,
6872 } ) ;
69- }
73+ } ,
7074
7175 visitPipe ( node : angular . BindingPipe , transformer : Transformer ) {
7276 return transformer . createNode < NGPipeExpression > ( {
@@ -78,7 +82,7 @@ class TransformerVisitor implements angular.AstVisitor {
7882 ) ,
7983 arguments : transformer . transformChildren < babel . Expression > ( node . args ) ,
8084 } ) ;
81- }
85+ } ,
8286
8387 visitChain ( node : angular . Chain , transformer : Transformer ) {
8488 return transformer . createNode < NGChainedExpression > ( {
@@ -87,7 +91,7 @@ class TransformerVisitor implements angular.AstVisitor {
8791 node . expressions ,
8892 ) ,
8993 } ) ;
90- }
94+ } ,
9195
9296 visitConditional ( node : angular . Conditional , transformer : Transformer ) {
9397 const [ test , consequent , alternate ] =
@@ -103,13 +107,13 @@ class TransformerVisitor implements angular.AstVisitor {
103107 consequent,
104108 alternate,
105109 } ) ;
106- }
110+ } ,
107111
108112 visitThisReceiver ( node : angular . ThisReceiver , transformer : Transformer ) {
109113 return transformer . createNode < babel . ThisExpression > ( {
110114 type : 'ThisExpression' ,
111115 } ) ;
112- }
116+ } ,
113117
114118 visitLiteralArray ( node : angular . LiteralArray , transformer : Transformer ) {
115119 return transformer . createNode < babel . ArrayExpression > ( {
@@ -118,7 +122,7 @@ class TransformerVisitor implements angular.AstVisitor {
118122 node . expressions ,
119123 ) ,
120124 } ) ;
121- }
125+ } ,
122126
123127 visitLiteralMap ( node : angular . LiteralMap , transformer : Transformer ) {
124128 const { keys, values } = node ;
@@ -157,7 +161,7 @@ class TransformerVisitor implements angular.AstVisitor {
157161 ) ;
158162 } ) ,
159163 } ) ;
160- }
164+ } ,
161165
162166 visitLiteralPrimitive (
163167 node : angular . LiteralPrimitive ,
@@ -195,7 +199,7 @@ class TransformerVisitor implements angular.AstVisitor {
195199 `Unexpected LiteralPrimitive value type ${ typeof value } ` ,
196200 ) ;
197201 }
198- }
202+ } ,
199203
200204 visitRegularExpressionLiteral (
201205 node : angular . RegularExpressionLiteral ,
@@ -206,14 +210,14 @@ class TransformerVisitor implements angular.AstVisitor {
206210 pattern : node . body ,
207211 flags : node . flags ?? '' ,
208212 } ) ;
209- }
213+ } ,
210214
211215 visitNonNullAssert ( node : angular . NonNullAssert , transformer : Transformer ) {
212216 return transformer . createNode < babel . TSNonNullExpression > ( {
213217 type : 'TSNonNullExpression' ,
214218 expression : transformer . transformChild < babel . Expression > ( node . expression ) ,
215219 } ) ;
216- }
220+ } ,
217221
218222 visitPrefixNot ( node : angular . PrefixNot , transformer : Transformer ) {
219223 return transformer . createNode < babel . UnaryExpression > (
@@ -225,7 +229,7 @@ class TransformerVisitor implements angular.AstVisitor {
225229 } ,
226230 node . sourceSpan ,
227231 ) ;
228- }
232+ } ,
229233
230234 visitTypeofExpression (
231235 node : angular . TypeofExpression ,
@@ -240,7 +244,7 @@ class TransformerVisitor implements angular.AstVisitor {
240244 } ,
241245 node . sourceSpan ,
242246 ) ;
243- }
247+ } ,
244248
245249 visitVoidExpression (
246250 node : angular . TypeofExpression ,
@@ -255,7 +259,7 @@ class TransformerVisitor implements angular.AstVisitor {
255259 } ,
256260 node . sourceSpan ,
257261 ) ;
258- }
262+ } ,
259263
260264 visitTaggedTemplateLiteral (
261265 node : angular . TaggedTemplateLiteral ,
@@ -266,7 +270,7 @@ class TransformerVisitor implements angular.AstVisitor {
266270 tag : transformer . transformChild < babel . Expression > ( node . tag ) ,
267271 quasi : transformer . transformChild < babel . TemplateLiteral > ( node . template ) ,
268272 } ) ;
269- }
273+ } ,
270274
271275 visitTemplateLiteral (
272276 node : angular . TemplateLiteral ,
@@ -277,7 +281,7 @@ class TransformerVisitor implements angular.AstVisitor {
277281 quasis : transformer . transformChildren ( node . elements ) ,
278282 expressions : transformer . transformChildren ( node . expressions ) ,
279283 } ) ;
280- }
284+ } ,
281285
282286 visitTemplateLiteralElement (
283287 node : angular . TemplateLiteralElement ,
@@ -301,126 +305,44 @@ class TransformerVisitor implements angular.AstVisitor {
301305 } ,
302306 [ start , end ] ,
303307 ) ;
304- }
308+ } ,
305309
306310 visitParenthesizedExpression (
307311 node : angular . ParenthesizedExpression ,
308312 transformer : Transformer ,
309313 ) {
310314 return transformer . transformChild ( node . expression ) ;
311- }
312-
313- #visitRead(
314- node :
315- | angular . KeyedRead
316- | angular . SafeKeyedRead
317- | angular . PropertyRead
318- | angular . SafePropertyRead ,
319- transformer : Transformer ,
320- ) {
321- const isComputed =
322- node instanceof angular . KeyedRead ||
323- node instanceof angular . SafeKeyedRead ;
324- const isOptional =
325- node instanceof angular . SafeKeyedRead ||
326- node instanceof angular . SafePropertyRead ;
327- const { receiver } = node ;
328- const isImplicitReceiver = receiver instanceof angular . ImplicitReceiver ;
329-
330- let property ;
331- if ( isComputed ) {
332- property = transformer . transformChild < babel . Expression > ( node . key ) ;
333- } else {
334- property = transformer . createNode < babel . Identifier > (
335- { type : 'Identifier' , name : node . name } ,
336- node . nameSpan ,
337- isImplicitReceiver ? transformer . ancestors : [ ] ,
338- ) ;
339- }
340-
341- if ( isImplicitReceiver ) {
342- return property ;
343- }
344-
345- const object = transformer . transformChild < babel . Expression > ( receiver ) ;
346- const isOptionalObject = isOptionalObjectOrCallee ( object ) ;
347-
348- if ( isOptional || isOptionalObject ) {
349- return transformer . createNode < babel . OptionalMemberExpression > ( {
350- type : 'OptionalMemberExpression' ,
351- optional : isOptional || ! isOptionalObject ,
352- computed : isComputed ,
353- property,
354- object,
355- } ) ;
356- }
357-
358- if ( isComputed ) {
359- return transformer . createNode < babel . MemberExpressionComputed > ( {
360- type : 'MemberExpression' ,
361- property,
362- object,
363- computed : true ,
364- } ) ;
365- }
366-
367- return transformer . createNode < babel . MemberExpressionNonComputed > ( {
368- type : 'MemberExpression' ,
369- object,
370- property : property as babel . MemberExpressionNonComputed [ 'property' ] ,
371- computed : false ,
372- } ) ;
373- }
315+ } ,
374316
375317 visitKeyedRead ( node : angular . KeyedRead , transformer : Transformer ) {
376- return this . #visitRead ( node , transformer ) ;
377- }
318+ return transformMemberExpression ( node , transformer , { computed : true } ) ;
319+ } ,
378320
379321 visitSafeKeyedRead ( node : angular . SafeKeyedRead , transformer : Transformer ) {
380- return this . #visitRead( node , transformer ) ;
381- }
322+ return transformMemberExpression ( node , transformer , {
323+ computed : true ,
324+ optional : true ,
325+ } ) ;
326+ } ,
382327
383328 visitPropertyRead ( node : angular . PropertyRead , transformer : Transformer ) {
384- return this . #visitRead ( node , transformer ) ;
385- }
329+ return transformMemberExpression ( node , transformer ) ;
330+ } ,
386331
387332 visitSafePropertyRead (
388333 node : angular . SafePropertyRead ,
389334 transformer : Transformer ,
390335 ) {
391- return this . #visitRead( node , transformer ) ;
392- }
393-
394- #visitCall( node : angular . Call | angular . SafeCall , transformer : Transformer ) {
395- const arguments_ = transformer . transformChildren < babel . Expression > (
396- node . args ,
397- ) ;
398- const callee = transformer . transformChild < babel . Expression > ( node . receiver ) ;
399- const isOptionalReceiver = isOptionalObjectOrCallee ( callee ) ;
400- const isOptional = node instanceof angular . SafeCall ;
401- const nodeType =
402- isOptional || isOptionalReceiver
403- ? 'OptionalCallExpression'
404- : 'CallExpression' ;
405- return transformer . createNode <
406- babel . CallExpression | babel . OptionalCallExpression
407- > ( {
408- type : nodeType ,
409- callee,
410- arguments : arguments_ ,
411- ...( nodeType === 'OptionalCallExpression'
412- ? { optional : isOptional }
413- : undefined ) ,
414- } ) ;
415- }
336+ return transformMemberExpression ( node , transformer , { optional : true } ) ;
337+ } ,
416338
417339 visitCall ( node : angular . Call , transformer : Transformer ) {
418- return this . #visitCall ( node , transformer ) ;
419- }
340+ return transformCall ( node , transformer ) ;
341+ } ,
420342
421343 visitSafeCall ( node : angular . SafeCall , transformer : Transformer ) {
422- return this . #visitCall ( node , transformer ) ;
423- }
344+ return transformCall ( node , transformer , { optional : true } ) ;
345+ } ,
424346
425347 visitInterpolation ( node : angular . Interpolation , transformer : Transformer ) {
426348 const { expressions } = node ;
@@ -431,16 +353,89 @@ class TransformerVisitor implements angular.AstVisitor {
431353 }
432354
433355 return transformer . transformChild ( expressions [ 0 ] ) ;
356+ } ,
357+
358+ visitImplicitReceiver ( ) { } ,
359+ } ;
360+
361+ function transformCall (
362+ node : angular . Call | angular . SafeCall ,
363+ transformer : Transformer ,
364+ { optional = false } = { } ,
365+ ) {
366+ const arguments_ = transformer . transformChildren < babel . Expression > ( node . args ) ;
367+ const callee = transformer . transformChild < babel . Expression > ( node . receiver ) ;
368+ const isOptionalReceiver = isOptionalObjectOrCallee ( callee ) ;
369+ const nodeType =
370+ optional || isOptionalReceiver
371+ ? 'OptionalCallExpression'
372+ : 'CallExpression' ;
373+ return transformer . createNode <
374+ babel . CallExpression | babel . OptionalCallExpression
375+ > ( {
376+ type : nodeType ,
377+ callee,
378+ arguments : arguments_ ,
379+ ...( nodeType === 'OptionalCallExpression' ? { optional } : undefined ) ,
380+ } ) ;
381+ }
382+
383+ function transformMemberExpression (
384+ node :
385+ | angular . KeyedRead
386+ | angular . SafeKeyedRead
387+ | angular . PropertyRead
388+ | angular . SafePropertyRead ,
389+ transformer : Transformer ,
390+ ) {
391+ const { receiver } = node ;
392+ const object = transformer . transformChild < babel . Expression > ( receiver ) ;
393+ const computed =
394+ node instanceof angular . KeyedRead || node instanceof angular . SafeKeyedRead ;
395+ const optional =
396+ node instanceof angular . SafeKeyedRead ||
397+ node instanceof angular . SafePropertyRead ;
398+
399+ let property ;
400+ if ( computed ) {
401+ property = transformer . transformChild < babel . Expression > ( node . key ) ;
402+ } else {
403+ property = transformer . createNode < babel . Identifier > (
404+ { type : 'Identifier' , name : node . name } ,
405+ node . nameSpan ,
406+ object ? [ ] : transformer . ancestors ,
407+ ) ;
434408 }
435409
436- visit ( node : angular . AST , context ?: any ) { }
410+ if ( ! object ) {
411+ return property ;
412+ }
437413
438- visitASTWithSource ( node : angular . ASTWithSource , transformer : Transformer ) { }
414+ const isOptionalObject = isOptionalObjectOrCallee ( object ) ;
439415
440- visitImplicitReceiver (
441- node : angular . ImplicitReceiver ,
442- transformer : Transformer ,
443- ) { }
444- }
416+ if ( optional || isOptionalObject ) {
417+ return transformer . createNode < babel . OptionalMemberExpression > ( {
418+ type : 'OptionalMemberExpression' ,
419+ optional : optional || ! isOptionalObject ,
420+ computed,
421+ property,
422+ object,
423+ } ) ;
424+ }
425+
426+ if ( computed ) {
427+ return transformer . createNode < babel . MemberExpressionComputed > ( {
428+ type : 'MemberExpression' ,
429+ property,
430+ object,
431+ computed : true ,
432+ } ) ;
433+ }
445434
446- export const transformVisitor = new TransformerVisitor ( ) ;
435+ return transformer . createNode < babel . MemberExpressionNonComputed > ( {
436+ type : 'MemberExpression' ,
437+ object,
438+ property : property as babel . MemberExpressionNonComputed [ 'property' ] ,
439+ computed : false ,
440+ } ) ;
441+ }
0 commit comments