Remove superCallShouldBeFirst error

It seems redundant since TS gives an error on any use of `this` before
super, and non-`this` uses before `super` should be fine.

Fixes #37371
This commit is contained in:
Nathan Shively-Sanders
2020-04-13 16:01:13 -07:00
parent 8dd6b3a389
commit 3c09153c8a
6 changed files with 2 additions and 169 deletions

View File

@@ -29632,15 +29632,6 @@ namespace ts {
return;
}
function isInstancePropertyWithInitializerOrPrivateIdentifierProperty(n: Node): boolean {
if (isPrivateIdentifierPropertyDeclaration(n)) {
return true;
}
return n.kind === SyntaxKind.PropertyDeclaration &&
!hasModifier(n, ModifierFlags.Static) &&
!!(<PropertyDeclaration>n).initializer;
}
// TS 1.0 spec (April 2014): 8.3.2
// Constructors of classes with no extends clause may not contain super calls, whereas
// constructors of derived classes must contain at least one super call somewhere in their function body.
@@ -29653,35 +29644,6 @@ namespace ts {
if (classExtendsNull) {
error(superCall, Diagnostics.A_constructor_cannot_contain_a_super_call_when_its_class_extends_null);
}
// The first statement in the body of a constructor (excluding prologue directives) must be a super call
// if both of the following are true:
// - The containing class is a derived class.
// - The constructor declares parameter properties
// or the containing class declares instance member variables with initializers.
const superCallShouldBeFirst =
some((<ClassDeclaration>node.parent).members, isInstancePropertyWithInitializerOrPrivateIdentifierProperty) ||
some(node.parameters, p => hasModifier(p, ModifierFlags.ParameterPropertyModifier));
// Skip past any prologue directives to find the first statement
// to ensure that it was a super call.
if (superCallShouldBeFirst) {
const statements = node.body!.statements;
let superCallStatement: ExpressionStatement | undefined;
for (const statement of statements) {
if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCall((<ExpressionStatement>statement).expression)) {
superCallStatement = <ExpressionStatement>statement;
break;
}
if (!isPrologueDirective(statement)) {
break;
}
}
if (!superCallStatement) {
error(node, Diagnostics.A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_parameter_properties_or_private_identifiers);
}
}
}
else if (!classExtendsNull) {
error(node, Diagnostics.Constructors_for_derived_classes_must_contain_a_super_call);

View File

@@ -1493,10 +1493,6 @@
"category": "Error",
"code": 2375
},
"A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers.": {
"category": "Error",
"code": 2376
},
"Constructors for derived classes must contain a 'super' call.": {
"category": "Error",
"code": 2377

View File

@@ -1,11 +1,9 @@
tests/cases/compiler/classUpdateTests.ts(34,2): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/classUpdateTests.ts(43,18): error TS2335: 'super' can only be referenced in a derived class.
tests/cases/compiler/classUpdateTests.ts(57,2): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers.
tests/cases/compiler/classUpdateTests.ts(63,7): error TS2415: Class 'L' incorrectly extends base class 'G'.
Property 'p1' is private in type 'L' but not in type 'G'.
tests/cases/compiler/classUpdateTests.ts(69,7): error TS2415: Class 'M' incorrectly extends base class 'G'.
Property 'p1' is private in type 'M' but not in type 'G'.
tests/cases/compiler/classUpdateTests.ts(70,2): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers.
tests/cases/compiler/classUpdateTests.ts(93,3): error TS1128: Declaration or statement expected.
tests/cases/compiler/classUpdateTests.ts(95,1): error TS1128: Declaration or statement expected.
tests/cases/compiler/classUpdateTests.ts(99,3): error TS1128: Declaration or statement expected.
@@ -18,7 +16,7 @@ tests/cases/compiler/classUpdateTests.ts(111,15): error TS1005: ';' expected.
tests/cases/compiler/classUpdateTests.ts(113,1): error TS1128: Declaration or statement expected.
==== tests/cases/compiler/classUpdateTests.ts (16 errors) ====
==== tests/cases/compiler/classUpdateTests.ts (14 errors) ====
//
// test codegen for instance properties
//
@@ -80,14 +78,9 @@ tests/cases/compiler/classUpdateTests.ts(113,1): error TS1128: Declaration or st
class K extends G {
constructor(public p1:number) { // ERROR
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var i = 0;
~~~~~~~~~~~~
super();
~~~~~~~~~~
}
~~
!!! error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers.
}
class L extends G {
@@ -104,14 +97,9 @@ tests/cases/compiler/classUpdateTests.ts(113,1): error TS1128: Declaration or st
!!! error TS2415: Class 'M' incorrectly extends base class 'G'.
!!! error TS2415: Property 'p1' is private in type 'M' but not in type 'G'.
constructor(private p1:number) { // ERROR
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var i = 0;
~~~~~~~~~~~~
super();
~~~~~~~~~~
}
~~
!!! error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers.
}
//

View File

@@ -1,15 +1,11 @@
tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassParameterProperties.ts(15,5): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers.
tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassParameterProperties.ts(30,5): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers.
tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassParameterProperties.ts(47,9): error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class.
tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassParameterProperties.ts(56,5): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers.
tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassParameterProperties.ts(57,9): error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class.
tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassParameterProperties.ts(58,9): error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class.
tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassParameterProperties.ts(79,5): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers.
tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassParameterProperties.ts(80,9): error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class.
tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassParameterProperties.ts(81,9): error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class.
==== tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassParameterProperties.ts (9 errors) ====
==== tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassParameterProperties.ts (5 errors) ====
// ordering of super calls in derived constructors matters depending on other class contents
class Base {
@@ -25,14 +21,9 @@ tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassP
class Derived2 extends Base {
constructor(public y: string) {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var a = 1;
~~~~~~~~~~~~~~~~~~
super(); // error
~~~~~~~~~~~~~~~~~~~~~~~~~
}
~~~~~
!!! error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers.
}
class Derived3 extends Base {
@@ -45,14 +36,9 @@ tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassP
class Derived4 extends Base {
a = 1;
constructor(y: string) {
~~~~~~~~~~~~~~~~~~~~~~~~
var b = 2;
~~~~~~~~~~~~~~~~~~
super(); // error
~~~~~~~~~~~~~~~~~~~~~~~~~
}
~~~~~
!!! error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers.
}
class Derived5 extends Base {
@@ -78,20 +64,14 @@ tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassP
a = 1;
b: number;
constructor(y: string) {
~~~~~~~~~~~~~~~~~~~~~~~~
this.a = 3;
~~~~~~~~~~~~~~~~~~~
~~~~
!!! error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class.
this.b = 3;
~~~~~~~~~~~~~~~~~~~
~~~~
!!! error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class.
super(); // error
~~~~~~~~~~~~~~~~~~~~~~~~~
}
~~~~~
!!! error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers.
}
class Derived8 extends Base {
@@ -111,20 +91,14 @@ tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassP
a = 1;
b: number;
constructor(y: string) {
~~~~~~~~~~~~~~~~~~~~~~~~
this.a = 3;
~~~~~~~~~~~~~~~~~~~
~~~~
!!! error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class.
this.b = 3;
~~~~~~~~~~~~~~~~~~~
~~~~
!!! error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class.
super(); // error
~~~~~~~~~~~~~~~~~~~~~~~~~
}
~~~~~
!!! error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers.
}
class Derived10<T> extends Base2<T> {

View File

@@ -1,17 +0,0 @@
tests/cases/conformance/classes/members/privateNames/privateNameBadSuper.ts(4,5): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers.
==== tests/cases/conformance/classes/members/privateNames/privateNameBadSuper.ts (1 errors) ====
class B {};
class A extends B {
#x;
constructor() {
~~~~~~~~~~~~~~~
void 0; // Error: 'super' call must come first
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
super();
~~~~~~~~~~~~~~~~
}
~~~~~
!!! error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers.
}

View File

@@ -1,70 +0,0 @@
tests/cases/compiler/strictModeInConstructor.ts(27,5): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers.
==== tests/cases/compiler/strictModeInConstructor.ts (1 errors) ====
class A {
}
class B extends A {
public s: number = 9;
constructor () {
"use strict"; // No error
super();
}
}
class C extends A {
public s: number = 9;
constructor () {
super(); // No error
"use strict";
}
}
class D extends A {
public s: number = 9;
constructor () {
~~~~~~~~~~~~~~~~
var x = 1; // Error
~~~~~~~~~~~~~~~~~~~~~~~~~~~
super();
~~~~~~~~~~~~~~~~
"use strict";
~~~~~~~~~~~~~~~~~~~~~
}
~~~~~
!!! error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers.
}
class Bs extends A {
public static s: number = 9;
constructor () {
"use strict"; // No error
super();
}
}
class Cs extends A {
public static s: number = 9;
constructor () {
super(); // No error
"use strict";
}
}
class Ds extends A {
public static s: number = 9;
constructor () {
var x = 1; // no Error
super();
"use strict";
}
}