mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
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:
@@ -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;
|
||||
}
|
||||
|
||||
+23
@@ -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;
|
||||
}
|
||||
}
|
||||
+23
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user