diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index a76f9eb59b..4b0c0010de 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1093,8 +1093,8 @@ namespace ts { return currentToken = scanner.reScanTemplateToken(); } - function reScanLessThanToken(): SyntaxKind { - return currentToken = scanner.reScanLessThanToken(); + function reScanLesserToken(): SyntaxKind { + return currentToken = scanner.reScanLesserToken(); } function scanJsxIdentifier(): SyntaxKind { @@ -2267,7 +2267,7 @@ namespace ts { function parseTypeReference(): TypeReferenceNode { const node = createNode(SyntaxKind.TypeReference); node.typeName = parseEntityName(/*allowReservedWords*/ true, Diagnostics.Type_expected); - if (!scanner.hasPrecedingLineBreak() && reScanLessThanToken() === SyntaxKind.LessThanToken) { + if (!scanner.hasPrecedingLineBreak() && reScanLesserToken() === SyntaxKind.LessThanToken) { node.typeArguments = parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken); } return finishNode(node); @@ -4506,7 +4506,8 @@ namespace ts { function parseCallExpressionRest(expression: LeftHandSideExpression): LeftHandSideExpression { while (true) { expression = parseMemberExpressionRest(expression); - if (token() === SyntaxKind.LessThanToken) { + // handle 'foo<()' + 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 @@ -4548,9 +4549,10 @@ namespace ts { } function parseTypeArgumentsInExpression() { - if (!parseOptional(SyntaxKind.LessThanToken)) { + if (reScanLesserToken() !== SyntaxKind.LessThanToken) { return undefined; } + nextToken(); const typeArguments = parseDelimitedList(ParsingContext.TypeArguments, parseType); if (!parseExpected(SyntaxKind.GreaterThanToken)) { diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 9359fe9b30..0411fa6635 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -31,7 +31,7 @@ namespace ts { scanJsxIdentifier(): SyntaxKind; scanJsxAttributeValue(): SyntaxKind; reScanJsxToken(): JsxTokenSyntaxKind; - reScanLessThanToken(): SyntaxKind; + reScanLesserToken(): SyntaxKind; scanJsxToken(): JsxTokenSyntaxKind; scanJSDocToken(): JsDocSyntaxKind; scan(): SyntaxKind; @@ -846,7 +846,7 @@ namespace ts { scanJsxIdentifier, scanJsxAttributeValue, reScanJsxToken, - reScanLessThanToken, + reScanLesserToken, scanJsxToken, scanJSDocToken, scan, @@ -1842,7 +1842,7 @@ namespace ts { return token = scanJsxToken(); } - function reScanLessThanToken(): SyntaxKind { + function reScanLesserToken(): SyntaxKind { if (token === SyntaxKind.LessThanLessThanToken) { pos = tokenPos + 1; return token = SyntaxKind.LessThanToken; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 25f71327d3..a28cb6ab6e 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3071,7 +3071,7 @@ declare namespace ts { scanJsxIdentifier(): SyntaxKind; scanJsxAttributeValue(): SyntaxKind; reScanJsxToken(): JsxTokenSyntaxKind; - reScanLessThanToken(): SyntaxKind; + reScanLesserToken(): SyntaxKind; scanJsxToken(): JsxTokenSyntaxKind; scanJSDocToken(): JsDocSyntaxKind; scan(): SyntaxKind; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 6a01e6bb58..87bd074c94 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3071,7 +3071,7 @@ declare namespace ts { scanJsxIdentifier(): SyntaxKind; scanJsxAttributeValue(): SyntaxKind; reScanJsxToken(): JsxTokenSyntaxKind; - reScanLessThanToken(): SyntaxKind; + reScanLesserToken(): SyntaxKind; scanJsxToken(): JsxTokenSyntaxKind; scanJSDocToken(): JsDocSyntaxKind; scan(): SyntaxKind; diff --git a/tests/baselines/reference/parseGenericArrowRatherThanLeftShift.js b/tests/baselines/reference/parseGenericArrowRatherThanLeftShift.js index 3416e5ad0f..f1efc8023b 100644 --- a/tests/baselines/reference/parseGenericArrowRatherThanLeftShift.js +++ b/tests/baselines/reference/parseGenericArrowRatherThanLeftShift.js @@ -1,7 +1,11 @@ //// [parseGenericArrowRatherThanLeftShift.ts] type Bar = ReturnType<(x: T) => number>; - declare const a: Bar; + +function foo(_x: T) {} +const b = foo<(x: T) => number>(() => 1); //// [parseGenericArrowRatherThanLeftShift.js] +function foo(_x) { } +var b = foo(function () { return 1; }); diff --git a/tests/baselines/reference/parseGenericArrowRatherThanLeftShift.symbols b/tests/baselines/reference/parseGenericArrowRatherThanLeftShift.symbols index 8610080455..335ffd451e 100644 --- a/tests/baselines/reference/parseGenericArrowRatherThanLeftShift.symbols +++ b/tests/baselines/reference/parseGenericArrowRatherThanLeftShift.symbols @@ -7,6 +7,19 @@ type Bar = ReturnType<(x: T) => number>; >T : Symbol(T, Decl(parseGenericArrowRatherThanLeftShift.ts, 0, 23)) declare const a: Bar; ->a : Symbol(a, Decl(parseGenericArrowRatherThanLeftShift.ts, 2, 13)) +>a : Symbol(a, Decl(parseGenericArrowRatherThanLeftShift.ts, 1, 13)) >Bar : Symbol(Bar, Decl(parseGenericArrowRatherThanLeftShift.ts, 0, 0)) +function foo(_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<(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)) + diff --git a/tests/baselines/reference/parseGenericArrowRatherThanLeftShift.types b/tests/baselines/reference/parseGenericArrowRatherThanLeftShift.types index 8c959cbed1..3f256ffdca 100644 --- a/tests/baselines/reference/parseGenericArrowRatherThanLeftShift.types +++ b/tests/baselines/reference/parseGenericArrowRatherThanLeftShift.types @@ -6,3 +6,15 @@ type Bar = ReturnType<(x: T) => number>; declare const a: Bar; >a : number +function foo(_x: T) {} +>foo : (_x: T) => void +>_x : T + +const b = foo<(x: T) => number>(() => 1); +>b : void +>foo<(x: T) => number>(() => 1) : void +>foo : (_x: T) => void +>x : T +>() => 1 : () => number +>1 : 1 + diff --git a/tests/cases/compiler/parseGenericArrowRatherThanLeftShift.ts b/tests/cases/compiler/parseGenericArrowRatherThanLeftShift.ts index cf4f06a590..e61f13a851 100644 --- a/tests/cases/compiler/parseGenericArrowRatherThanLeftShift.ts +++ b/tests/cases/compiler/parseGenericArrowRatherThanLeftShift.ts @@ -1,3 +1,5 @@ type Bar = ReturnType<(x: T) => number>; - declare const a: Bar; + +function foo(_x: T) {} +const b = foo<(x: T) => number>(() => 1);