@@ -34,6 +34,11 @@ function isImplicitThis(node: angular.AST, text: string): boolean {
3434 return start >= end || / ^ \s + $ / . test ( text . slice ( start , end ) ) ;
3535}
3636
37+ type NodeTransformOptions = {
38+ isInParentParens ?: boolean ;
39+ parent ?: angular . AST ;
40+ } ;
41+
3742class Transformer extends Source {
3843 #node;
3944 #text;
@@ -105,12 +110,19 @@ class Transformer extends Source {
105110 ) ;
106111 }
107112
108- #transform< T extends NGNode > ( node : angular . AST , isInParentParens = false ) {
109- return this . #transformNode( node , isInParentParens ) as T &
110- LocationInformation ;
113+ #transform< T extends NGNode > (
114+ node : angular . AST ,
115+ options ?: NodeTransformOptions ,
116+ ) {
117+ return this . #transformNode( node , options ) as T & LocationInformation ;
111118 }
112119
113- #transformNode( node : angular . AST , isInParentParens = false ) : NGNode {
120+ #transformNode( node : angular . AST , options ?: NodeTransformOptions ) : NGNode {
121+ const { isInParentParens } = {
122+ isInParentParens : false ,
123+ ...options ,
124+ } ;
125+
114126 if ( node instanceof angular . Interpolation ) {
115127 const { expressions } = node ;
116128
@@ -374,7 +386,11 @@ class Transformer extends Source {
374386 const { receiver, args } = node ;
375387 const tArgs =
376388 args . length === 1
377- ? [ this . #transform< babel . Expression > ( args [ 0 ] , true ) ]
389+ ? [
390+ this . #transform< babel . Expression > ( args [ 0 ] , {
391+ isInParentParens : true ,
392+ } ) ,
393+ ]
378394 : ( args as angular . AST [ ] ) . map < babel . Expression > ( ( node ) =>
379395 this . #transform( node ) ,
380396 ) ;
@@ -523,6 +539,55 @@ class Transformer extends Source {
523539 ) ;
524540 }
525541
542+ if ( node instanceof angular . TemplateLiteral ) {
543+ const { elements, expressions } = node ;
544+
545+ return this . #create< babel . TemplateLiteral > ( {
546+ type : 'TemplateLiteral' ,
547+ quasis : elements . map ( ( element ) =>
548+ this . #transform( element , { parent : node } ) ,
549+ ) ,
550+ expressions : expressions . map ( ( expression ) =>
551+ this . #transform( expression ) ,
552+ ) ,
553+ ...node . sourceSpan ,
554+ } ) ;
555+ }
556+
557+ if ( node instanceof angular . TemplateLiteralElement ) {
558+ const templateLiteral = options ! . parent ! as angular . TemplateLiteral ;
559+ const elementIndex = templateLiteral . elements . indexOf ( node ) ;
560+ const isFirst = elementIndex === 0 ;
561+ const isLast = elementIndex === templateLiteral . elements . length - 1 ;
562+
563+ // The `TemplateLiteralElement` don't have correct location information
564+ const start = isFirst
565+ ? templateLiteral . sourceSpan . start + 1
566+ : node . sourceSpan . start ;
567+ let end ;
568+ if ( isLast ) {
569+ end = templateLiteral . sourceSpan . end - 1 ;
570+ } else {
571+ const nextExpression = templateLiteral . expressions [ elementIndex ] ;
572+ end = this . getCharacterLastIndex ( '$' , nextExpression . sourceSpan . start ) ;
573+ }
574+ const raw = this . text . slice ( start , end ) ;
575+
576+ return this . #create< babel . TemplateElement > (
577+ {
578+ type : 'TemplateElement' ,
579+ value : {
580+ cooked : node . text ,
581+ raw,
582+ } ,
583+ start : start ,
584+ end : end ,
585+ tail : isLast ,
586+ } ,
587+ { stripSpaces : false } ,
588+ ) ;
589+ }
590+
526591 // istanbul ignore next
527592 throw Object . assign ( new Error ( 'Unexpected node' ) , { node } ) ;
528593 }
0 commit comments