Skip to content

Commit

Permalink
More permissive parsing of instantiation expressions (#48659)
Browse files Browse the repository at this point in the history
* More permissive parsing of expressions with type arguments

* Add test
  • Loading branch information
ahejlsberg authored Apr 13, 2022
1 parent 988fa85 commit a027cfa
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 26 deletions.
28 changes: 2 additions & 26 deletions src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {}

12 changes: 12 additions & 0 deletions tests/baselines/reference/instantiationExpressionErrors.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ true;

const x3 = f<true>;
true;

// Parsed as instantiation expression

const x4 = f<true>
if (true) {}


//// [instantiationExpressionErrors.js]
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -101,3 +109,7 @@ declare const x3: {
(): true;
g<U>(): U;
};
declare const x4: {
(): true;
g<U>(): U;
};
Original file line number Diff line number Diff line change
Expand Up @@ -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) {}

10 changes: 10 additions & 0 deletions tests/baselines/reference/instantiationExpressionErrors.types
Original file line number Diff line number Diff line change
Expand Up @@ -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

Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,8 @@ true;

const x3 = f<true>;
true;

// Parsed as instantiation expression

const x4 = f<true>
if (true) {}

0 comments on commit a027cfa

Please sign in to comment.