@@ -223,6 +223,7 @@ namespace ts {
223
223
visitNodes ( cbNode , cbNodes , ( < CallExpression > node ) . arguments ) ;
224
224
case SyntaxKind . TaggedTemplateExpression :
225
225
return visitNode ( cbNode , ( < TaggedTemplateExpression > node ) . tag ) ||
226
+ visitNodes ( cbNode , cbNodes , ( < TaggedTemplateExpression > node ) . typeArguments ) ||
226
227
visitNode ( cbNode , ( < TaggedTemplateExpression > node ) . template ) ;
227
228
case SyntaxKind . TypeAssertionExpression :
228
229
return visitNode ( cbNode , ( < TypeAssertion > node ) . type ) ||
@@ -4362,20 +4363,29 @@ namespace ts {
4362
4363
continue ;
4363
4364
}
4364
4365
4365
- if ( token ( ) === SyntaxKind . NoSubstitutionTemplateLiteral || token ( ) === SyntaxKind . TemplateHead ) {
4366
- const tagExpression = < TaggedTemplateExpression > createNode ( SyntaxKind . TaggedTemplateExpression , expression . pos ) ;
4367
- tagExpression . tag = expression ;
4368
- tagExpression . template = token ( ) === SyntaxKind . NoSubstitutionTemplateLiteral
4369
- ? < NoSubstitutionTemplateLiteral > parseLiteralNode ( )
4370
- : parseTemplateExpression ( ) ;
4371
- expression = finishNode ( tagExpression ) ;
4366
+ if ( isTemplateStartOfTaggedTemplate ( ) ) {
4367
+ expression = parseTaggedTemplateRest ( expression , /*typeArguments*/ undefined ) ;
4372
4368
continue ;
4373
4369
}
4374
4370
4375
4371
return < MemberExpression > expression ;
4376
4372
}
4377
4373
}
4378
4374
4375
+ function isTemplateStartOfTaggedTemplate ( ) {
4376
+ return token ( ) === SyntaxKind . NoSubstitutionTemplateLiteral || token ( ) === SyntaxKind . TemplateHead ;
4377
+ }
4378
+
4379
+ function parseTaggedTemplateRest ( tag : LeftHandSideExpression , typeArguments : NodeArray < TypeNode > | undefined ) {
4380
+ const tagExpression = < TaggedTemplateExpression > createNode ( SyntaxKind . TaggedTemplateExpression , tag . pos ) ;
4381
+ tagExpression . tag = tag ;
4382
+ tagExpression . typeArguments = typeArguments ;
4383
+ tagExpression . template = token ( ) === SyntaxKind . NoSubstitutionTemplateLiteral
4384
+ ? < NoSubstitutionTemplateLiteral > parseLiteralNode ( )
4385
+ : parseTemplateExpression ( ) ;
4386
+ return finishNode ( tagExpression ) ;
4387
+ }
4388
+
4379
4389
function parseCallExpressionRest ( expression : LeftHandSideExpression ) : LeftHandSideExpression {
4380
4390
while ( true ) {
4381
4391
expression = parseMemberExpressionRest ( expression ) ;
@@ -4389,6 +4399,11 @@ namespace ts {
4389
4399
return expression ;
4390
4400
}
4391
4401
4402
+ if ( isTemplateStartOfTaggedTemplate ( ) ) {
4403
+ expression = parseTaggedTemplateRest ( expression , typeArguments ) ;
4404
+ continue ;
4405
+ }
4406
+
4392
4407
const callExpr = < CallExpression > createNode ( SyntaxKind . CallExpression , expression . pos ) ;
4393
4408
callExpr . expression = expression ;
4394
4409
callExpr . typeArguments = typeArguments ;
@@ -4436,8 +4451,10 @@ namespace ts {
4436
4451
function canFollowTypeArgumentsInExpression ( ) : boolean {
4437
4452
switch ( token ( ) ) {
4438
4453
case SyntaxKind . OpenParenToken : // foo<x>(
4439
- // this case are the only case where this token can legally follow a type argument
4440
- // list. So we definitely want to treat this as a type arg list.
4454
+ case SyntaxKind . NoSubstitutionTemplateLiteral : // foo<T> `...`
4455
+ case SyntaxKind . TemplateHead : // foo<T> `...${100}...`
4456
+ // these are the only tokens can legally follow a type argument
4457
+ // list. So we definitely want to treat them as type arg lists.
4441
4458
4442
4459
case SyntaxKind . DotToken : // foo<x>.
4443
4460
case SyntaxKind . CloseParenToken : // foo<x>)
@@ -4666,9 +4683,23 @@ namespace ts {
4666
4683
return finishNode ( node ) ;
4667
4684
}
4668
4685
4686
+ let expression : MemberExpression = parsePrimaryExpression ( ) ;
4687
+ let typeArguments ;
4688
+ while ( true ) {
4689
+ expression = parseMemberExpressionRest ( expression ) ;
4690
+ typeArguments = tryParse ( parseTypeArgumentsInExpression ) ;
4691
+ if ( isTemplateStartOfTaggedTemplate ( ) ) {
4692
+ Debug . assert ( ! ! typeArguments ,
4693
+ "Expected a type argument list; all plain tagged template starts should be consumed in 'parseMemberExpressionRest'" ) ;
4694
+ expression = parseTaggedTemplateRest ( expression , typeArguments ) ;
4695
+ typeArguments = undefined ;
4696
+ }
4697
+ break ;
4698
+ }
4699
+
4669
4700
const node = < NewExpression > createNode ( SyntaxKind . NewExpression , fullStart ) ;
4670
- node . expression = parseMemberExpressionOrHigher ( ) ;
4671
- node . typeArguments = tryParse ( parseTypeArgumentsInExpression ) ;
4701
+ node . expression = expression ;
4702
+ node . typeArguments = typeArguments ;
4672
4703
if ( node . typeArguments || token ( ) === SyntaxKind . OpenParenToken ) {
4673
4704
node . arguments = parseArgumentList ( ) ;
4674
4705
}
0 commit comments