More permissive parsing of instantiation expressions (#48659)

* More permissive parsing of expressions with type arguments

* Add test
This commit is contained in:
Anders Hejlsberg 2022-04-13 06:16:43 -07:00 committed by GitHub
parent 988fa85f88
commit a027cfa8ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 42 additions and 26 deletions

View File

@ -5735,34 +5735,10 @@ namespace ts {
case SyntaxKind.OpenParenToken: // foo<x>(
case SyntaxKind.NoSubstitutionTemplateLiteral: // foo<T> `...`
case SyntaxKind.TemplateHead: // foo<T> `...${100}...`
// These tokens can't follow in a call expression, nor can they start an
// expression. So, consider the type argument list part of an instantiation
// expression.
// falls through
case SyntaxKind.CommaToken: // foo<x>,
case SyntaxKind.DotToken: // foo<x>.
case SyntaxKind.QuestionDotToken: // foo<x>?.
case SyntaxKind.CloseParenToken: // foo<x>)
case SyntaxKind.CloseBracketToken: // foo<x>]
case SyntaxKind.ColonToken: // foo<x>:
case SyntaxKind.SemicolonToken: // foo<x>;
case SyntaxKind.QuestionToken: // foo<x>?
case SyntaxKind.EqualsEqualsToken: // foo<x> ==
case SyntaxKind.EqualsEqualsEqualsToken: // foo<x> ===
case SyntaxKind.ExclamationEqualsToken: // foo<x> !=
case SyntaxKind.ExclamationEqualsEqualsToken: // foo<x> !==
case SyntaxKind.AmpersandAmpersandToken: // foo<x> &&
case SyntaxKind.BarBarToken: // foo<x> ||
case SyntaxKind.QuestionQuestionToken: // foo<x> ??
case SyntaxKind.CaretToken: // foo<x> ^
case SyntaxKind.AmpersandToken: // foo<x> &
case SyntaxKind.BarToken: // foo<x> |
case SyntaxKind.CloseBraceToken: // foo<x> }
case SyntaxKind.EndOfFileToken: // foo<x>
return true;
}
// Treat anything else as an expression.
return false;
// Consider something a type argument list only if the following token can't start an expression.
return !isStartOfExpression();
}
function parsePrimaryExpression(): PrimaryExpression {

View File

@ -72,4 +72,9 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpr
const x3 = f<true>;
true;
// Parsed as instantiation expression
const x4 = f<true>
if (true) {}

View File

@ -40,6 +40,11 @@ true;
const x3 = f<true>;
true;
// Parsed as instantiation expression
const x4 = f<true>
if (true) {}
//// [instantiationExpressionErrors.js]
@ -70,6 +75,9 @@ var x2 = f < true >
// Parsed as instantiation expression
var x3 = (f);
true;
// Parsed as instantiation expression
var x4 = (f);
if (true) { }
//// [instantiationExpressionErrors.d.ts]
@ -101,3 +109,7 @@ declare const x3: {
(): true;
g<U>(): U;
};
declare const x4: {
(): true;
g<U>(): U;
};

View File

@ -99,3 +99,11 @@ const x3 = f<true>;
true;
// Parsed as instantiation expression
const x4 = f<true>
>x4 : Symbol(x4, Decl(instantiationExpressionErrors.ts, 44, 5))
>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11))
if (true) {}

View File

@ -122,3 +122,13 @@ const x3 = f<true>;
true;
>true : true
// Parsed as instantiation expression
const x4 = f<true>
>x4 : { (): true; g<U>(): U; }
>f : { <T>(): T; g<U>(): U; }
>true : true
if (true) {}
>true : true

View File

@ -42,3 +42,8 @@ true;
const x3 = f<true>;
true;
// Parsed as instantiation expression
const x4 = f<true>
if (true) {}