From ce1778d19bb8f7215ba8f62f17212031b1743196 Mon Sep 17 00:00:00 2001 From: fisker Date: Fri, 21 Nov 2025 22:57:40 +0800 Subject: [PATCH] Support regexp literal --- src/source.ts | 3 +- src/transform-node.ts | 12 +++ tests/transform.test.ts | 170 ++++++++++++++++++++-------------------- 3 files changed, 100 insertions(+), 85 deletions(-) diff --git a/src/source.ts b/src/source.ts index 6772d391..e639fc36 100644 --- a/src/source.ts +++ b/src/source.ts @@ -67,7 +67,8 @@ export class Source { switch (type) { case 'NumericLiteral': - case 'StringLiteral': { + case 'StringLiteral': + case 'RegExpLiteral': { const raw = this.text.slice(node.start, node.end); const { value } = node as unknown as | babel.NumericLiteral diff --git a/src/transform-node.ts b/src/transform-node.ts index 1251af1e..656a2807 100644 --- a/src/transform-node.ts +++ b/src/transform-node.ts @@ -384,6 +384,18 @@ class Transformer extends Source { } } + if (node instanceof angular.RegularExpressionLiteral) { + return this.#create( + { + type: 'RegExpLiteral', + pattern: node.body, + flags: node.flags ?? '', + ...node.sourceSpan, + }, + { hasParentParens: isInParentParens }, + ); + } + if (node instanceof angular.Call || node instanceof angular.SafeCall) { const isOptionalType = node instanceof angular.SafeCall; const { receiver, args } = node; diff --git a/tests/transform.test.ts b/tests/transform.test.ts index 000bc4c6..13334d56 100644 --- a/tests/transform.test.ts +++ b/tests/transform.test.ts @@ -26,90 +26,92 @@ const PARSE_METHODS = [ ] as const; describe.each` - expectedAngularType | expectedEstreeType | text | parseAction | parseBinding | parseSimpleBinding | parseInterpolationExpression - ${'Binary'} | ${'BinaryExpression'} | ${' 0 - 1 '} | ${true} | ${true} | ${true} | ${true} - ${'Binary'} | ${'BinaryExpression'} | ${' a ** b '} | ${true} | ${true} | ${true} | ${true} - ${'Binary'} | ${'BinaryExpression'} | ${' ( ( ( ( a ) ) in ( ( b ) ) ) ) '} | ${true} | ${true} | ${true} | ${true} - ${'Binary'} | ${'LogicalExpression'} | ${' a && b '} | ${true} | ${true} | ${true} | ${true} - ${'Binary'} | ${'LogicalExpression'} | ${' a ?? b '} | ${true} | ${true} | ${true} | ${true} - ${'Unary'} | ${'UnaryExpression'} | ${' - 1 '} | ${true} | ${true} | ${true} | ${true} - ${'Unary'} | ${'UnaryExpression'} | ${' + 1 '} | ${true} | ${true} | ${true} | ${true} - ${'BindingPipe'} | ${'NGPipeExpression'} | ${' a | b '} | ${false} | ${true} | ${false} | ${true} - ${'BindingPipe'} | ${'NGPipeExpression'} | ${' a | b : c '} | ${false} | ${true} | ${false} | ${true} - ${'Chain'} | ${'NGChainedExpression'} | ${' a ; b '} | ${true} | ${false} | ${false} | ${false} - ${'Conditional'} | ${'ConditionalExpression'} | ${' a ? 1 : 2 '} | ${true} | ${true} | ${true} | ${true} - ${'EmptyExpr'} | ${'NGEmptyExpression'} | ${''} | ${true} | ${true} | ${true} | ${true} - ${'Call'} | ${'CallExpression'} | ${' ( a . b ) ( 1 , 2 ) '} | ${true} | ${true} | ${true} | ${true} - ${'SafeCall'} | ${'OptionalCallExpression'} | ${' ( a . b )?.( 1 , 2 ) '} | ${true} | ${true} | ${true} | ${true} - ${'Call'} | ${'CallExpression'} | ${' ( a ) ( 1 , 2 ) '} | ${true} | ${true} | ${true} | ${true} - ${'SafeCall'} | ${'OptionalCallExpression'} | ${' ( a )?.( 1 , 2 ) '} | ${true} | ${true} | ${true} | ${true} - ${'Call'} | ${'CallExpression'} | ${' a ( 1 ) ( 2 ) '} | ${true} | ${true} | ${true} | ${true} - ${'SafeCall'} | ${'OptionalCallExpression'} | ${' a ( 1 )?.( 2 ) '} | ${true} | ${true} | ${true} | ${true} - ${'KeyedRead'} | ${'MemberExpression'} | ${' a [ b ] '} | ${true} | ${true} | ${true} | ${true} - ${'SafeKeyedRead'} | ${'OptionalMemberExpression'} | ${' a ?. [ b ] '} | ${true} | ${true} | ${true} | ${true} - ${'KeyedRead'} | ${'OptionalMemberExpression'} | ${' a ?. b [ c ] '} | ${true} | ${true} | ${true} | ${true} - ${'SafeKeyedRead'} | ${'OptionalMemberExpression'} | ${' a ?. b ?. [ c ] '} | ${true} | ${true} | ${true} | ${true} - ${'KeyedRead'} | ${'OptionalMemberExpression'} | ${' a ?. b () [ c ] '} | ${true} | ${true} | ${true} | ${true} - ${'SafeKeyedRead'} | ${'OptionalMemberExpression'} | ${' a ?. b () ?. [ c ] '} | ${true} | ${true} | ${true} | ${true} - ${'Binary'} | ${'AssignmentExpression'} | ${' a [ b ] = 1 '} | ${true} | ${true} | ${true} | ${true} - ${'ImplicitReceiver'} | ${'ThisExpression'} | ${' this '} | ${true} | ${true} | ${true} | ${true} - ${'LiteralArray'} | ${'ArrayExpression'} | ${' [ 1 ] '} | ${true} | ${true} | ${true} | ${true} - ${'LiteralMap'} | ${'ObjectExpression'} | ${' ( { "a" : 1 } )'} | ${true} | ${true} | ${true} | ${true} - ${'LiteralMap'} | ${'ObjectExpression'} | ${' ( { a : 1 } ) '} | ${true} | ${true} | ${true} | ${true} - ${'Call'} | ${'CallExpression'} | ${' f ( { a : 1 } ) '} | ${true} | ${true} | ${true} | ${true} - ${'LiteralMap'} | ${'ObjectExpression'} | ${' ( {a, b: 2} ) '} | ${true} | ${true} | ${true} | ${true} - ${'Call'} | ${'CallExpression'} | ${' f ( {a, b: 2} ) '} | ${true} | ${true} | ${true} | ${true} - ${'LiteralMap'} | ${'ObjectExpression'} | ${' ( {a, b} ) '} | ${true} | ${true} | ${true} | ${true} - ${'LiteralMap'} | ${'ObjectExpression'} | ${' ( { a, b} ) '} | ${true} | ${true} | ${true} | ${true} - ${'LiteralPrimitive'} | ${'BooleanLiteral'} | ${' true '} | ${true} | ${true} | ${true} | ${true} - ${'LiteralPrimitive'} | ${'Identifier'} | ${' undefined '} | ${true} | ${true} | ${true} | ${true} - ${'LiteralPrimitive'} | ${'NullLiteral'} | ${' null '} | ${true} | ${true} | ${true} | ${true} - ${'LiteralPrimitive'} | ${'NumericLiteral'} | ${' ( 1 ) '} | ${true} | ${true} | ${true} | ${true} - ${'LiteralPrimitive'} | ${'NumericLiteral'} | ${' 1 '} | ${true} | ${true} | ${true} | ${true} - ${'LiteralPrimitive'} | ${'StringLiteral'} | ${' ( "hello" ) '} | ${true} | ${true} | ${true} | ${true} - ${'Call'} | ${'CallExpression'} | ${' a ( this ) '} | ${true} | ${true} | ${true} | ${true} - ${'SafeCall'} | ${'OptionalCallExpression'} | ${' a ?.( this ) '} | ${true} | ${true} | ${true} | ${true} - ${'Call'} | ${'CallExpression'} | ${' a ( b) '} | ${true} | ${true} | ${true} | ${true} - ${'SafeCall'} | ${'OptionalCallExpression'} | ${' a ?.( b) '} | ${true} | ${true} | ${true} | ${true} - ${'Call'} | ${'CallExpression'} | ${' a . b ( 1 , 2 ) '} | ${true} | ${true} | ${true} | ${true} - ${'SafeCall'} | ${'OptionalCallExpression'} | ${' a . b ?.( 1 , 2 ) '} | ${true} | ${true} | ${true} | ${true} - ${'Call'} | ${'CallExpression'} | ${' a ( 1 , 2 ) '} | ${true} | ${true} | ${true} | ${true} - ${'SafeCall'} | ${'OptionalCallExpression'} | ${' a ?. ( 1 , 2 ) '} | ${true} | ${true} | ${true} | ${true} - ${'Call'} | ${'OptionalCallExpression'} | ${' a ?. b . c ( ) '} | ${true} | ${true} | ${true} | ${true} - ${'SafeCall'} | ${'OptionalCallExpression'} | ${' a ?. b . c ?. ( ) '} | ${true} | ${true} | ${true} | ${true} - ${'Call'} | ${'OptionalCallExpression'} | ${' a ?. b ( ) . c ( ) '} | ${true} | ${true} | ${true} | ${true} - ${'SafeCall'} | ${'OptionalCallExpression'} | ${' a ?. b ( ) . c ?.( ) '} | ${true} | ${true} | ${true} | ${true} - ${'NonNullAssert'} | ${'TSNonNullExpression'} | ${' x ! '} | ${true} | ${true} | ${true} | ${true} - ${'PrefixNot'} | ${'UnaryExpression'} | ${' ! x '} | ${true} | ${true} | ${true} | ${true} - ${'PropertyRead'} | ${'Identifier'} | ${' ( ( a ) ) '} | ${true} | ${true} | ${true} | ${true} - ${'PropertyRead'} | ${'Identifier'} | ${' a '} | ${true} | ${true} | ${true} | ${true} - ${'PropertyRead'} | ${'Identifier'} | ${' a // hello '} | ${true} | ${true} | ${true} | ${true} - ${'PropertyRead'} | ${'MemberExpression'} | ${' a . b '} | ${true} | ${true} | ${true} | ${true} - ${'PropertyRead'} | ${'MemberExpression'} | ${' this . a '} | ${true} | ${true} | ${true} | ${true} - ${'PropertyRead'} | ${'OptionalMemberExpression'} | ${' a ?. b . c '} | ${true} | ${true} | ${true} | ${true} - ${'PropertyRead'} | ${'OptionalMemberExpression'} | ${' a ?. b ( ) . c '} | ${true} | ${true} | ${true} | ${true} - ${'PropertyRead'} | ${'OptionalMemberExpression'} | ${' foo?.bar!.bam '} | ${true} | ${true} | ${true} | ${true} - ${'PropertyRead'} | ${'MemberExpression'} | ${' (foo?.bar)!.bam '} | ${true} | ${true} | ${true} | ${true} - ${'PropertyRead'} | ${'MemberExpression'} | ${' (foo?.bar!).bam '} | ${true} | ${true} | ${true} | ${true} - ${'Binary'} | ${'AssignmentExpression'} | ${' a . b = 1 '} | ${true} | ${false} | ${false} | ${false} - ${'Binary'} | ${'AssignmentExpression'} | ${' a = 1 '} | ${true} | ${false} | ${false} | ${false} - ${'Call'} | ${'OptionalCallExpression'} | ${' a ?. b ( ) '} | ${true} | ${true} | ${true} | ${true} - ${'SafeCall'} | ${'OptionalCallExpression'} | ${' a ?. b ?. ( ) '} | ${true} | ${true} | ${true} | ${true} - ${'SafePropertyRead'} | ${'OptionalMemberExpression'} | ${' a ?. b '} | ${true} | ${true} | ${true} | ${true} - ${'TypeofExpression'} | ${'UnaryExpression'} | ${' ( ( typeof {} ) ) '} | ${true} | ${true} | ${true} | ${true} - ${'Binary'} | ${'BinaryExpression'} | ${' typeof {} === "object" '} | ${true} | ${true} | ${true} | ${true} - ${'PrefixNot'} | ${'UnaryExpression'} | ${' ! ( typeof {} === "" ) '} | ${true} | ${true} | ${true} | ${true} - ${'VoidExpression'} | ${'UnaryExpression'} | ${' ( ( void ( ( a() ) ) ) ) '} | ${true} | ${true} | ${true} | ${true} - ${'TemplateLiteral'} | ${'TemplateLiteral'} | ${' ` a ${ b } \\u0063 ` '} | ${true} | ${true} | ${true} | ${true} - ${'TemplateLiteral'} | ${'TemplateLiteral'} | ${' ( ( ` a ${ b } \\u0063 ` ) ) '} | ${true} | ${true} | ${true} | ${true} - ${'TemplateLiteral'} | ${'TemplateLiteral'} | ${' ` \\u0063 ` '} | ${true} | ${true} | ${true} | ${true} - ${'TemplateLiteral'} | ${'TemplateLiteral'} | ${' ( ( ` ` ) ) '} | ${true} | ${true} | ${true} | ${true} - ${'TemplateLiteral'} | ${'TemplateLiteral'} | ${' `` '} | ${true} | ${true} | ${true} | ${true} - ${'TaggedTemplateLiteral'} | ${'TaggedTemplateExpression'} | ${' tag ` a ${ b } \\u0063 ` '} | ${true} | ${true} | ${true} | ${true} - ${'TaggedTemplateLiteral'} | ${'TaggedTemplateExpression'} | ${' ( ( ( ( tag ) ) ` a ${ b } \\u0063 ` ) ) '} | ${true} | ${true} | ${true} | ${true} - ${'LiteralMap'} | ${'ObjectExpression'} | ${' ( ( {foo: ` a ${ b } ` } ) ) '} | ${true} | ${true} | ${true} | ${true} - ${'LiteralMap'} | ${'ObjectExpression'} | ${' ( ( {foo: tag ` a ${ b } ` } ) ) '} | ${true} | ${true} | ${true} | ${true} - ${'Binary'} | ${'AssignmentExpression'} | ${' a ??= b '} | ${true} | ${false} | ${false} | ${false} + expectedAngularType | expectedEstreeType | text | parseAction | parseBinding | parseSimpleBinding | parseInterpolationExpression + ${'Binary'} | ${'BinaryExpression'} | ${' 0 - 1 '} | ${true} | ${true} | ${true} | ${true} + ${'Binary'} | ${'BinaryExpression'} | ${' a ** b '} | ${true} | ${true} | ${true} | ${true} + ${'Binary'} | ${'BinaryExpression'} | ${' ( ( ( ( a ) ) in ( ( b ) ) ) ) '} | ${true} | ${true} | ${true} | ${true} + ${'Binary'} | ${'LogicalExpression'} | ${' a && b '} | ${true} | ${true} | ${true} | ${true} + ${'Binary'} | ${'LogicalExpression'} | ${' a ?? b '} | ${true} | ${true} | ${true} | ${true} + ${'Unary'} | ${'UnaryExpression'} | ${' - 1 '} | ${true} | ${true} | ${true} | ${true} + ${'Unary'} | ${'UnaryExpression'} | ${' + 1 '} | ${true} | ${true} | ${true} | ${true} + ${'BindingPipe'} | ${'NGPipeExpression'} | ${' a | b '} | ${false} | ${true} | ${false} | ${true} + ${'BindingPipe'} | ${'NGPipeExpression'} | ${' a | b : c '} | ${false} | ${true} | ${false} | ${true} + ${'Chain'} | ${'NGChainedExpression'} | ${' a ; b '} | ${true} | ${false} | ${false} | ${false} + ${'Conditional'} | ${'ConditionalExpression'} | ${' a ? 1 : 2 '} | ${true} | ${true} | ${true} | ${true} + ${'EmptyExpr'} | ${'NGEmptyExpression'} | ${''} | ${true} | ${true} | ${true} | ${true} + ${'Call'} | ${'CallExpression'} | ${' ( a . b ) ( 1 , 2 ) '} | ${true} | ${true} | ${true} | ${true} + ${'SafeCall'} | ${'OptionalCallExpression'} | ${' ( a . b )?.( 1 , 2 ) '} | ${true} | ${true} | ${true} | ${true} + ${'Call'} | ${'CallExpression'} | ${' ( a ) ( 1 , 2 ) '} | ${true} | ${true} | ${true} | ${true} + ${'SafeCall'} | ${'OptionalCallExpression'} | ${' ( a )?.( 1 , 2 ) '} | ${true} | ${true} | ${true} | ${true} + ${'Call'} | ${'CallExpression'} | ${' a ( 1 ) ( 2 ) '} | ${true} | ${true} | ${true} | ${true} + ${'SafeCall'} | ${'OptionalCallExpression'} | ${' a ( 1 )?.( 2 ) '} | ${true} | ${true} | ${true} | ${true} + ${'KeyedRead'} | ${'MemberExpression'} | ${' a [ b ] '} | ${true} | ${true} | ${true} | ${true} + ${'SafeKeyedRead'} | ${'OptionalMemberExpression'} | ${' a ?. [ b ] '} | ${true} | ${true} | ${true} | ${true} + ${'KeyedRead'} | ${'OptionalMemberExpression'} | ${' a ?. b [ c ] '} | ${true} | ${true} | ${true} | ${true} + ${'SafeKeyedRead'} | ${'OptionalMemberExpression'} | ${' a ?. b ?. [ c ] '} | ${true} | ${true} | ${true} | ${true} + ${'KeyedRead'} | ${'OptionalMemberExpression'} | ${' a ?. b () [ c ] '} | ${true} | ${true} | ${true} | ${true} + ${'SafeKeyedRead'} | ${'OptionalMemberExpression'} | ${' a ?. b () ?. [ c ] '} | ${true} | ${true} | ${true} | ${true} + ${'Binary'} | ${'AssignmentExpression'} | ${' a [ b ] = 1 '} | ${true} | ${true} | ${true} | ${true} + ${'ImplicitReceiver'} | ${'ThisExpression'} | ${' this '} | ${true} | ${true} | ${true} | ${true} + ${'LiteralArray'} | ${'ArrayExpression'} | ${' [ 1 ] '} | ${true} | ${true} | ${true} | ${true} + ${'LiteralMap'} | ${'ObjectExpression'} | ${' ( { "a" : 1 } )'} | ${true} | ${true} | ${true} | ${true} + ${'LiteralMap'} | ${'ObjectExpression'} | ${' ( { a : 1 } ) '} | ${true} | ${true} | ${true} | ${true} + ${'Call'} | ${'CallExpression'} | ${' f ( { a : 1 } ) '} | ${true} | ${true} | ${true} | ${true} + ${'LiteralMap'} | ${'ObjectExpression'} | ${' ( {a, b: 2} ) '} | ${true} | ${true} | ${true} | ${true} + ${'Call'} | ${'CallExpression'} | ${' f ( {a, b: 2} ) '} | ${true} | ${true} | ${true} | ${true} + ${'LiteralMap'} | ${'ObjectExpression'} | ${' ( {a, b} ) '} | ${true} | ${true} | ${true} | ${true} + ${'LiteralMap'} | ${'ObjectExpression'} | ${' ( { a, b} ) '} | ${true} | ${true} | ${true} | ${true} + ${'LiteralPrimitive'} | ${'BooleanLiteral'} | ${' true '} | ${true} | ${true} | ${true} | ${true} + ${'LiteralPrimitive'} | ${'Identifier'} | ${' undefined '} | ${true} | ${true} | ${true} | ${true} + ${'LiteralPrimitive'} | ${'NullLiteral'} | ${' null '} | ${true} | ${true} | ${true} | ${true} + ${'LiteralPrimitive'} | ${'NumericLiteral'} | ${' ( 1 ) '} | ${true} | ${true} | ${true} | ${true} + ${'LiteralPrimitive'} | ${'NumericLiteral'} | ${' 1 '} | ${true} | ${true} | ${true} | ${true} + ${'LiteralPrimitive'} | ${'StringLiteral'} | ${' ( "hello" ) '} | ${true} | ${true} | ${true} | ${true} + ${'RegularExpressionLiteral'} | ${'RegExpLiteral'} | ${' ( ( /\\d+/ ) ) '} | ${true} | ${true} | ${true} | ${true} + ${'RegularExpressionLiteral'} | ${'RegExpLiteral'} | ${' ( ( /\\d+/g ) )'} | ${true} | ${true} | ${true} | ${true} + ${'Call'} | ${'CallExpression'} | ${' a ( this ) '} | ${true} | ${true} | ${true} | ${true} + ${'SafeCall'} | ${'OptionalCallExpression'} | ${' a ?.( this ) '} | ${true} | ${true} | ${true} | ${true} + ${'Call'} | ${'CallExpression'} | ${' a ( b) '} | ${true} | ${true} | ${true} | ${true} + ${'SafeCall'} | ${'OptionalCallExpression'} | ${' a ?.( b) '} | ${true} | ${true} | ${true} | ${true} + ${'Call'} | ${'CallExpression'} | ${' a . b ( 1 , 2 ) '} | ${true} | ${true} | ${true} | ${true} + ${'SafeCall'} | ${'OptionalCallExpression'} | ${' a . b ?.( 1 , 2 ) '} | ${true} | ${true} | ${true} | ${true} + ${'Call'} | ${'CallExpression'} | ${' a ( 1 , 2 ) '} | ${true} | ${true} | ${true} | ${true} + ${'SafeCall'} | ${'OptionalCallExpression'} | ${' a ?. ( 1 , 2 ) '} | ${true} | ${true} | ${true} | ${true} + ${'Call'} | ${'OptionalCallExpression'} | ${' a ?. b . c ( ) '} | ${true} | ${true} | ${true} | ${true} + ${'SafeCall'} | ${'OptionalCallExpression'} | ${' a ?. b . c ?. ( ) '} | ${true} | ${true} | ${true} | ${true} + ${'Call'} | ${'OptionalCallExpression'} | ${' a ?. b ( ) . c ( ) '} | ${true} | ${true} | ${true} | ${true} + ${'SafeCall'} | ${'OptionalCallExpression'} | ${' a ?. b ( ) . c ?.( ) '} | ${true} | ${true} | ${true} | ${true} + ${'NonNullAssert'} | ${'TSNonNullExpression'} | ${' x ! '} | ${true} | ${true} | ${true} | ${true} + ${'PrefixNot'} | ${'UnaryExpression'} | ${' ! x '} | ${true} | ${true} | ${true} | ${true} + ${'PropertyRead'} | ${'Identifier'} | ${' ( ( a ) ) '} | ${true} | ${true} | ${true} | ${true} + ${'PropertyRead'} | ${'Identifier'} | ${' a '} | ${true} | ${true} | ${true} | ${true} + ${'PropertyRead'} | ${'Identifier'} | ${' a // hello '} | ${true} | ${true} | ${true} | ${true} + ${'PropertyRead'} | ${'MemberExpression'} | ${' a . b '} | ${true} | ${true} | ${true} | ${true} + ${'PropertyRead'} | ${'MemberExpression'} | ${' this . a '} | ${true} | ${true} | ${true} | ${true} + ${'PropertyRead'} | ${'OptionalMemberExpression'} | ${' a ?. b . c '} | ${true} | ${true} | ${true} | ${true} + ${'PropertyRead'} | ${'OptionalMemberExpression'} | ${' a ?. b ( ) . c '} | ${true} | ${true} | ${true} | ${true} + ${'PropertyRead'} | ${'OptionalMemberExpression'} | ${' foo?.bar!.bam '} | ${true} | ${true} | ${true} | ${true} + ${'PropertyRead'} | ${'MemberExpression'} | ${' (foo?.bar)!.bam '} | ${true} | ${true} | ${true} | ${true} + ${'PropertyRead'} | ${'MemberExpression'} | ${' (foo?.bar!).bam '} | ${true} | ${true} | ${true} | ${true} + ${'Binary'} | ${'AssignmentExpression'} | ${' a . b = 1 '} | ${true} | ${false} | ${false} | ${false} + ${'Binary'} | ${'AssignmentExpression'} | ${' a = 1 '} | ${true} | ${false} | ${false} | ${false} + ${'Call'} | ${'OptionalCallExpression'} | ${' a ?. b ( ) '} | ${true} | ${true} | ${true} | ${true} + ${'SafeCall'} | ${'OptionalCallExpression'} | ${' a ?. b ?. ( ) '} | ${true} | ${true} | ${true} | ${true} + ${'SafePropertyRead'} | ${'OptionalMemberExpression'} | ${' a ?. b '} | ${true} | ${true} | ${true} | ${true} + ${'TypeofExpression'} | ${'UnaryExpression'} | ${' ( ( typeof {} ) ) '} | ${true} | ${true} | ${true} | ${true} + ${'Binary'} | ${'BinaryExpression'} | ${' typeof {} === "object" '} | ${true} | ${true} | ${true} | ${true} + ${'PrefixNot'} | ${'UnaryExpression'} | ${' ! ( typeof {} === "" ) '} | ${true} | ${true} | ${true} | ${true} + ${'VoidExpression'} | ${'UnaryExpression'} | ${' ( ( void ( ( a() ) ) ) ) '} | ${true} | ${true} | ${true} | ${true} + ${'TemplateLiteral'} | ${'TemplateLiteral'} | ${' ` a ${ b } \\u0063 ` '} | ${true} | ${true} | ${true} | ${true} + ${'TemplateLiteral'} | ${'TemplateLiteral'} | ${' ( ( ` a ${ b } \\u0063 ` ) ) '} | ${true} | ${true} | ${true} | ${true} + ${'TemplateLiteral'} | ${'TemplateLiteral'} | ${' ` \\u0063 ` '} | ${true} | ${true} | ${true} | ${true} + ${'TemplateLiteral'} | ${'TemplateLiteral'} | ${' ( ( ` ` ) ) '} | ${true} | ${true} | ${true} | ${true} + ${'TemplateLiteral'} | ${'TemplateLiteral'} | ${' `` '} | ${true} | ${true} | ${true} | ${true} + ${'TaggedTemplateLiteral'} | ${'TaggedTemplateExpression'} | ${' tag ` a ${ b } \\u0063 ` '} | ${true} | ${true} | ${true} | ${true} + ${'TaggedTemplateLiteral'} | ${'TaggedTemplateExpression'} | ${' ( ( ( ( tag ) ) ` a ${ b } \\u0063 ` ) ) '} | ${true} | ${true} | ${true} | ${true} + ${'LiteralMap'} | ${'ObjectExpression'} | ${' ( ( {foo: ` a ${ b } ` } ) ) '} | ${true} | ${true} | ${true} | ${true} + ${'LiteralMap'} | ${'ObjectExpression'} | ${' ( ( {foo: tag ` a ${ b } ` } ) ) '} | ${true} | ${true} | ${true} | ${true} + ${'Binary'} | ${'AssignmentExpression'} | ${' a ??= b '} | ${true} | ${false} | ${false} | ${false} `('($expectedAngularType -> $expectedEstreeType)', (fields) => { for (const method of PARSE_METHODS) { testSection(method, fields);