Emit statements before super (#36417)

* Emit statements before super

When statements come before super, Typescript's emit is incorrect,
whether there is an error or not. This change preserves statements that
come before super whether there is an error or not.

Here is the case with no errors:

```ts
class Test extends Array {
  p: number
  constructor() {
    console.log("p is initialised in the constructor below super()")
    super()
    this.p = 1
  }
}
```

Notice that `p` is manually initialised in the constructor after
`super()` instead of at the property declaration.

* Update baselines

Parameter properties in the error case now move below the super call.
This is an improvement because it means the code is more likely to execute
correctly.

* remove outdated comments
This commit is contained in:
Nathan Shively-Sanders
2020-01-24 14:52:48 -08:00
committed by GitHub
parent 98110904da
commit 43fc19c958
22 changed files with 816 additions and 12 deletions
+6 -4
View File
@@ -294,10 +294,12 @@ namespace ts {
return index;
}
const statement = statements[index];
if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCall((<ExpressionStatement>statement).expression)) {
result.push(visitNode(statement, visitor, isStatement));
return index + 1;
const superIndex = findIndex(statements, s => isExpressionStatement(s) && isSuperCall(s.expression), index);
if (superIndex > -1) {
for (let i = index; i <= superIndex; i++) {
result.push(visitNode(statements[i], visitor, isStatement));
}
return superIndex + 1;
}
return index;
@@ -214,9 +214,9 @@ var K = /** @class */ (function (_super) {
__extends(K, _super);
function K(p1) {
var _this = this;
_this.p1 = p1;
var i = 0;
_this = _super.call(this) || this;
_this.p1 = p1;
return _this;
}
return K;
@@ -234,9 +234,9 @@ var M = /** @class */ (function (_super) {
__extends(M, _super);
function M(p1) {
var _this = this;
_this.p1 = p1;
var i = 0;
_this = _super.call(this) || this;
_this.p1 = p1;
return _this;
}
return M;
@@ -128,9 +128,9 @@ var Derived2 = /** @class */ (function (_super) {
__extends(Derived2, _super);
function Derived2(y) {
var _this = this;
_this.y = y;
var a = 1;
_this = _super.call(this) || this; // error
_this.y = y;
return _this;
}
return Derived2;
@@ -149,9 +149,9 @@ var Derived4 = /** @class */ (function (_super) {
__extends(Derived4, _super);
function Derived4(y) {
var _this = this;
_this.a = 1;
var b = 2;
_this = _super.call(this) || this; // error
_this.a = 1;
return _this;
}
return Derived4;
@@ -181,10 +181,10 @@ var Derived7 = /** @class */ (function (_super) {
__extends(Derived7, _super);
function Derived7(y) {
var _this = this;
_this.a = 1;
_this.a = 3;
_this.b = 3;
_this = _super.call(this) || this; // error
_this.a = 1;
return _this;
}
return Derived7;
@@ -210,10 +210,10 @@ var Derived9 = /** @class */ (function (_super) {
__extends(Derived9, _super);
function Derived9(y) {
var _this = this;
_this.a = 1;
_this.a = 3;
_this.b = 3;
_this = _super.call(this) || this; // error
_this.a = 1;
return _this;
}
return Derived9;
@@ -0,0 +1,53 @@
//// [emitCodeBeforeSuperCall.ts]
// TODO: With false, master is correct for `Test` but incorrect for `Sub`.
// `Test` is correct because classic emit doesn't emit for definition and `Test`
// doesn't need to emit any code for initialisation because it's already
// part of the user code
class Base {
}
class Sub extends Base {
// @ts-ignore
constructor(public p: number) {
console.log('hi');
super();
}
field = 0;
}
class Test extends Base {
prop: number;
// @ts-ignore
constructor(public p: number) {
1; // Any statements here break it
super();
this.prop = 1;
}
}
//// [emitCodeBeforeSuperCall.js]
// TODO: With false, master is correct for `Test` but incorrect for `Sub`.
// `Test` is correct because classic emit doesn't emit for definition and `Test`
// doesn't need to emit any code for initialisation because it's already
// part of the user code
class Base {
}
class Sub extends Base {
// @ts-ignore
constructor(p) {
console.log('hi');
super();
this.p = p;
this.field = 0;
}
}
class Test extends Base {
// @ts-ignore
constructor(p) {
1; // Any statements here break it
super();
this.p = p;
this.prop = 1;
}
}
@@ -0,0 +1,51 @@
=== tests/cases/conformance/classes/constructorDeclarations/superCalls/emitCodeBeforeSuperCall.ts ===
// TODO: With false, master is correct for `Test` but incorrect for `Sub`.
// `Test` is correct because classic emit doesn't emit for definition and `Test`
// doesn't need to emit any code for initialisation because it's already
// part of the user code
class Base {
>Base : Symbol(Base, Decl(emitCodeBeforeSuperCall.ts, 0, 0))
}
class Sub extends Base {
>Sub : Symbol(Sub, Decl(emitCodeBeforeSuperCall.ts, 6, 1))
>Base : Symbol(Base, Decl(emitCodeBeforeSuperCall.ts, 0, 0))
// @ts-ignore
constructor(public p: number) {
>p : Symbol(Sub.p, Decl(emitCodeBeforeSuperCall.ts, 9, 16))
console.log('hi');
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
super();
>super : Symbol(Base, Decl(emitCodeBeforeSuperCall.ts, 0, 0))
}
field = 0;
>field : Symbol(Sub.field, Decl(emitCodeBeforeSuperCall.ts, 12, 5))
}
class Test extends Base {
>Test : Symbol(Test, Decl(emitCodeBeforeSuperCall.ts, 14, 1))
>Base : Symbol(Base, Decl(emitCodeBeforeSuperCall.ts, 0, 0))
prop: number;
>prop : Symbol(Test.prop, Decl(emitCodeBeforeSuperCall.ts, 16, 25))
// @ts-ignore
constructor(public p: number) {
>p : Symbol(Test.p, Decl(emitCodeBeforeSuperCall.ts, 19, 16))
1; // Any statements here break it
super();
>super : Symbol(Base, Decl(emitCodeBeforeSuperCall.ts, 0, 0))
this.prop = 1;
>this.prop : Symbol(Test.prop, Decl(emitCodeBeforeSuperCall.ts, 16, 25))
>this : Symbol(Test, Decl(emitCodeBeforeSuperCall.ts, 14, 1))
>prop : Symbol(Test.prop, Decl(emitCodeBeforeSuperCall.ts, 16, 25))
}
}
@@ -0,0 +1,60 @@
=== tests/cases/conformance/classes/constructorDeclarations/superCalls/emitCodeBeforeSuperCall.ts ===
// TODO: With false, master is correct for `Test` but incorrect for `Sub`.
// `Test` is correct because classic emit doesn't emit for definition and `Test`
// doesn't need to emit any code for initialisation because it's already
// part of the user code
class Base {
>Base : Base
}
class Sub extends Base {
>Sub : Sub
>Base : Base
// @ts-ignore
constructor(public p: number) {
>p : number
console.log('hi');
>console.log('hi') : void
>console.log : (message?: any, ...optionalParams: any[]) => void
>console : Console
>log : (message?: any, ...optionalParams: any[]) => void
>'hi' : "hi"
super();
>super() : void
>super : typeof Base
}
field = 0;
>field : number
>0 : 0
}
class Test extends Base {
>Test : Test
>Base : Base
prop: number;
>prop : number
// @ts-ignore
constructor(public p: number) {
>p : number
1; // Any statements here break it
>1 : 1
super();
>super() : void
>super : typeof Base
this.prop = 1;
>this.prop = 1 : 1
>this.prop : number
>this : this
>prop : number
>1 : 1
}
}
@@ -0,0 +1,49 @@
//// [emitCodeBeforeSuperCall2.ts]
// TODO: With false, master is correct for `Test` but incorrect for `Sub`.
// `Test` is correct because classic emit doesn't emit for definition and `Test`
// doesn't need to emit any code for initialisation because it's already
// part of the user code
class BaseA {
public constructor(public x: number) { }
}
class DerivedA extends BaseA {
constructor(public x: number) { super(x); }
}
//// [emitCodeBeforeSuperCall2.js]
// TODO: With false, master is correct for `Test` but incorrect for `Sub`.
// `Test` is correct because classic emit doesn't emit for definition and `Test`
// doesn't need to emit any code for initialisation because it's already
// part of the user code
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var BaseA = /** @class */ (function () {
function BaseA(x) {
this.x = x;
}
return BaseA;
}());
var DerivedA = /** @class */ (function (_super) {
__extends(DerivedA, _super);
function DerivedA(x) {
var _this = this;
_this.x = x;
_this = _super.call(this, x) || this;
return _this;
}
return DerivedA;
}(BaseA));
@@ -0,0 +1,23 @@
=== tests/cases/conformance/classes/constructorDeclarations/superCalls/emitCodeBeforeSuperCall2.ts ===
// TODO: With false, master is correct for `Test` but incorrect for `Sub`.
// `Test` is correct because classic emit doesn't emit for definition and `Test`
// doesn't need to emit any code for initialisation because it's already
// part of the user code
class BaseA {
>BaseA : Symbol(BaseA, Decl(emitCodeBeforeSuperCall2.ts, 0, 0))
public constructor(public x: number) { }
>x : Symbol(BaseA.x, Decl(emitCodeBeforeSuperCall2.ts, 7, 23))
}
class DerivedA extends BaseA {
>DerivedA : Symbol(DerivedA, Decl(emitCodeBeforeSuperCall2.ts, 8, 1))
>BaseA : Symbol(BaseA, Decl(emitCodeBeforeSuperCall2.ts, 0, 0))
constructor(public x: number) { super(x); }
>x : Symbol(DerivedA.x, Decl(emitCodeBeforeSuperCall2.ts, 10, 16))
>super : Symbol(BaseA, Decl(emitCodeBeforeSuperCall2.ts, 0, 0))
>x : Symbol(x, Decl(emitCodeBeforeSuperCall2.ts, 10, 16))
}
@@ -0,0 +1,24 @@
=== tests/cases/conformance/classes/constructorDeclarations/superCalls/emitCodeBeforeSuperCall2.ts ===
// TODO: With false, master is correct for `Test` but incorrect for `Sub`.
// `Test` is correct because classic emit doesn't emit for definition and `Test`
// doesn't need to emit any code for initialisation because it's already
// part of the user code
class BaseA {
>BaseA : BaseA
public constructor(public x: number) { }
>x : number
}
class DerivedA extends BaseA {
>DerivedA : DerivedA
>BaseA : BaseA
constructor(public x: number) { super(x); }
>x : number
>super(x) : void
>super : typeof BaseA
>x : number
}
@@ -0,0 +1,74 @@
//// [emitCodeBeforeSuperCallWithDefineFields.ts]
// TODO: With false, master is correct for `Test` but incorrect for `Sub`.
// `Test` is correct because classic emit doesn't emit for definition and `Test`
// doesn't need to emit any code for initialisation because it's already
// part of the user code
class Base {
}
class Sub extends Base {
// @ts-ignore
constructor(public p: number) {
console.log('hi');
super();
}
field = 0;
}
class Test extends Base {
prop: number;
// @ts-ignore
constructor(public p: number) {
1; // Any statements here break it
super();
this.prop = 1;
}
}
//// [emitCodeBeforeSuperCallWithDefineFields.js]
// TODO: With false, master is correct for `Test` but incorrect for `Sub`.
// `Test` is correct because classic emit doesn't emit for definition and `Test`
// doesn't need to emit any code for initialisation because it's already
// part of the user code
class Base {
}
class Sub extends Base {
// @ts-ignore
constructor(p) {
console.log('hi');
super();
Object.defineProperty(this, "p", {
enumerable: true,
configurable: true,
writable: true,
value: p
});
Object.defineProperty(this, "field", {
enumerable: true,
configurable: true,
writable: true,
value: 0
});
}
}
class Test extends Base {
// @ts-ignore
constructor(p) {
1; // Any statements here break it
super();
Object.defineProperty(this, "p", {
enumerable: true,
configurable: true,
writable: true,
value: p
});
Object.defineProperty(this, "prop", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
this.prop = 1;
}
}
@@ -0,0 +1,51 @@
=== tests/cases/conformance/classes/constructorDeclarations/superCalls/emitCodeBeforeSuperCallWithDefineFields.ts ===
// TODO: With false, master is correct for `Test` but incorrect for `Sub`.
// `Test` is correct because classic emit doesn't emit for definition and `Test`
// doesn't need to emit any code for initialisation because it's already
// part of the user code
class Base {
>Base : Symbol(Base, Decl(emitCodeBeforeSuperCallWithDefineFields.ts, 0, 0))
}
class Sub extends Base {
>Sub : Symbol(Sub, Decl(emitCodeBeforeSuperCallWithDefineFields.ts, 6, 1))
>Base : Symbol(Base, Decl(emitCodeBeforeSuperCallWithDefineFields.ts, 0, 0))
// @ts-ignore
constructor(public p: number) {
>p : Symbol(Sub.p, Decl(emitCodeBeforeSuperCallWithDefineFields.ts, 9, 16))
console.log('hi');
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
super();
>super : Symbol(Base, Decl(emitCodeBeforeSuperCallWithDefineFields.ts, 0, 0))
}
field = 0;
>field : Symbol(Sub.field, Decl(emitCodeBeforeSuperCallWithDefineFields.ts, 12, 5))
}
class Test extends Base {
>Test : Symbol(Test, Decl(emitCodeBeforeSuperCallWithDefineFields.ts, 14, 1))
>Base : Symbol(Base, Decl(emitCodeBeforeSuperCallWithDefineFields.ts, 0, 0))
prop: number;
>prop : Symbol(Test.prop, Decl(emitCodeBeforeSuperCallWithDefineFields.ts, 16, 25))
// @ts-ignore
constructor(public p: number) {
>p : Symbol(Test.p, Decl(emitCodeBeforeSuperCallWithDefineFields.ts, 19, 16))
1; // Any statements here break it
super();
>super : Symbol(Base, Decl(emitCodeBeforeSuperCallWithDefineFields.ts, 0, 0))
this.prop = 1;
>this.prop : Symbol(Test.prop, Decl(emitCodeBeforeSuperCallWithDefineFields.ts, 16, 25))
>this : Symbol(Test, Decl(emitCodeBeforeSuperCallWithDefineFields.ts, 14, 1))
>prop : Symbol(Test.prop, Decl(emitCodeBeforeSuperCallWithDefineFields.ts, 16, 25))
}
}
@@ -0,0 +1,60 @@
=== tests/cases/conformance/classes/constructorDeclarations/superCalls/emitCodeBeforeSuperCallWithDefineFields.ts ===
// TODO: With false, master is correct for `Test` but incorrect for `Sub`.
// `Test` is correct because classic emit doesn't emit for definition and `Test`
// doesn't need to emit any code for initialisation because it's already
// part of the user code
class Base {
>Base : Base
}
class Sub extends Base {
>Sub : Sub
>Base : Base
// @ts-ignore
constructor(public p: number) {
>p : number
console.log('hi');
>console.log('hi') : void
>console.log : (message?: any, ...optionalParams: any[]) => void
>console : Console
>log : (message?: any, ...optionalParams: any[]) => void
>'hi' : "hi"
super();
>super() : void
>super : typeof Base
}
field = 0;
>field : number
>0 : 0
}
class Test extends Base {
>Test : Test
>Base : Base
prop: number;
>prop : number
// @ts-ignore
constructor(public p: number) {
>p : number
1; // Any statements here break it
>1 : 1
super();
>super() : void
>super : typeof Base
this.prop = 1;
>this.prop = 1 : 1
>this.prop : number
>this : this
>prop : number
>1 : 1
}
}
@@ -0,0 +1,44 @@
//// [emitStatementsBeforeSuperCall.ts]
class Base {
}
class Sub extends Base {
// @ts-ignore
constructor(public p: number) {
console.log('hi'); // should emit before super
super();
}
field = 0;
}
class Test extends Base {
prop: number;
// @ts-ignore
constructor(public p: number) {
1; // should emit before super
super();
this.prop = 1;
}
}
//// [emitStatementsBeforeSuperCall.js]
class Base {
}
class Sub extends Base {
// @ts-ignore
constructor(p) {
console.log('hi'); // should emit before super
super();
this.p = p;
this.field = 0;
}
}
class Test extends Base {
// @ts-ignore
constructor(p) {
1; // should emit before super
super();
this.p = p;
this.prop = 1;
}
}
@@ -0,0 +1,46 @@
=== tests/cases/conformance/classes/constructorDeclarations/superCalls/emitStatementsBeforeSuperCall.ts ===
class Base {
>Base : Symbol(Base, Decl(emitStatementsBeforeSuperCall.ts, 0, 0))
}
class Sub extends Base {
>Sub : Symbol(Sub, Decl(emitStatementsBeforeSuperCall.ts, 1, 1))
>Base : Symbol(Base, Decl(emitStatementsBeforeSuperCall.ts, 0, 0))
// @ts-ignore
constructor(public p: number) {
>p : Symbol(Sub.p, Decl(emitStatementsBeforeSuperCall.ts, 4, 16))
console.log('hi'); // should emit before super
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
super();
>super : Symbol(Base, Decl(emitStatementsBeforeSuperCall.ts, 0, 0))
}
field = 0;
>field : Symbol(Sub.field, Decl(emitStatementsBeforeSuperCall.ts, 7, 5))
}
class Test extends Base {
>Test : Symbol(Test, Decl(emitStatementsBeforeSuperCall.ts, 9, 1))
>Base : Symbol(Base, Decl(emitStatementsBeforeSuperCall.ts, 0, 0))
prop: number;
>prop : Symbol(Test.prop, Decl(emitStatementsBeforeSuperCall.ts, 11, 25))
// @ts-ignore
constructor(public p: number) {
>p : Symbol(Test.p, Decl(emitStatementsBeforeSuperCall.ts, 14, 16))
1; // should emit before super
super();
>super : Symbol(Base, Decl(emitStatementsBeforeSuperCall.ts, 0, 0))
this.prop = 1;
>this.prop : Symbol(Test.prop, Decl(emitStatementsBeforeSuperCall.ts, 11, 25))
>this : Symbol(Test, Decl(emitStatementsBeforeSuperCall.ts, 9, 1))
>prop : Symbol(Test.prop, Decl(emitStatementsBeforeSuperCall.ts, 11, 25))
}
}
@@ -0,0 +1,55 @@
=== tests/cases/conformance/classes/constructorDeclarations/superCalls/emitStatementsBeforeSuperCall.ts ===
class Base {
>Base : Base
}
class Sub extends Base {
>Sub : Sub
>Base : Base
// @ts-ignore
constructor(public p: number) {
>p : number
console.log('hi'); // should emit before super
>console.log('hi') : void
>console.log : (message?: any, ...optionalParams: any[]) => void
>console : Console
>log : (message?: any, ...optionalParams: any[]) => void
>'hi' : "hi"
super();
>super() : void
>super : typeof Base
}
field = 0;
>field : number
>0 : 0
}
class Test extends Base {
>Test : Test
>Base : Base
prop: number;
>prop : number
// @ts-ignore
constructor(public p: number) {
>p : number
1; // should emit before super
>1 : 1
super();
>super() : void
>super : typeof Base
this.prop = 1;
>this.prop = 1 : 1
>this.prop : number
>this : this
>prop : number
>1 : 1
}
}
@@ -0,0 +1,65 @@
//// [emitStatementsBeforeSuperCallWithDefineFields.ts]
class Base {
}
class Sub extends Base {
// @ts-ignore
constructor(public p: number) {
console.log('hi');
super();
}
field = 0;
}
class Test extends Base {
prop: number;
// @ts-ignore
constructor(public p: number) {
1;
super();
this.prop = 1;
}
}
//// [emitStatementsBeforeSuperCallWithDefineFields.js]
class Base {
}
class Sub extends Base {
// @ts-ignore
constructor(p) {
console.log('hi');
super();
Object.defineProperty(this, "p", {
enumerable: true,
configurable: true,
writable: true,
value: p
});
Object.defineProperty(this, "field", {
enumerable: true,
configurable: true,
writable: true,
value: 0
});
}
}
class Test extends Base {
// @ts-ignore
constructor(p) {
1;
super();
Object.defineProperty(this, "p", {
enumerable: true,
configurable: true,
writable: true,
value: p
});
Object.defineProperty(this, "prop", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
this.prop = 1;
}
}
@@ -0,0 +1,46 @@
=== tests/cases/conformance/classes/constructorDeclarations/superCalls/emitStatementsBeforeSuperCallWithDefineFields.ts ===
class Base {
>Base : Symbol(Base, Decl(emitStatementsBeforeSuperCallWithDefineFields.ts, 0, 0))
}
class Sub extends Base {
>Sub : Symbol(Sub, Decl(emitStatementsBeforeSuperCallWithDefineFields.ts, 1, 1))
>Base : Symbol(Base, Decl(emitStatementsBeforeSuperCallWithDefineFields.ts, 0, 0))
// @ts-ignore
constructor(public p: number) {
>p : Symbol(Sub.p, Decl(emitStatementsBeforeSuperCallWithDefineFields.ts, 4, 16))
console.log('hi');
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
super();
>super : Symbol(Base, Decl(emitStatementsBeforeSuperCallWithDefineFields.ts, 0, 0))
}
field = 0;
>field : Symbol(Sub.field, Decl(emitStatementsBeforeSuperCallWithDefineFields.ts, 7, 5))
}
class Test extends Base {
>Test : Symbol(Test, Decl(emitStatementsBeforeSuperCallWithDefineFields.ts, 9, 1))
>Base : Symbol(Base, Decl(emitStatementsBeforeSuperCallWithDefineFields.ts, 0, 0))
prop: number;
>prop : Symbol(Test.prop, Decl(emitStatementsBeforeSuperCallWithDefineFields.ts, 11, 25))
// @ts-ignore
constructor(public p: number) {
>p : Symbol(Test.p, Decl(emitStatementsBeforeSuperCallWithDefineFields.ts, 14, 16))
1;
super();
>super : Symbol(Base, Decl(emitStatementsBeforeSuperCallWithDefineFields.ts, 0, 0))
this.prop = 1;
>this.prop : Symbol(Test.prop, Decl(emitStatementsBeforeSuperCallWithDefineFields.ts, 11, 25))
>this : Symbol(Test, Decl(emitStatementsBeforeSuperCallWithDefineFields.ts, 9, 1))
>prop : Symbol(Test.prop, Decl(emitStatementsBeforeSuperCallWithDefineFields.ts, 11, 25))
}
}
@@ -0,0 +1,55 @@
=== tests/cases/conformance/classes/constructorDeclarations/superCalls/emitStatementsBeforeSuperCallWithDefineFields.ts ===
class Base {
>Base : Base
}
class Sub extends Base {
>Sub : Sub
>Base : Base
// @ts-ignore
constructor(public p: number) {
>p : number
console.log('hi');
>console.log('hi') : void
>console.log : (message?: any, ...optionalParams: any[]) => void
>console : Console
>log : (message?: any, ...optionalParams: any[]) => void
>'hi' : "hi"
super();
>super() : void
>super : typeof Base
}
field = 0;
>field : number
>0 : 0
}
class Test extends Base {
>Test : Test
>Base : Base
prop: number;
>prop : number
// @ts-ignore
constructor(public p: number) {
>p : number
1;
>1 : 1
super();
>super() : void
>super : typeof Base
this.prop = 1;
>this.prop = 1 : 1
>this.prop : number
>this : this
>prop : number
>1 : 1
}
}
@@ -15,9 +15,9 @@ class B {
;
class A extends B {
constructor() {
_x.set(this, void 0);
void 0; // Error: 'super' call must come first
super();
_x.set(this, void 0);
}
}
_x = new WeakMap();
@@ -103,9 +103,9 @@ var D = /** @class */ (function (_super) {
__extends(D, _super);
function D() {
var _this = this;
_this.s = 9;
var x = 1; // Error
_this = _super.call(this) || this;
_this.s = 9;
"use strict";
return _this;
}
@@ -0,0 +1,23 @@
// @useDefineForClassFields: false
// @target: es2015
class Base {
}
class Sub extends Base {
// @ts-ignore
constructor(public p: number) {
console.log('hi'); // should emit before super
super();
}
field = 0;
}
class Test extends Base {
prop: number;
// @ts-ignore
constructor(public p: number) {
1; // should emit before super
super();
this.prop = 1;
}
}
@@ -0,0 +1,23 @@
// @useDefineForClassFields: true
// @target: es2015
class Base {
}
class Sub extends Base {
// @ts-ignore
constructor(public p: number) {
console.log('hi');
super();
}
field = 0;
}
class Test extends Base {
prop: number;
// @ts-ignore
constructor(public p: number) {
1;
super();
this.prop = 1;
}
}