Skip to content

Commit d796bf1

Browse files
Improve the flexibility of speculative parsing.
We now no longer fail a speculative parse just because an error was encountered at any point while speculating. instead, we allow the speculative function that is being called to determine if the parse was successful or not. Only if it decides it was not successful is parsing rewound. This improves our error recovery in several cases (esp. around arrow functions). it will also help in a followup refactoring to prevent lookahead/speculative parsing from causing lambda allocations.
1 parent 05dc934 commit d796bf1

13 files changed

+164
-178
lines changed

src/compiler/parser.ts

Lines changed: 97 additions & 78 deletions
Large diffs are not rendered by default.
Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
1-
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/ArrowFunction3.ts(1,12): error TS1005: ',' expected.
2-
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/ArrowFunction3.ts(1,14): error TS1005: ';' expected.
3-
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/ArrowFunction3.ts(1,10): error TS2304: Cannot find name 'a'.
1+
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/ArrowFunction3.ts(1,14): error TS1110: Type expected.
2+
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/ArrowFunction3.ts(1,13): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement.
43

54

6-
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/ArrowFunction3.ts (3 errors) ====
5+
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/ArrowFunction3.ts (2 errors) ====
76
var v = (a): => {
8-
~
9-
!!! error TS1005: ',' expected.
107
~~
11-
!!! error TS1005: ';' expected.
12-
~
13-
!!! error TS2304: Cannot find name 'a'.
8+
!!! error TS1110: Type expected.
9+
10+
!!! error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement.
1411

1512
};
Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
11
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,9): error TS1127: Invalid character.
22
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,1): error TS2304: Cannot find name 'Foo'.
3-
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,5): error TS2304: Cannot find name 'A'.
4-
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,7): error TS2304: Cannot find name 'B'.
5-
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,11): error TS2304: Cannot find name 'C'.
63

74

8-
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts (5 errors) ====
5+
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts (2 errors) ====
96
Foo<A,B,\ C>(4, 5, 6);
107

118
!!! error TS1127: Invalid character.
129
~~~
13-
!!! error TS2304: Cannot find name 'Foo'.
14-
~
15-
!!! error TS2304: Cannot find name 'A'.
16-
~
17-
!!! error TS2304: Cannot find name 'B'.
18-
~
19-
!!! error TS2304: Cannot find name 'C'.
10+
!!! error TS2304: Cannot find name 'Foo'.
Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
1-
tests/cases/compiler/genericCallWithoutArgs.ts(4,17): error TS1109: Expression expected.
2-
tests/cases/compiler/genericCallWithoutArgs.ts(4,18): error TS1003: Identifier expected.
3-
tests/cases/compiler/genericCallWithoutArgs.ts(4,3): error TS2304: Cannot find name 'number'.
4-
tests/cases/compiler/genericCallWithoutArgs.ts(4,10): error TS2304: Cannot find name 'string'.
1+
tests/cases/compiler/genericCallWithoutArgs.ts(4,17): error TS1005: '(' expected.
2+
tests/cases/compiler/genericCallWithoutArgs.ts(4,18): error TS1005: ')' expected.
53

64

7-
==== tests/cases/compiler/genericCallWithoutArgs.ts (4 errors) ====
5+
==== tests/cases/compiler/genericCallWithoutArgs.ts (2 errors) ====
86
function f<X, Y>(x: X, y: Y) {
97
}
108

119
f<number,string>.
1210
~
13-
!!! error TS1109: Expression expected.
11+
!!! error TS1005: '(' expected.
1412

15-
!!! error TS1003: Identifier expected.
16-
~~~~~~
17-
!!! error TS2304: Cannot find name 'number'.
18-
~~~~~~
19-
!!! error TS2304: Cannot find name 'string'.
13+
!!! error TS1005: ')' expected.
Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,18 @@
1-
tests/cases/compiler/genericCallsWithoutParens.ts(2,18): error TS1109: Expression expected.
2-
tests/cases/compiler/genericCallsWithoutParens.ts(7,22): error TS1109: Expression expected.
3-
tests/cases/compiler/genericCallsWithoutParens.ts(2,11): error TS2304: Cannot find name 'number'.
4-
tests/cases/compiler/genericCallsWithoutParens.ts(7,15): error TS2304: Cannot find name 'number'.
1+
tests/cases/compiler/genericCallsWithoutParens.ts(2,18): error TS1005: '(' expected.
2+
tests/cases/compiler/genericCallsWithoutParens.ts(7,22): error TS1005: '(' expected.
53

64

7-
==== tests/cases/compiler/genericCallsWithoutParens.ts (4 errors) ====
5+
==== tests/cases/compiler/genericCallsWithoutParens.ts (2 errors) ====
86
function f<T>() { }
97
var r = f<number>; // parse error
108
~
11-
!!! error TS1109: Expression expected.
12-
~~~~~~
13-
!!! error TS2304: Cannot find name 'number'.
9+
!!! error TS1005: '(' expected.
1410

1511
class C<T> {
1612
foo: T;
1713
}
1814
var c = new C<number>; // parse error
1915
~
20-
!!! error TS1109: Expression expected.
21-
~~~~~~
22-
!!! error TS2304: Cannot find name 'number'.
16+
!!! error TS1005: '(' expected.
2317

2418

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
tests/cases/compiler/genericConstructExpressionWithoutArgs.ts(10,1): error TS1109: Expression expected.
2-
tests/cases/compiler/genericConstructExpressionWithoutArgs.ts(9,16): error TS2304: Cannot find name 'number'.
1+
tests/cases/compiler/genericConstructExpressionWithoutArgs.ts(10,1): error TS1005: '(' expected.
32

43

5-
==== tests/cases/compiler/genericConstructExpressionWithoutArgs.ts (2 errors) ====
4+
==== tests/cases/compiler/genericConstructExpressionWithoutArgs.ts (1 errors) ====
65
class B { }
76
var b = new B; // no error
87

@@ -12,8 +11,6 @@ tests/cases/compiler/genericConstructExpressionWithoutArgs.ts(9,16): error TS230
1211

1312
var c = new C // C<any>
1413
var c2 = new C<number> // error, type params are actually part of the arg list so you need both
15-
~~~~~~
16-
!!! error TS2304: Cannot find name 'number'.
1714

1815

19-
!!! error TS1109: Expression expected.
16+
!!! error TS1005: '(' expected.
Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
1-
tests/cases/compiler/genericObjectCreationWithoutTypeArgs.ts(6,26): error TS1109: Expression expected.
2-
tests/cases/compiler/genericObjectCreationWithoutTypeArgs.ts(6,19): error TS2304: Cannot find name 'number'.
1+
tests/cases/compiler/genericObjectCreationWithoutTypeArgs.ts(6,26): error TS1005: '(' expected.
32

43

5-
==== tests/cases/compiler/genericObjectCreationWithoutTypeArgs.ts (2 errors) ====
4+
==== tests/cases/compiler/genericObjectCreationWithoutTypeArgs.ts (1 errors) ====
65
class SS<T>{
76

87
}
98

109
var x1 = new SS<number>(); // OK
1110
var x2 = new SS < number>; // Correctly give error
1211
~
13-
!!! error TS1109: Expression expected.
14-
~~~~~~
15-
!!! error TS2304: Cannot find name 'number'.
12+
!!! error TS1005: '(' expected.
1613
var x3 = new SS(); // OK
1714
var x4 = new SS; // Should be allowed, but currently give error ('supplied parameters do not match any signature of the call target')
1815

tests/baselines/reference/newOperatorErrorCases.errors.txt

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
tests/cases/conformance/expressions/newOperator/newOperatorErrorCases.ts(27,16): error TS1005: ',' expected.
2-
tests/cases/conformance/expressions/newOperator/newOperatorErrorCases.ts(32,23): error TS1109: Expression expected.
3-
tests/cases/conformance/expressions/newOperator/newOperatorErrorCases.ts(32,16): error TS2304: Cannot find name 'string'.
2+
tests/cases/conformance/expressions/newOperator/newOperatorErrorCases.ts(32,23): error TS1005: '(' expected.
43
tests/cases/conformance/expressions/newOperator/newOperatorErrorCases.ts(37,9): error TS2350: Only a void function can be called with the 'new' keyword.
54

65

7-
==== tests/cases/conformance/expressions/newOperator/newOperatorErrorCases.ts (4 errors) ====
6+
==== tests/cases/conformance/expressions/newOperator/newOperatorErrorCases.ts (3 errors) ====
87

98
class C0 {
109

@@ -40,9 +39,7 @@ tests/cases/conformance/expressions/newOperator/newOperatorErrorCases.ts(37,9):
4039
var c1: T<{}>;
4140
var c2 = new T<string>; // Parse error
4241
~
43-
!!! error TS1109: Expression expected.
44-
~~~~~~
45-
!!! error TS2304: Cannot find name 'string'.
42+
!!! error TS1005: '(' expected.
4643

4744

4845
// Construct expression of non-void returning function
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
tests/cases/conformance/parser/ecmascript5/Generics/parserConstructorAmbiguity3.ts(1,12): error TS1109: Expression expected.
1+
tests/cases/conformance/parser/ecmascript5/Generics/parserConstructorAmbiguity3.ts(1,12): error TS1005: '(' expected.
2+
tests/cases/conformance/parser/ecmascript5/Generics/parserConstructorAmbiguity3.ts(1,1): error TS2346: Supplied parameters do not match any signature of call target.
23
tests/cases/conformance/parser/ecmascript5/Generics/parserConstructorAmbiguity3.ts(1,10): error TS2304: Cannot find name 'A'.
34

45

5-
==== tests/cases/conformance/parser/ecmascript5/Generics/parserConstructorAmbiguity3.ts (2 errors) ====
6+
==== tests/cases/conformance/parser/ecmascript5/Generics/parserConstructorAmbiguity3.ts (3 errors) ====
67
new Date<A>
78

8-
!!! error TS1109: Expression expected.
9+
!!! error TS1005: '(' expected.
10+
~~~~~~~~~~~
11+
!!! error TS2346: Supplied parameters do not match any signature of call target.
912
~
1013
!!! error TS2304: Cannot find name 'A'.
Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
1-
tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(3,7): error TS1109: Expression expected.
2-
tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(4,7): error TS1109: Expression expected.
1+
tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(3,7): error TS1005: '(' expected.
2+
tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(3,13): error TS1005: ')' expected.
3+
tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(4,7): error TS1005: '(' expected.
4+
tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(4,16): error TS1005: ')' expected.
35
tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(1,1): error TS2304: Cannot find name 'Foo'.
46
tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(2,1): error TS2304: Cannot find name 'Foo'.
57
tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(3,1): error TS2304: Cannot find name 'Foo'.
6-
tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(3,5): error TS2304: Cannot find name 'T'.
8+
tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(3,8): error TS2304: Cannot find name 'Bar'.
79
tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(4,1): error TS2304: Cannot find name 'Foo'.
8-
tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(4,5): error TS2304: Cannot find name 'T'.
10+
tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(4,8): error TS2304: Cannot find name 'Bar'.
911

1012

11-
==== tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts (8 errors) ====
13+
==== tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts (10 errors) ====
1214
Foo<T>();
1315
~~~
1416
!!! error TS2304: Cannot find name 'Foo'.
@@ -17,16 +19,20 @@ tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression
1719
!!! error TS2304: Cannot find name 'Foo'.
1820
Foo<T>.Bar();
1921
~
20-
!!! error TS1109: Expression expected.
22+
!!! error TS1005: '(' expected.
23+
~
24+
!!! error TS1005: ')' expected.
2125
~~~
2226
!!! error TS2304: Cannot find name 'Foo'.
23-
~
24-
!!! error TS2304: Cannot find name 'T'.
27+
~~~
28+
!!! error TS2304: Cannot find name 'Bar'.
2529
Foo<T>.Bar<T>();
2630
~
27-
!!! error TS1109: Expression expected.
31+
!!! error TS1005: '(' expected.
32+
~
33+
!!! error TS1005: ')' expected.
2834
~~~
2935
!!! error TS2304: Cannot find name 'Foo'.
30-
~
31-
!!! error TS2304: Cannot find name 'T'.
36+
~~~
37+
!!! error TS2304: Cannot find name 'Bar'.
3238

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
1-
tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts(1,21): error TS1109: Expression expected.
1+
tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts(1,21): error TS1005: '(' expected.
2+
tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts(1,33): error TS1005: ')' expected.
23
tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts(1,9): error TS2304: Cannot find name 'List'.
3-
tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts(1,14): error TS2304: Cannot find name 'number'.
4+
tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts(1,22): error TS2304: Cannot find name 'makeChild'.
45

56

6-
==== tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts (3 errors) ====
7+
==== tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts (4 errors) ====
78
var v = List<number>.makeChild();
89
~
9-
!!! error TS1109: Expression expected.
10+
!!! error TS1005: '(' expected.
11+
~
12+
!!! error TS1005: ')' expected.
1013
~~~~
1114
!!! error TS2304: Cannot find name 'List'.
12-
~~~~~~
13-
!!! error TS2304: Cannot find name 'number'.
15+
~~~~~~~~~
16+
!!! error TS2304: Cannot find name 'makeChild'.
Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
1-
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/parserX_ArrowFunction3.ts(1,12): error TS1005: ',' expected.
2-
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/parserX_ArrowFunction3.ts(1,14): error TS1005: ';' expected.
3-
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/parserX_ArrowFunction3.ts(1,10): error TS2304: Cannot find name 'a'.
1+
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/parserX_ArrowFunction3.ts(1,14): error TS1110: Type expected.
2+
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/parserX_ArrowFunction3.ts(1,13): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement.
43

54

6-
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/parserX_ArrowFunction3.ts (3 errors) ====
5+
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/parserX_ArrowFunction3.ts (2 errors) ====
76
var v = (a): => {
8-
~
9-
!!! error TS1005: ',' expected.
107
~~
11-
!!! error TS1005: ';' expected.
12-
~
13-
!!! error TS2304: Cannot find name 'a'.
8+
!!! error TS1110: Type expected.
9+
10+
!!! error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement.
1411

1512
};
Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
11
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/parserX_TypeArgumentList1.ts(1,9): error TS1127: Invalid character.
22
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/parserX_TypeArgumentList1.ts(1,1): error TS2304: Cannot find name 'Foo'.
3-
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/parserX_TypeArgumentList1.ts(1,5): error TS2304: Cannot find name 'A'.
4-
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/parserX_TypeArgumentList1.ts(1,7): error TS2304: Cannot find name 'B'.
5-
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/parserX_TypeArgumentList1.ts(1,11): error TS2304: Cannot find name 'C'.
63

74

8-
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/parserX_TypeArgumentList1.ts (5 errors) ====
5+
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/parserX_TypeArgumentList1.ts (2 errors) ====
96
Foo<A,B,\ C>(4, 5, 6);
107

118
!!! error TS1127: Invalid character.
129
~~~
13-
!!! error TS2304: Cannot find name 'Foo'.
14-
~
15-
!!! error TS2304: Cannot find name 'A'.
16-
~
17-
!!! error TS2304: Cannot find name 'B'.
18-
~
19-
!!! error TS2304: Cannot find name 'C'.
10+
!!! error TS2304: Cannot find name 'Foo'.

0 commit comments

Comments
 (0)