From 9abcddc21e4dd9bb9b0519b6938f5f662c8c7b6c Mon Sep 17 00:00:00 2001 From: rbuckton Date: Wed, 4 Jan 2017 19:16:33 -0800 Subject: [PATCH] Simplify emit for syntactic 'extends null' case --- src/compiler/transformers/es2015.ts | 11 +++++++---- tests/baselines/reference/classExtendingNull.js | 2 -- tests/baselines/reference/classExtendingPrimitive.js | 1 - tests/baselines/reference/classExtendingPrimitive2.js | 1 - tests/baselines/reference/classExtendsNull.js | 3 +-- tests/baselines/reference/declFileClassExtendsNull.js | 1 - .../reference/superCallBeforeThisAccessing4.js | 9 +++------ .../reference/superCallBeforeThisAccessing5.js | 4 +--- 8 files changed, 12 insertions(+), 20 deletions(-) diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index e8af4ecbc25..072be8b1dfc 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -925,7 +925,10 @@ namespace ts { } - const superCaptureStatus = declareOrCaptureOrReturnThisForConstructorIfNeeded(statements, constructor, !!extendsClauseElement, hasSynthesizedSuper, statementOffset); + // determine whether the class is known syntactically to be a derived class (e.g. a + // class that extends a value that is not syntactically known to be `null`). + const isDerivedClass = extendsClauseElement && skipOuterExpressions(extendsClauseElement.expression).kind !== SyntaxKind.NullKeyword; + const superCaptureStatus = declareOrCaptureOrReturnThisForConstructorIfNeeded(statements, constructor, isDerivedClass, hasSynthesizedSuper, statementOffset); // The last statement expression was replaced. Skip it. if (superCaptureStatus === SuperCaptureResult.ReplaceSuperCapture || superCaptureStatus === SuperCaptureResult.ReplaceWithReturn) { @@ -942,7 +945,7 @@ namespace ts { // Return `_this` unless we're sure enough that it would be pointless to add a return statement. // If there's a constructor that we can tell returns in enough places, then we *do not* want to add a return. - if (extendsClauseElement + if (isDerivedClass && superCaptureStatus !== SuperCaptureResult.ReplaceWithReturn && !(constructor && isSufficientlyCoveredByReturnStatements(constructor.body))) { statements.push( @@ -1011,11 +1014,11 @@ namespace ts { function declareOrCaptureOrReturnThisForConstructorIfNeeded( statements: Statement[], ctor: ConstructorDeclaration | undefined, - hasExtendsClause: boolean, + isDerivedClass: boolean, hasSynthesizedSuper: boolean, statementOffset: number) { // If this isn't a derived class, just capture 'this' for arrow functions if necessary. - if (!hasExtendsClause) { + if (!isDerivedClass) { if (ctor) { addCaptureThisForNodeIfNeeded(statements, ctor); } diff --git a/tests/baselines/reference/classExtendingNull.js b/tests/baselines/reference/classExtendingNull.js index ebfcea3903b..6725bcc7d9e 100644 --- a/tests/baselines/reference/classExtendingNull.js +++ b/tests/baselines/reference/classExtendingNull.js @@ -17,14 +17,12 @@ var __extends = (this && this.__extends) || (function () { var C1 = (function (_super) { __extends(C1, _super); function C1() { - return _super !== null && _super.apply(this, arguments) || this; } return C1; }(null)); var C2 = (function (_super) { __extends(C2, _super); function C2() { - return _super !== null && _super.apply(this, arguments) || this; } return C2; }((null))); diff --git a/tests/baselines/reference/classExtendingPrimitive.js b/tests/baselines/reference/classExtendingPrimitive.js index eb36a24aeaf..fac6ada65ec 100644 --- a/tests/baselines/reference/classExtendingPrimitive.js +++ b/tests/baselines/reference/classExtendingPrimitive.js @@ -70,7 +70,6 @@ var C5 = (function (_super) { var C5a = (function (_super) { __extends(C5a, _super); function C5a() { - return _super !== null && _super.apply(this, arguments) || this; } return C5a; }(null)); diff --git a/tests/baselines/reference/classExtendingPrimitive2.js b/tests/baselines/reference/classExtendingPrimitive2.js index 0b1c14936ba..2b9cd6de6b6 100644 --- a/tests/baselines/reference/classExtendingPrimitive2.js +++ b/tests/baselines/reference/classExtendingPrimitive2.js @@ -25,7 +25,6 @@ void {}; var C5a = (function (_super) { __extends(C5a, _super); function C5a() { - return _super !== null && _super.apply(this, arguments) || this; } return C5a; }(null)); diff --git a/tests/baselines/reference/classExtendsNull.js b/tests/baselines/reference/classExtendsNull.js index bd73122f450..674b212f98e 100644 --- a/tests/baselines/reference/classExtendsNull.js +++ b/tests/baselines/reference/classExtendsNull.js @@ -26,7 +26,7 @@ var __extends = (this && this.__extends) || (function () { var C = (function (_super) { __extends(C, _super); function C() { - var _this = _super.call(this) || this; + _this = _super.call(this) || this; return Object.create(null); } return C; @@ -34,7 +34,6 @@ var C = (function (_super) { var D = (function (_super) { __extends(D, _super); function D() { - var _this = this; return Object.create(null); } return D; diff --git a/tests/baselines/reference/declFileClassExtendsNull.js b/tests/baselines/reference/declFileClassExtendsNull.js index 9af5b3f3eae..a7ea02011fe 100644 --- a/tests/baselines/reference/declFileClassExtendsNull.js +++ b/tests/baselines/reference/declFileClassExtendsNull.js @@ -17,7 +17,6 @@ var __extends = (this && this.__extends) || (function () { var ExtendsNull = (function (_super) { __extends(ExtendsNull, _super); function ExtendsNull() { - return _super !== null && _super.apply(this, arguments) || this; } return ExtendsNull; }(null)); diff --git a/tests/baselines/reference/superCallBeforeThisAccessing4.js b/tests/baselines/reference/superCallBeforeThisAccessing4.js index 2e97c7c2a0e..80a71d02d4d 100644 --- a/tests/baselines/reference/superCallBeforeThisAccessing4.js +++ b/tests/baselines/reference/superCallBeforeThisAccessing4.js @@ -29,19 +29,16 @@ var __extends = (this && this.__extends) || (function () { var D = (function (_super) { __extends(D, _super); function D() { - var _this = this; - _this._t; + this._t; _this = _super.call(this) || this; - return _this; } return D; }(null)); var E = (function (_super) { __extends(E, _super); function E() { - var _this = _super.call(this) || this; - _this._t; - return _this; + _this = _super.call(this) || this; + this._t; } return E; }(null)); diff --git a/tests/baselines/reference/superCallBeforeThisAccessing5.js b/tests/baselines/reference/superCallBeforeThisAccessing5.js index 50c3fcd6b4a..42049ff2b32 100644 --- a/tests/baselines/reference/superCallBeforeThisAccessing5.js +++ b/tests/baselines/reference/superCallBeforeThisAccessing5.js @@ -21,9 +21,7 @@ var __extends = (this && this.__extends) || (function () { var D = (function (_super) { __extends(D, _super); function D() { - var _this = this; - _this._t; // No error - return _this; + this._t; // No error } return D; }(null));