Skip to content

Commit 2f6c65e

Browse files
Merge pull request #26653 from Kingwl/improve_type_arguments_parser_1
parse less than token rather than left shift in context of type argum…
2 parents ebebc9f + e38ac0d commit 2f6c65e

8 files changed

+82
-3
lines changed

src/compiler/parser.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,6 +1093,10 @@ namespace ts {
10931093
return currentToken = scanner.reScanTemplateToken();
10941094
}
10951095

1096+
function reScanLessThanToken(): SyntaxKind {
1097+
return currentToken = scanner.reScanLessThanToken();
1098+
}
1099+
10961100
function scanJsxIdentifier(): SyntaxKind {
10971101
return currentToken = scanner.scanJsxIdentifier();
10981102
}
@@ -2276,7 +2280,7 @@ namespace ts {
22762280
function parseTypeReference(): TypeReferenceNode {
22772281
const node = <TypeReferenceNode>createNode(SyntaxKind.TypeReference);
22782282
node.typeName = parseEntityName(/*allowReservedWords*/ true, Diagnostics.Type_expected);
2279-
if (!scanner.hasPrecedingLineBreak() && token() === SyntaxKind.LessThanToken) {
2283+
if (!scanner.hasPrecedingLineBreak() && reScanLessThanToken() === SyntaxKind.LessThanToken) {
22802284
node.typeArguments = parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken);
22812285
}
22822286
return finishNode(node);
@@ -4523,7 +4527,8 @@ namespace ts {
45234527
function parseCallExpressionRest(expression: LeftHandSideExpression): LeftHandSideExpression {
45244528
while (true) {
45254529
expression = parseMemberExpressionRest(expression);
4526-
if (token() === SyntaxKind.LessThanToken) {
4530+
// handle 'foo<<T>()'
4531+
if (token() === SyntaxKind.LessThanToken || token() === SyntaxKind.LessThanLessThanToken) {
45274532
// See if this is the start of a generic invocation. If so, consume it and
45284533
// keep checking for postfix expressions. Otherwise, it's just a '<' that's
45294534
// part of an arithmetic expression. Break out so we consume it higher in the
@@ -4565,9 +4570,10 @@ namespace ts {
45654570
}
45664571

45674572
function parseTypeArgumentsInExpression() {
4568-
if (!parseOptional(SyntaxKind.LessThanToken)) {
4573+
if (reScanLessThanToken() !== SyntaxKind.LessThanToken) {
45694574
return undefined;
45704575
}
4576+
nextToken();
45714577

45724578
const typeArguments = parseDelimitedList(ParsingContext.TypeArguments, parseType);
45734579
if (!parseExpected(SyntaxKind.GreaterThanToken)) {

src/compiler/scanner.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ namespace ts {
3131
scanJsxIdentifier(): SyntaxKind;
3232
scanJsxAttributeValue(): SyntaxKind;
3333
reScanJsxToken(): JsxTokenSyntaxKind;
34+
reScanLessThanToken(): SyntaxKind;
3435
scanJsxToken(): JsxTokenSyntaxKind;
3536
scanJSDocToken(): JsDocSyntaxKind;
3637
scan(): SyntaxKind;
@@ -874,6 +875,7 @@ namespace ts {
874875
scanJsxIdentifier,
875876
scanJsxAttributeValue,
876877
reScanJsxToken,
878+
reScanLessThanToken,
877879
scanJsxToken,
878880
scanJSDocToken,
879881
scan,
@@ -1939,6 +1941,14 @@ namespace ts {
19391941
return token = scanJsxToken();
19401942
}
19411943

1944+
function reScanLessThanToken(): SyntaxKind {
1945+
if (token === SyntaxKind.LessThanLessThanToken) {
1946+
pos = tokenPos + 1;
1947+
return token = SyntaxKind.LessThanToken;
1948+
}
1949+
return token;
1950+
}
1951+
19421952
function scanJsxToken(): JsxTokenSyntaxKind {
19431953
startPos = tokenPos = pos;
19441954

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3097,6 +3097,7 @@ declare namespace ts {
30973097
scanJsxIdentifier(): SyntaxKind;
30983098
scanJsxAttributeValue(): SyntaxKind;
30993099
reScanJsxToken(): JsxTokenSyntaxKind;
3100+
reScanLessThanToken(): SyntaxKind;
31003101
scanJsxToken(): JsxTokenSyntaxKind;
31013102
scanJSDocToken(): JsDocSyntaxKind;
31023103
scan(): SyntaxKind;

tests/baselines/reference/api/typescript.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3097,6 +3097,7 @@ declare namespace ts {
30973097
scanJsxIdentifier(): SyntaxKind;
30983098
scanJsxAttributeValue(): SyntaxKind;
30993099
reScanJsxToken(): JsxTokenSyntaxKind;
3100+
reScanLessThanToken(): SyntaxKind;
31003101
scanJsxToken(): JsxTokenSyntaxKind;
31013102
scanJSDocToken(): JsDocSyntaxKind;
31023103
scan(): SyntaxKind;
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//// [parseGenericArrowRatherThanLeftShift.ts]
2+
type Bar = ReturnType<<T>(x: T) => number>;
3+
declare const a: Bar;
4+
5+
function foo<T>(_x: T) {}
6+
const b = foo<<T>(x: T) => number>(() => 1);
7+
8+
9+
//// [parseGenericArrowRatherThanLeftShift.js]
10+
function foo(_x) { }
11+
var b = foo(function () { return 1; });
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
=== tests/cases/compiler/parseGenericArrowRatherThanLeftShift.ts ===
2+
type Bar = ReturnType<<T>(x: T) => number>;
3+
>Bar : Symbol(Bar, Decl(parseGenericArrowRatherThanLeftShift.ts, 0, 0))
4+
>ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --))
5+
>T : Symbol(T, Decl(parseGenericArrowRatherThanLeftShift.ts, 0, 23))
6+
>x : Symbol(x, Decl(parseGenericArrowRatherThanLeftShift.ts, 0, 26))
7+
>T : Symbol(T, Decl(parseGenericArrowRatherThanLeftShift.ts, 0, 23))
8+
9+
declare const a: Bar;
10+
>a : Symbol(a, Decl(parseGenericArrowRatherThanLeftShift.ts, 1, 13))
11+
>Bar : Symbol(Bar, Decl(parseGenericArrowRatherThanLeftShift.ts, 0, 0))
12+
13+
function foo<T>(_x: T) {}
14+
>foo : Symbol(foo, Decl(parseGenericArrowRatherThanLeftShift.ts, 1, 21))
15+
>T : Symbol(T, Decl(parseGenericArrowRatherThanLeftShift.ts, 3, 13))
16+
>_x : Symbol(_x, Decl(parseGenericArrowRatherThanLeftShift.ts, 3, 16))
17+
>T : Symbol(T, Decl(parseGenericArrowRatherThanLeftShift.ts, 3, 13))
18+
19+
const b = foo<<T>(x: T) => number>(() => 1);
20+
>b : Symbol(b, Decl(parseGenericArrowRatherThanLeftShift.ts, 4, 5))
21+
>foo : Symbol(foo, Decl(parseGenericArrowRatherThanLeftShift.ts, 1, 21))
22+
>T : Symbol(T, Decl(parseGenericArrowRatherThanLeftShift.ts, 4, 15))
23+
>x : Symbol(x, Decl(parseGenericArrowRatherThanLeftShift.ts, 4, 18))
24+
>T : Symbol(T, Decl(parseGenericArrowRatherThanLeftShift.ts, 4, 15))
25+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
=== tests/cases/compiler/parseGenericArrowRatherThanLeftShift.ts ===
2+
type Bar = ReturnType<<T>(x: T) => number>;
3+
>Bar : number
4+
>x : T
5+
6+
declare const a: Bar;
7+
>a : number
8+
9+
function foo<T>(_x: T) {}
10+
>foo : <T>(_x: T) => void
11+
>_x : T
12+
13+
const b = foo<<T>(x: T) => number>(() => 1);
14+
>b : void
15+
>foo<<T>(x: T) => number>(() => 1) : void
16+
>foo : <T>(_x: T) => void
17+
>x : T
18+
>() => 1 : () => number
19+
>1 : 1
20+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
type Bar = ReturnType<<T>(x: T) => number>;
2+
declare const a: Bar;
3+
4+
function foo<T>(_x: T) {}
5+
const b = foo<<T>(x: T) => number>(() => 1);

0 commit comments

Comments
 (0)