Merge pull request #26653 from Kingwl/improve_type_arguments_parser_1

parse less than token rather than left shift in context of type argum…
This commit is contained in:
Ryan Cavanaugh 2019-01-23 16:21:12 -08:00 committed by GitHub
commit 2f6c65e691
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 82 additions and 3 deletions

View File

@ -1093,6 +1093,10 @@ namespace ts {
return currentToken = scanner.reScanTemplateToken();
}
function reScanLessThanToken(): SyntaxKind {
return currentToken = scanner.reScanLessThanToken();
}
function scanJsxIdentifier(): SyntaxKind {
return currentToken = scanner.scanJsxIdentifier();
}
@ -2276,7 +2280,7 @@ namespace ts {
function parseTypeReference(): TypeReferenceNode {
const node = <TypeReferenceNode>createNode(SyntaxKind.TypeReference);
node.typeName = parseEntityName(/*allowReservedWords*/ true, Diagnostics.Type_expected);
if (!scanner.hasPrecedingLineBreak() && token() === SyntaxKind.LessThanToken) {
if (!scanner.hasPrecedingLineBreak() && reScanLessThanToken() === SyntaxKind.LessThanToken) {
node.typeArguments = parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken);
}
return finishNode(node);
@ -4523,7 +4527,8 @@ namespace ts {
function parseCallExpressionRest(expression: LeftHandSideExpression): LeftHandSideExpression {
while (true) {
expression = parseMemberExpressionRest(expression);
if (token() === SyntaxKind.LessThanToken) {
// handle 'foo<<T>()'
if (token() === SyntaxKind.LessThanToken || token() === SyntaxKind.LessThanLessThanToken) {
// See if this is the start of a generic invocation. If so, consume it and
// keep checking for postfix expressions. Otherwise, it's just a '<' that's
// part of an arithmetic expression. Break out so we consume it higher in the
@ -4565,9 +4570,10 @@ namespace ts {
}
function parseTypeArgumentsInExpression() {
if (!parseOptional(SyntaxKind.LessThanToken)) {
if (reScanLessThanToken() !== SyntaxKind.LessThanToken) {
return undefined;
}
nextToken();
const typeArguments = parseDelimitedList(ParsingContext.TypeArguments, parseType);
if (!parseExpected(SyntaxKind.GreaterThanToken)) {

View File

@ -31,6 +31,7 @@ namespace ts {
scanJsxIdentifier(): SyntaxKind;
scanJsxAttributeValue(): SyntaxKind;
reScanJsxToken(): JsxTokenSyntaxKind;
reScanLessThanToken(): SyntaxKind;
scanJsxToken(): JsxTokenSyntaxKind;
scanJSDocToken(): JsDocSyntaxKind;
scan(): SyntaxKind;
@ -874,6 +875,7 @@ namespace ts {
scanJsxIdentifier,
scanJsxAttributeValue,
reScanJsxToken,
reScanLessThanToken,
scanJsxToken,
scanJSDocToken,
scan,
@ -1939,6 +1941,14 @@ namespace ts {
return token = scanJsxToken();
}
function reScanLessThanToken(): SyntaxKind {
if (token === SyntaxKind.LessThanLessThanToken) {
pos = tokenPos + 1;
return token = SyntaxKind.LessThanToken;
}
return token;
}
function scanJsxToken(): JsxTokenSyntaxKind {
startPos = tokenPos = pos;

View File

@ -3097,6 +3097,7 @@ declare namespace ts {
scanJsxIdentifier(): SyntaxKind;
scanJsxAttributeValue(): SyntaxKind;
reScanJsxToken(): JsxTokenSyntaxKind;
reScanLessThanToken(): SyntaxKind;
scanJsxToken(): JsxTokenSyntaxKind;
scanJSDocToken(): JsDocSyntaxKind;
scan(): SyntaxKind;

View File

@ -3097,6 +3097,7 @@ declare namespace ts {
scanJsxIdentifier(): SyntaxKind;
scanJsxAttributeValue(): SyntaxKind;
reScanJsxToken(): JsxTokenSyntaxKind;
reScanLessThanToken(): SyntaxKind;
scanJsxToken(): JsxTokenSyntaxKind;
scanJSDocToken(): JsDocSyntaxKind;
scan(): SyntaxKind;

View File

@ -0,0 +1,11 @@
//// [parseGenericArrowRatherThanLeftShift.ts]
type Bar = ReturnType<<T>(x: T) => number>;
declare const a: Bar;
function foo<T>(_x: T) {}
const b = foo<<T>(x: T) => number>(() => 1);
//// [parseGenericArrowRatherThanLeftShift.js]
function foo(_x) { }
var b = foo(function () { return 1; });

View File

@ -0,0 +1,25 @@
=== tests/cases/compiler/parseGenericArrowRatherThanLeftShift.ts ===
type Bar = ReturnType<<T>(x: T) => number>;
>Bar : Symbol(Bar, Decl(parseGenericArrowRatherThanLeftShift.ts, 0, 0))
>ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --))
>T : Symbol(T, Decl(parseGenericArrowRatherThanLeftShift.ts, 0, 23))
>x : Symbol(x, Decl(parseGenericArrowRatherThanLeftShift.ts, 0, 26))
>T : Symbol(T, Decl(parseGenericArrowRatherThanLeftShift.ts, 0, 23))
declare const a: Bar;
>a : Symbol(a, Decl(parseGenericArrowRatherThanLeftShift.ts, 1, 13))
>Bar : Symbol(Bar, Decl(parseGenericArrowRatherThanLeftShift.ts, 0, 0))
function foo<T>(_x: T) {}
>foo : Symbol(foo, Decl(parseGenericArrowRatherThanLeftShift.ts, 1, 21))
>T : Symbol(T, Decl(parseGenericArrowRatherThanLeftShift.ts, 3, 13))
>_x : Symbol(_x, Decl(parseGenericArrowRatherThanLeftShift.ts, 3, 16))
>T : Symbol(T, Decl(parseGenericArrowRatherThanLeftShift.ts, 3, 13))
const b = foo<<T>(x: T) => number>(() => 1);
>b : Symbol(b, Decl(parseGenericArrowRatherThanLeftShift.ts, 4, 5))
>foo : Symbol(foo, Decl(parseGenericArrowRatherThanLeftShift.ts, 1, 21))
>T : Symbol(T, Decl(parseGenericArrowRatherThanLeftShift.ts, 4, 15))
>x : Symbol(x, Decl(parseGenericArrowRatherThanLeftShift.ts, 4, 18))
>T : Symbol(T, Decl(parseGenericArrowRatherThanLeftShift.ts, 4, 15))

View File

@ -0,0 +1,20 @@
=== tests/cases/compiler/parseGenericArrowRatherThanLeftShift.ts ===
type Bar = ReturnType<<T>(x: T) => number>;
>Bar : number
>x : T
declare const a: Bar;
>a : number
function foo<T>(_x: T) {}
>foo : <T>(_x: T) => void
>_x : T
const b = foo<<T>(x: T) => number>(() => 1);
>b : void
>foo<<T>(x: T) => number>(() => 1) : void
>foo : <T>(_x: T) => void
>x : T
>() => 1 : () => number
>1 : 1

View File

@ -0,0 +1,5 @@
type Bar = ReturnType<<T>(x: T) => number>;
declare const a: Bar;
function foo<T>(_x: T) {}
const b = foo<<T>(x: T) => number>(() => 1);