diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts index 3cf912dfb47..a602d6c0486 100644 --- a/src/compiler/transformers/utilities.ts +++ b/src/compiler/transformers/utilities.ts @@ -294,10 +294,12 @@ namespace ts { return index; } - const statement = statements[index]; - if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCall((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; diff --git a/tests/baselines/reference/classUpdateTests.js b/tests/baselines/reference/classUpdateTests.js index 077bd62bfa4..916ac9baa47 100644 --- a/tests/baselines/reference/classUpdateTests.js +++ b/tests/baselines/reference/classUpdateTests.js @@ -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; diff --git a/tests/baselines/reference/derivedClassParameterProperties.js b/tests/baselines/reference/derivedClassParameterProperties.js index f13be2bd7f6..a3213b0ebbd 100644 --- a/tests/baselines/reference/derivedClassParameterProperties.js +++ b/tests/baselines/reference/derivedClassParameterProperties.js @@ -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; diff --git a/tests/baselines/reference/emitCodeBeforeSuperCall.js b/tests/baselines/reference/emitCodeBeforeSuperCall.js new file mode 100644 index 00000000000..1c5f63e6377 --- /dev/null +++ b/tests/baselines/reference/emitCodeBeforeSuperCall.js @@ -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; + } +} diff --git a/tests/baselines/reference/emitCodeBeforeSuperCall.symbols b/tests/baselines/reference/emitCodeBeforeSuperCall.symbols new file mode 100644 index 00000000000..a79857ba65a --- /dev/null +++ b/tests/baselines/reference/emitCodeBeforeSuperCall.symbols @@ -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)) + } +} + diff --git a/tests/baselines/reference/emitCodeBeforeSuperCall.types b/tests/baselines/reference/emitCodeBeforeSuperCall.types new file mode 100644 index 00000000000..49f5c079513 --- /dev/null +++ b/tests/baselines/reference/emitCodeBeforeSuperCall.types @@ -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 + } +} + diff --git a/tests/baselines/reference/emitCodeBeforeSuperCall2.js b/tests/baselines/reference/emitCodeBeforeSuperCall2.js new file mode 100644 index 00000000000..43bf2c1e82c --- /dev/null +++ b/tests/baselines/reference/emitCodeBeforeSuperCall2.js @@ -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)); diff --git a/tests/baselines/reference/emitCodeBeforeSuperCall2.symbols b/tests/baselines/reference/emitCodeBeforeSuperCall2.symbols new file mode 100644 index 00000000000..8502639b32a --- /dev/null +++ b/tests/baselines/reference/emitCodeBeforeSuperCall2.symbols @@ -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)) +} + diff --git a/tests/baselines/reference/emitCodeBeforeSuperCall2.types b/tests/baselines/reference/emitCodeBeforeSuperCall2.types new file mode 100644 index 00000000000..6aef3c503cf --- /dev/null +++ b/tests/baselines/reference/emitCodeBeforeSuperCall2.types @@ -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 +} + diff --git a/tests/baselines/reference/emitCodeBeforeSuperCallWithDefineFields.js b/tests/baselines/reference/emitCodeBeforeSuperCallWithDefineFields.js new file mode 100644 index 00000000000..f84a843ddcd --- /dev/null +++ b/tests/baselines/reference/emitCodeBeforeSuperCallWithDefineFields.js @@ -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; + } +} diff --git a/tests/baselines/reference/emitCodeBeforeSuperCallWithDefineFields.symbols b/tests/baselines/reference/emitCodeBeforeSuperCallWithDefineFields.symbols new file mode 100644 index 00000000000..50260f261b6 --- /dev/null +++ b/tests/baselines/reference/emitCodeBeforeSuperCallWithDefineFields.symbols @@ -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)) + } +} + diff --git a/tests/baselines/reference/emitCodeBeforeSuperCallWithDefineFields.types b/tests/baselines/reference/emitCodeBeforeSuperCallWithDefineFields.types new file mode 100644 index 00000000000..94dfd93cf86 --- /dev/null +++ b/tests/baselines/reference/emitCodeBeforeSuperCallWithDefineFields.types @@ -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 + } +} + diff --git a/tests/baselines/reference/emitStatementsBeforeSuperCall.js b/tests/baselines/reference/emitStatementsBeforeSuperCall.js new file mode 100644 index 00000000000..72b3e7b4836 --- /dev/null +++ b/tests/baselines/reference/emitStatementsBeforeSuperCall.js @@ -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; + } +} diff --git a/tests/baselines/reference/emitStatementsBeforeSuperCall.symbols b/tests/baselines/reference/emitStatementsBeforeSuperCall.symbols new file mode 100644 index 00000000000..1a76d236318 --- /dev/null +++ b/tests/baselines/reference/emitStatementsBeforeSuperCall.symbols @@ -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)) + } +} + diff --git a/tests/baselines/reference/emitStatementsBeforeSuperCall.types b/tests/baselines/reference/emitStatementsBeforeSuperCall.types new file mode 100644 index 00000000000..ab731b040ef --- /dev/null +++ b/tests/baselines/reference/emitStatementsBeforeSuperCall.types @@ -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 + } +} + diff --git a/tests/baselines/reference/emitStatementsBeforeSuperCallWithDefineFields.js b/tests/baselines/reference/emitStatementsBeforeSuperCallWithDefineFields.js new file mode 100644 index 00000000000..685c7562d6d --- /dev/null +++ b/tests/baselines/reference/emitStatementsBeforeSuperCallWithDefineFields.js @@ -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; + } +} diff --git a/tests/baselines/reference/emitStatementsBeforeSuperCallWithDefineFields.symbols b/tests/baselines/reference/emitStatementsBeforeSuperCallWithDefineFields.symbols new file mode 100644 index 00000000000..106aa7bc343 --- /dev/null +++ b/tests/baselines/reference/emitStatementsBeforeSuperCallWithDefineFields.symbols @@ -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)) + } +} + diff --git a/tests/baselines/reference/emitStatementsBeforeSuperCallWithDefineFields.types b/tests/baselines/reference/emitStatementsBeforeSuperCallWithDefineFields.types new file mode 100644 index 00000000000..29a20cbbdc0 --- /dev/null +++ b/tests/baselines/reference/emitStatementsBeforeSuperCallWithDefineFields.types @@ -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 + } +} + diff --git a/tests/baselines/reference/privateNameBadSuper.js b/tests/baselines/reference/privateNameBadSuper.js index be1b0e6ea61..07d8c2324f5 100644 --- a/tests/baselines/reference/privateNameBadSuper.js +++ b/tests/baselines/reference/privateNameBadSuper.js @@ -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(); diff --git a/tests/baselines/reference/strictModeInConstructor.js b/tests/baselines/reference/strictModeInConstructor.js index 4356793d3d2..d7e877eda2f 100644 --- a/tests/baselines/reference/strictModeInConstructor.js +++ b/tests/baselines/reference/strictModeInConstructor.js @@ -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; } diff --git a/tests/cases/conformance/classes/constructorDeclarations/superCalls/emitStatementsBeforeSuperCall.ts b/tests/cases/conformance/classes/constructorDeclarations/superCalls/emitStatementsBeforeSuperCall.ts new file mode 100644 index 00000000000..3c3559808b1 --- /dev/null +++ b/tests/cases/conformance/classes/constructorDeclarations/superCalls/emitStatementsBeforeSuperCall.ts @@ -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; + } +} diff --git a/tests/cases/conformance/classes/constructorDeclarations/superCalls/emitStatementsBeforeSuperCallWithDefineFields.ts b/tests/cases/conformance/classes/constructorDeclarations/superCalls/emitStatementsBeforeSuperCallWithDefineFields.ts new file mode 100644 index 00000000000..f1736ac8a9f --- /dev/null +++ b/tests/cases/conformance/classes/constructorDeclarations/superCalls/emitStatementsBeforeSuperCallWithDefineFields.ts @@ -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; + } +}