Skip to content

Commit 13d9f08

Browse files
soonRyanCavanaugh
authored andcommitted
Gracefully parse 'super' with type arguments (#10677) (#30913)
1 parent 72f6656 commit 13d9f08

23 files changed

+58
-91
lines changed

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2605,6 +2605,10 @@
26052605
"category": "Error",
26062606
"code": 2753
26072607
},
2608+
"'super' may not use type arguments.": {
2609+
"category": "Error",
2610+
"code": 2754
2611+
},
26082612

26092613
"Import declaration '{0}' is using private name '{1}'.": {
26102614
"category": "Error",

src/compiler/parser.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4189,6 +4189,14 @@ namespace ts {
41894189

41904190
function parseSuperExpression(): MemberExpression {
41914191
const expression = parseTokenNode<PrimaryExpression>();
4192+
if (token() === SyntaxKind.LessThanToken) {
4193+
const startPos = getNodePos();
4194+
const typeArguments = tryParse(parseTypeArgumentsInExpression);
4195+
if (typeArguments !== undefined) {
4196+
parseErrorAt(startPos, getNodePos(), Diagnostics.super_may_not_use_type_arguments);
4197+
}
4198+
}
4199+
41924200
if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.DotToken || token() === SyntaxKind.OpenBracketToken) {
41934201
return expression;
41944202
}

tests/baselines/reference/errorSuperCalls.errors.txt

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,14 @@ tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(26,9): error T
77
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(30,16): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
88
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(34,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
99
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(38,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
10-
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(46,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
11-
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(46,14): error TS1034: 'super' must be followed by an argument list or member access.
10+
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(46,14): error TS2754: 'super' may not use type arguments.
1211
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(58,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
1312
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(62,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
1413
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(67,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
1514
tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(71,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
1615

1716

18-
==== tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts (15 errors) ====
17+
==== tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts (14 errors) ====
1918
//super call in class constructor with no base type
2019
class NoBase {
2120
constructor() {
@@ -80,10 +79,8 @@ tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(71,9): error T
8079
//super call with type arguments
8180
constructor() {
8281
super<string>();
83-
~~~~~
84-
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
85-
~
86-
!!! error TS1034: 'super' must be followed by an argument list or member access.
82+
~~~~~~~~
83+
!!! error TS2754: 'super' may not use type arguments.
8784
super();
8885
}
8986
}

tests/baselines/reference/errorSuperCalls.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,7 @@ var Derived = /** @class */ (function (_super) {
140140
__extends(Derived, _super);
141141
//super call with type arguments
142142
function Derived() {
143-
var _this = this;
144-
_super.prototype..call(_this);
143+
var _this = _super.call(this) || this;
145144
_this = _super.call(this) || this;
146145
return _this;
147146
}

tests/baselines/reference/errorSuperCalls.types

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,8 @@ class Derived<T> extends Base<T> {
9191
//super call with type arguments
9292
constructor() {
9393
super<string>();
94-
>super<string>() : any
95-
>super : any
96-
>super : Base<T>
97-
> : any
94+
>super<string>() : void
95+
>super : typeof Base
9896

9997
super();
10098
>super() : void
Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
1-
tests/cases/conformance/parser/ecmascript5/SuperExpressions/parserSuperExpression2.ts(3,5): error TS2335: 'super' can only be referenced in a derived class.
2-
tests/cases/conformance/parser/ecmascript5/SuperExpressions/parserSuperExpression2.ts(3,10): error TS1034: 'super' must be followed by an argument list or member access.
3-
tests/cases/conformance/parser/ecmascript5/SuperExpressions/parserSuperExpression2.ts(3,11): error TS2304: Cannot find name 'T'.
1+
tests/cases/conformance/parser/ecmascript5/SuperExpressions/parserSuperExpression2.ts(3,5): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
2+
tests/cases/conformance/parser/ecmascript5/SuperExpressions/parserSuperExpression2.ts(3,10): error TS2754: 'super' may not use type arguments.
43

54

6-
==== tests/cases/conformance/parser/ecmascript5/SuperExpressions/parserSuperExpression2.ts (3 errors) ====
5+
==== tests/cases/conformance/parser/ecmascript5/SuperExpressions/parserSuperExpression2.ts (2 errors) ====
76
class C {
87
M() {
98
super<T>(0);
109
~~~~~
11-
!!! error TS2335: 'super' can only be referenced in a derived class.
12-
~
13-
!!! error TS1034: 'super' must be followed by an argument list or member access.
14-
~
15-
!!! error TS2304: Cannot find name 'T'.
10+
!!! error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
11+
~~~
12+
!!! error TS2754: 'super' may not use type arguments.
1613
}
1714
}

tests/baselines/reference/parserSuperExpression2.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ var C = /** @class */ (function () {
1010
function C() {
1111
}
1212
C.prototype.M = function () {
13-
_super.prototype..call(this, 0);
13+
_this = _super.call(this, 0) || this;
1414
};
1515
return C;
1616
}());

tests/baselines/reference/parserSuperExpression2.types

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@ class C {
66
>M : () => void
77

88
super<T>(0);
9-
>super<T>(0) : any
9+
>super<T>(0) : void
1010
>super : any
11-
>super : any
12-
> : any
1311
>0 : 0
1412
}
1513
}
Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,15 @@
1-
tests/cases/compiler/superWithTypeArgument.ts(6,5): error TS2377: Constructors for derived classes must contain a 'super' call.
2-
tests/cases/compiler/superWithTypeArgument.ts(7,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
3-
tests/cases/compiler/superWithTypeArgument.ts(7,14): error TS1034: 'super' must be followed by an argument list or member access.
1+
tests/cases/compiler/superWithTypeArgument.ts(7,14): error TS2754: 'super' may not use type arguments.
42

53

6-
==== tests/cases/compiler/superWithTypeArgument.ts (3 errors) ====
4+
==== tests/cases/compiler/superWithTypeArgument.ts (1 errors) ====
75
class C {
86

97
}
108

119
class D<T> extends C {
1210
constructor() {
13-
~~~~~~~~~~~~~~~
1411
super<T>();
15-
~~~~~~~~~~~~~~~~~~~
16-
~~~~~
17-
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
18-
~
19-
!!! error TS1034: 'super' must be followed by an argument list or member access.
12+
~~~
13+
!!! error TS2754: 'super' may not use type arguments.
2014
}
21-
~~~~~
22-
!!! error TS2377: Constructors for derived classes must contain a 'super' call.
2315
}

tests/baselines/reference/superWithTypeArgument.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@ var C = /** @class */ (function () {
3131
var D = /** @class */ (function (_super) {
3232
__extends(D, _super);
3333
function D() {
34-
var _this = this;
35-
_super.prototype..call(_this);
36-
return _this;
34+
return _super.call(this) || this;
3735
}
3836
return D;
3937
}(C));

tests/baselines/reference/superWithTypeArgument.symbols

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,5 @@ class D<T> extends C {
1212
constructor() {
1313
super<T>();
1414
>super : Symbol(C, Decl(superWithTypeArgument.ts, 0, 0))
15-
>T : Symbol(T, Decl(superWithTypeArgument.ts, 4, 8))
1615
}
1716
}

tests/baselines/reference/superWithTypeArgument.types

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ class D<T> extends C {
1010

1111
constructor() {
1212
super<T>();
13-
>super<T>() : any
14-
>super : any
15-
>super : C
16-
> : any
13+
>super<T>() : void
14+
>super : typeof C
1715
}
1816
}
Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,18 @@
1-
tests/cases/compiler/superWithTypeArgument2.ts(6,5): error TS2377: Constructors for derived classes must contain a 'super' call.
2-
tests/cases/compiler/superWithTypeArgument2.ts(7,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
3-
tests/cases/compiler/superWithTypeArgument2.ts(7,14): error TS1034: 'super' must be followed by an argument list or member access.
1+
tests/cases/compiler/superWithTypeArgument2.ts(7,14): error TS2754: 'super' may not use type arguments.
2+
tests/cases/compiler/superWithTypeArgument2.ts(7,18): error TS2554: Expected 0 arguments, but got 1.
43

54

6-
==== tests/cases/compiler/superWithTypeArgument2.ts (3 errors) ====
5+
==== tests/cases/compiler/superWithTypeArgument2.ts (2 errors) ====
76
class C<T> {
87
foo: T;
98
}
109

1110
class D<T> extends C<T> {
1211
constructor(x) {
13-
~~~~~~~~~~~~~~~~
1412
super<T>(x);
15-
~~~~~~~~~~~~~~~~~~~~
16-
~~~~~
17-
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
18-
~
19-
!!! error TS1034: 'super' must be followed by an argument list or member access.
13+
~~~
14+
!!! error TS2754: 'super' may not use type arguments.
15+
~
16+
!!! error TS2554: Expected 0 arguments, but got 1.
2017
}
21-
~~~~~
22-
!!! error TS2377: Constructors for derived classes must contain a 'super' call.
2318
}

tests/baselines/reference/superWithTypeArgument2.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@ var C = /** @class */ (function () {
3131
var D = /** @class */ (function (_super) {
3232
__extends(D, _super);
3333
function D(x) {
34-
var _this = this;
35-
_super.prototype..call(_this, x);
36-
return _this;
34+
return _super.call(this, x) || this;
3735
}
3836
return D;
3937
}(C));

tests/baselines/reference/superWithTypeArgument2.symbols

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ class D<T> extends C<T> {
1919

2020
super<T>(x);
2121
>super : Symbol(C, Decl(superWithTypeArgument2.ts, 0, 0))
22-
>T : Symbol(T, Decl(superWithTypeArgument2.ts, 4, 8))
2322
>x : Symbol(x, Decl(superWithTypeArgument2.ts, 5, 16))
2423
}
2524
}

tests/baselines/reference/superWithTypeArgument2.types

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,8 @@ class D<T> extends C<T> {
1414
>x : any
1515

1616
super<T>(x);
17-
>super<T>(x) : any
18-
>super : any
19-
>super : C<T>
20-
> : any
17+
>super<T>(x) : void
18+
>super : typeof C
2119
>x : any
2220
}
2321
}

tests/baselines/reference/superWithTypeArgument3.errors.txt

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,18 @@
1-
tests/cases/compiler/superWithTypeArgument3.ts(7,5): error TS2377: Constructors for derived classes must contain a 'super' call.
2-
tests/cases/compiler/superWithTypeArgument3.ts(8,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
3-
tests/cases/compiler/superWithTypeArgument3.ts(8,14): error TS1034: 'super' must be followed by an argument list or member access.
1+
tests/cases/compiler/superWithTypeArgument3.ts(8,14): error TS2754: 'super' may not use type arguments.
42

53

6-
==== tests/cases/compiler/superWithTypeArgument3.ts (3 errors) ====
4+
==== tests/cases/compiler/superWithTypeArgument3.ts (1 errors) ====
75
class C<T> {
86
foo: T;
97
bar<U>(x: U) { }
108
}
119

1210
class D<T> extends C<T> {
1311
constructor() {
14-
~~~~~~~~~~~~~~~
1512
super<T>();
16-
~~~~~~~~~~~~~~~~~~~
17-
~~~~~
18-
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
19-
~
20-
!!! error TS1034: 'super' must be followed by an argument list or member access.
13+
~~~
14+
!!! error TS2754: 'super' may not use type arguments.
2115
}
22-
~~~~~
23-
!!! error TS2377: Constructors for derived classes must contain a 'super' call.
2416
bar() {
2517
super.bar<T>(null);
2618
}

tests/baselines/reference/superWithTypeArgument3.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,7 @@ var C = /** @class */ (function () {
3636
var D = /** @class */ (function (_super) {
3737
__extends(D, _super);
3838
function D() {
39-
var _this = this;
40-
_super.prototype..call(_this);
41-
return _this;
39+
return _super.call(this) || this;
4240
}
4341
D.prototype.bar = function () {
4442
_super.prototype.bar.call(this, null);

tests/baselines/reference/superWithTypeArgument3.symbols

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ class D<T> extends C<T> {
2323
constructor() {
2424
super<T>();
2525
>super : Symbol(C, Decl(superWithTypeArgument3.ts, 0, 0))
26-
>T : Symbol(T, Decl(superWithTypeArgument3.ts, 5, 8))
2726
}
2827
bar() {
2928
>bar : Symbol(D.bar, Decl(superWithTypeArgument3.ts, 8, 5))

tests/baselines/reference/superWithTypeArgument3.types

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,8 @@ class D<T> extends C<T> {
1616

1717
constructor() {
1818
super<T>();
19-
>super<T>() : any
20-
>super : any
21-
>super : C<T>
22-
> : any
19+
>super<T>() : void
20+
>super : typeof C
2321
}
2422
bar() {
2523
>bar : () => void

tests/baselines/reference/taggedTemplatesWithTypeArguments2.errors.txt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(15,11
33
tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(17,30): error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number'.
44
tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(35,5): error TS2377: Constructors for derived classes must contain a 'super' call.
55
tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(36,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
6-
tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(36,14): error TS1034: 'super' must be followed by an argument list or member access.
6+
tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(36,14): error TS2754: 'super' may not use type arguments.
7+
tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(36,34): error TS1034: 'super' must be followed by an argument list or member access.
78

89

9-
==== tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts (6 errors) ====
10+
==== tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts (7 errors) ====
1011
export interface SomethingTaggable {
1112
<T>(t: TemplateStringsArray, ...args: T[]): SomethingNewable;
1213
}
@@ -53,7 +54,9 @@ tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(36,14
5354
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5455
~~~~~
5556
!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class.
56-
~
57+
~~~~~~~~~~~~~~~~~~~
58+
!!! error TS2754: 'super' may not use type arguments.
59+
~~~~~~~~~~~~~
5760
!!! error TS1034: 'super' must be followed by an argument list or member access.
5861
}
5962
~~~~~

tests/baselines/reference/taggedTemplatesWithTypeArguments2.symbols

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,5 @@ class SomeDerived<T> extends SomeBase<number, string, T> {
7878
constructor() {
7979
super<number, string, T> `hello world`;
8080
>super : Symbol(SomeBase, Decl(taggedTemplatesWithTypeArguments2.ts, 27, 10))
81-
>T : Symbol(T, Decl(taggedTemplatesWithTypeArguments2.ts, 33, 18))
8281
}
8382
}

tests/baselines/reference/taggedTemplatesWithTypeArguments2.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ class SomeDerived<T> extends SomeBase<number, string, T> {
9292
constructor() {
9393
super<number, string, T> `hello world`;
9494
>super<number, string, T> `hello world` : any
95-
>super : any
95+
>super<number, string, T> : any
9696
>super : SomeBase<number, string, T>
9797
> : any
9898
>`hello world` : "hello world"

0 commit comments

Comments
 (0)