diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index ad016972d0..3c7f3539e7 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -1024,8 +1024,11 @@ namespace ts { } } - // Return the result if we have an immediate super() call on the last statement. - if (superCallExpression && statementOffset === ctorStatements.length - 1) { + // Return the result if we have an immediate super() call on the last statement, + // but only if the constructor itself doesn't use 'this' elsewhere. + if (superCallExpression + && statementOffset === ctorStatements.length - 1 + && !(ctor.transformFlags & (TransformFlags.ContainsLexicalThis | TransformFlags.ContainsCapturedLexicalThis))) { const returnStatement = createReturn(superCallExpression); if (superCallExpression.kind !== SyntaxKind.BinaryExpression diff --git a/tests/baselines/reference/arrowFunctionContexts.js b/tests/baselines/reference/arrowFunctionContexts.js index 64727398f7..1af0797b41 100644 --- a/tests/baselines/reference/arrowFunctionContexts.js +++ b/tests/baselines/reference/arrowFunctionContexts.js @@ -116,7 +116,8 @@ var Base = (function () { var Derived = (function (_super) { __extends(Derived, _super); function Derived() { - return _super.call(this, function () { return _this; }) || this; + var _this = _super.call(this, function () { return _this; }) || this; + return _this; } return Derived; }(Base)); @@ -157,7 +158,8 @@ var M2; var Derived = (function (_super) { __extends(Derived, _super); function Derived() { - return _super.call(this, function () { return _this; }) || this; + var _this = _super.call(this, function () { return _this; }) || this; + return _this; } return Derived; }(Base)); diff --git a/tests/baselines/reference/captureSuperPropertyAccessInSuperCall01.errors.txt b/tests/baselines/reference/captureSuperPropertyAccessInSuperCall01.errors.txt new file mode 100644 index 0000000000..6e2b7ef578 --- /dev/null +++ b/tests/baselines/reference/captureSuperPropertyAccessInSuperCall01.errors.txt @@ -0,0 +1,17 @@ +tests/cases/compiler/captureSuperPropertyAccessInSuperCall01.ts(9,24): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class. + + +==== tests/cases/compiler/captureSuperPropertyAccessInSuperCall01.ts (1 errors) ==== + class A { + constructor(f: () => string) { + } + public blah(): string { return ""; } + } + + class B extends A { + constructor() { + super(() => { return super.blah(); }) + ~~~~~ +!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class. + } + } \ No newline at end of file diff --git a/tests/baselines/reference/captureSuperPropertyAccessInSuperCall01.js b/tests/baselines/reference/captureSuperPropertyAccessInSuperCall01.js new file mode 100644 index 0000000000..7fde44106c --- /dev/null +++ b/tests/baselines/reference/captureSuperPropertyAccessInSuperCall01.js @@ -0,0 +1,33 @@ +//// [captureSuperPropertyAccessInSuperCall01.ts] +class A { + constructor(f: () => string) { + } + public blah(): string { return ""; } +} + +class B extends A { + constructor() { + super(() => { return super.blah(); }) + } +} + +//// [captureSuperPropertyAccessInSuperCall01.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var A = (function () { + function A(f) { + } + A.prototype.blah = function () { return ""; }; + return A; +}()); +var B = (function (_super) { + __extends(B, _super); + function B() { + var _this = _super.call(this, function () { return _super.blah.call(_this); }) || this; + return _this; + } + return B; +}(A)); diff --git a/tests/baselines/reference/captureThisInSuperCall.js b/tests/baselines/reference/captureThisInSuperCall.js index 2c4df5db96..069871f598 100644 --- a/tests/baselines/reference/captureThisInSuperCall.js +++ b/tests/baselines/reference/captureThisInSuperCall.js @@ -22,7 +22,8 @@ var A = (function () { var B = (function (_super) { __extends(B, _super); function B() { - return _super.call(this, { test: function () { return _this.someMethod(); } }) || this; + var _this = _super.call(this, { test: function () { return _this.someMethod(); } }) || this; + return _this; } B.prototype.someMethod = function () { }; return B; diff --git a/tests/baselines/reference/checkSuperCallBeforeThisAccessing5.js b/tests/baselines/reference/checkSuperCallBeforeThisAccessing5.js index 4cce975d6d..ded73f57ba 100644 --- a/tests/baselines/reference/checkSuperCallBeforeThisAccessing5.js +++ b/tests/baselines/reference/checkSuperCallBeforeThisAccessing5.js @@ -25,7 +25,8 @@ var Based = (function () { var Derived = (function (_super) { __extends(Derived, _super); function Derived() { - return _super.call(this, this.x) || this; + var _this = _super.call(this, _this.x) || this; + return _this; } return Derived; }(Based)); diff --git a/tests/baselines/reference/checkSuperCallBeforeThisAccessing7.js b/tests/baselines/reference/checkSuperCallBeforeThisAccessing7.js index ca12c16e04..364aed4d4b 100644 --- a/tests/baselines/reference/checkSuperCallBeforeThisAccessing7.js +++ b/tests/baselines/reference/checkSuperCallBeforeThisAccessing7.js @@ -23,7 +23,8 @@ var Base = (function () { var Super = (function (_super) { __extends(Super, _super); function Super() { - return _super.call(this, (function () { return _this; })) || this; + var _this = _super.call(this, (function () { return _this; })) || this; + return _this; } return Super; }(Base)); diff --git a/tests/baselines/reference/derivedClassSuperCallsWithThisArg.js b/tests/baselines/reference/derivedClassSuperCallsWithThisArg.js index 504d414a60..039e25919f 100644 --- a/tests/baselines/reference/derivedClassSuperCallsWithThisArg.js +++ b/tests/baselines/reference/derivedClassSuperCallsWithThisArg.js @@ -42,7 +42,8 @@ var Base = (function () { var Derived = (function (_super) { __extends(Derived, _super); function Derived() { - return _super.call(this, _this) || this; + var _this = _super.call(this, _this) || this; + return _this; } return Derived; }(Base)); diff --git a/tests/baselines/reference/superCallBeforeThisAccessing2.js b/tests/baselines/reference/superCallBeforeThisAccessing2.js index 7331718a9e..91cc3d28dd 100644 --- a/tests/baselines/reference/superCallBeforeThisAccessing2.js +++ b/tests/baselines/reference/superCallBeforeThisAccessing2.js @@ -24,7 +24,8 @@ var Base = (function () { var D = (function (_super) { __extends(D, _super); function D() { - return _super.call(this, function () { _this._t; }) || this; + var _this = _super.call(this, function () { _this._t; }) || this; + return _this; } return D; }(Base)); diff --git a/tests/baselines/reference/superCallBeforeThisAccessing6.js b/tests/baselines/reference/superCallBeforeThisAccessing6.js index e4dfb3f714..4eb8e5266c 100644 --- a/tests/baselines/reference/superCallBeforeThisAccessing6.js +++ b/tests/baselines/reference/superCallBeforeThisAccessing6.js @@ -24,7 +24,8 @@ var Base = (function () { var D = (function (_super) { __extends(D, _super); function D() { - return _super.call(this, this) || this; + var _this = _super.call(this, _this) || this; + return _this; } return D; }(Base)); diff --git a/tests/baselines/reference/superPropertyAccessInSuperCall01.errors.txt b/tests/baselines/reference/superPropertyAccessInSuperCall01.errors.txt new file mode 100644 index 0000000000..f7449a26d5 --- /dev/null +++ b/tests/baselines/reference/superPropertyAccessInSuperCall01.errors.txt @@ -0,0 +1,17 @@ +tests/cases/compiler/superPropertyAccessInSuperCall01.ts(9,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class. + + +==== tests/cases/compiler/superPropertyAccessInSuperCall01.ts (1 errors) ==== + class A { + constructor(f: string) { + } + public blah(): string { return ""; } + } + + class B extends A { + constructor() { + super(super.blah()) + ~~~~~ +!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class. + } + } \ No newline at end of file diff --git a/tests/baselines/reference/superPropertyAccessInSuperCall01.js b/tests/baselines/reference/superPropertyAccessInSuperCall01.js new file mode 100644 index 0000000000..f0dc925682 --- /dev/null +++ b/tests/baselines/reference/superPropertyAccessInSuperCall01.js @@ -0,0 +1,33 @@ +//// [superPropertyAccessInSuperCall01.ts] +class A { + constructor(f: string) { + } + public blah(): string { return ""; } +} + +class B extends A { + constructor() { + super(super.blah()) + } +} + +//// [superPropertyAccessInSuperCall01.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var A = (function () { + function A(f) { + } + A.prototype.blah = function () { return ""; }; + return A; +}()); +var B = (function (_super) { + __extends(B, _super); + function B() { + var _this = _super.call(this, _super.blah.call(_this)) || this; + return _this; + } + return B; +}(A)); diff --git a/tests/baselines/reference/superPropertyInConstructorBeforeSuperCall.js b/tests/baselines/reference/superPropertyInConstructorBeforeSuperCall.js index 15bc0c40f3..3fcf7167ee 100644 --- a/tests/baselines/reference/superPropertyInConstructorBeforeSuperCall.js +++ b/tests/baselines/reference/superPropertyInConstructorBeforeSuperCall.js @@ -40,7 +40,8 @@ var C1 = (function (_super) { var C2 = (function (_super) { __extends(C2, _super); function C2() { - return _super.call(this, _super.x.call(_this)) || this; + var _this = _super.call(this, _super.x.call(_this)) || this; + return _this; } return C2; }(B)); diff --git a/tests/baselines/reference/thisInInvalidContexts.js b/tests/baselines/reference/thisInInvalidContexts.js index 1fc1c73463..7f299fd7e1 100644 --- a/tests/baselines/reference/thisInInvalidContexts.js +++ b/tests/baselines/reference/thisInInvalidContexts.js @@ -70,7 +70,8 @@ var ClassWithNoInitializer = (function (_super) { __extends(ClassWithNoInitializer, _super); //'this' in optional super call function ClassWithNoInitializer() { - return _super.call(this, _this) || this; + var _this = _super.call(this, _this) || this; + return _this; } return ClassWithNoInitializer; }(BaseErrClass)); diff --git a/tests/baselines/reference/thisInInvalidContextsExternalModule.js b/tests/baselines/reference/thisInInvalidContextsExternalModule.js index f8cb6d695d..65a1ef1eee 100644 --- a/tests/baselines/reference/thisInInvalidContextsExternalModule.js +++ b/tests/baselines/reference/thisInInvalidContextsExternalModule.js @@ -71,7 +71,8 @@ var ClassWithNoInitializer = (function (_super) { __extends(ClassWithNoInitializer, _super); //'this' in optional super call function ClassWithNoInitializer() { - return _super.call(this, _this) || this; + var _this = _super.call(this, _this) || this; + return _this; } return ClassWithNoInitializer; }(BaseErrClass)); diff --git a/tests/baselines/reference/thisInSuperCall.js b/tests/baselines/reference/thisInSuperCall.js index 2a4d15973a..1c1f11ffbc 100644 --- a/tests/baselines/reference/thisInSuperCall.js +++ b/tests/baselines/reference/thisInSuperCall.js @@ -36,7 +36,8 @@ var Base = (function () { var Foo = (function (_super) { __extends(Foo, _super); function Foo() { - return _super.call(this, _this) || this; + var _this = _super.call(this, _this) || this; + return _this; } return Foo; }(Base)); diff --git a/tests/baselines/reference/thisInSuperCall2.js b/tests/baselines/reference/thisInSuperCall2.js index eabfa9d562..6288082ed6 100644 --- a/tests/baselines/reference/thisInSuperCall2.js +++ b/tests/baselines/reference/thisInSuperCall2.js @@ -33,7 +33,8 @@ var Base = (function () { var Foo = (function (_super) { __extends(Foo, _super); function Foo() { - return _super.call(this, _this) || this; + var _this = _super.call(this, _this) || this; + return _this; } return Foo; }(Base)); diff --git a/tests/baselines/reference/validUseOfThisInSuper.js b/tests/baselines/reference/validUseOfThisInSuper.js index 483e905b48..bbd564db36 100644 --- a/tests/baselines/reference/validUseOfThisInSuper.js +++ b/tests/baselines/reference/validUseOfThisInSuper.js @@ -24,7 +24,8 @@ var Base = (function () { var Super = (function (_super) { __extends(Super, _super); function Super() { - return _super.call(this, (function () { return _this; })()) || this; + var _this = _super.call(this, (function () { return _this; })()) || this; + return _this; } return Super; }(Base)); diff --git a/tests/cases/compiler/captureSuperPropertyAccessInSuperCall01.ts b/tests/cases/compiler/captureSuperPropertyAccessInSuperCall01.ts new file mode 100644 index 0000000000..e60b9801c0 --- /dev/null +++ b/tests/cases/compiler/captureSuperPropertyAccessInSuperCall01.ts @@ -0,0 +1,11 @@ +class A { + constructor(f: () => string) { + } + public blah(): string { return ""; } +} + +class B extends A { + constructor() { + super(() => { return super.blah(); }) + } +} \ No newline at end of file diff --git a/tests/cases/compiler/superPropertyAccessInSuperCall01.ts b/tests/cases/compiler/superPropertyAccessInSuperCall01.ts new file mode 100644 index 0000000000..38373e9eef --- /dev/null +++ b/tests/cases/compiler/superPropertyAccessInSuperCall01.ts @@ -0,0 +1,11 @@ +class A { + constructor(f: string) { + } + public blah(): string { return ""; } +} + +class B extends A { + constructor() { + super(super.blah()) + } +} \ No newline at end of file