From 1b9a9d8312676dfee5f9d9966d7abd0f19774a49 Mon Sep 17 00:00:00 2001 From: Patrick Szmucer Date: Tue, 19 Apr 2022 14:33:54 +0000 Subject: [PATCH] Fix transformed constructor code when there is code between prologue statements and super call --- src/compiler/transformers/es2015.ts | 2 +- .../constructorWithSuperAndPrologue.es5.js | 52 +++++++++++++++++++ ...onstructorWithSuperAndPrologue.es5.symbols | 31 +++++++++++ .../constructorWithSuperAndPrologue.es5.types | 39 ++++++++++++++ .../constructorWithSuperAndPrologue.es5.ts | 17 ++++++ 5 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/constructorWithSuperAndPrologue.es5.js create mode 100644 tests/baselines/reference/constructorWithSuperAndPrologue.es5.symbols create mode 100644 tests/baselines/reference/constructorWithSuperAndPrologue.es5.types create mode 100644 tests/cases/compiler/constructorWithSuperAndPrologue.es5.ts diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 36a0f29d109e3..38ad28faacc32 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -1146,7 +1146,7 @@ namespace ts { [ ...existingPrologue, ...prologue, - ...(superStatementIndex <= existingPrologue.length ? emptyArray : visitNodes(constructor.body.statements, visitor, isStatement, existingPrologue.length, superStatementIndex)), + ...(superStatementIndex <= existingPrologue.length ? emptyArray : visitNodes(constructor.body.statements, visitor, isStatement, existingPrologue.length, superStatementIndex - existingPrologue.length)), ...statements ] ), diff --git a/tests/baselines/reference/constructorWithSuperAndPrologue.es5.js b/tests/baselines/reference/constructorWithSuperAndPrologue.es5.js new file mode 100644 index 0000000000000..a06a4f7a4faa7 --- /dev/null +++ b/tests/baselines/reference/constructorWithSuperAndPrologue.es5.js @@ -0,0 +1,52 @@ +//// [constructorWithSuperAndPrologue.es5.ts] +// https://github.com/microsoft/TypeScript/issues/48761 +"use strict"; + +class A { + public constructor() { + console.log("A") + } +} + +class B extends A { + constructor() { + "ngInject"; + console.log("B") + super(); + } +} + + +//// [constructorWithSuperAndPrologue.es5.js] +// https://github.com/microsoft/TypeScript/issues/48761 +"use strict"; +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 (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var A = /** @class */ (function () { + function A() { + console.log("A"); + } + return A; +}()); +var B = /** @class */ (function (_super) { + __extends(B, _super); + function B() { + "ngInject"; + console.log("B"); + return _super.call(this) || this; + } + return B; +}(A)); diff --git a/tests/baselines/reference/constructorWithSuperAndPrologue.es5.symbols b/tests/baselines/reference/constructorWithSuperAndPrologue.es5.symbols new file mode 100644 index 0000000000000..4ec2815f8a485 --- /dev/null +++ b/tests/baselines/reference/constructorWithSuperAndPrologue.es5.symbols @@ -0,0 +1,31 @@ +=== tests/cases/compiler/constructorWithSuperAndPrologue.es5.ts === +// https://github.com/microsoft/TypeScript/issues/48761 +"use strict"; + +class A { +>A : Symbol(A, Decl(constructorWithSuperAndPrologue.es5.ts, 1, 13)) + + public constructor() { + console.log("A") +>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, --, --)) + } +} + +class B extends A { +>B : Symbol(B, Decl(constructorWithSuperAndPrologue.es5.ts, 7, 1)) +>A : Symbol(A, Decl(constructorWithSuperAndPrologue.es5.ts, 1, 13)) + + constructor() { + "ngInject"; + console.log("B") +>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(A, Decl(constructorWithSuperAndPrologue.es5.ts, 1, 13)) + } +} + diff --git a/tests/baselines/reference/constructorWithSuperAndPrologue.es5.types b/tests/baselines/reference/constructorWithSuperAndPrologue.es5.types new file mode 100644 index 0000000000000..7e615a1a6601c --- /dev/null +++ b/tests/baselines/reference/constructorWithSuperAndPrologue.es5.types @@ -0,0 +1,39 @@ +=== tests/cases/compiler/constructorWithSuperAndPrologue.es5.ts === +// https://github.com/microsoft/TypeScript/issues/48761 +"use strict"; +>"use strict" : "use strict" + +class A { +>A : A + + public constructor() { + console.log("A") +>console.log("A") : void +>console.log : (...data: any[]) => void +>console : Console +>log : (...data: any[]) => void +>"A" : "A" + } +} + +class B extends A { +>B : B +>A : A + + constructor() { + "ngInject"; +>"ngInject" : "ngInject" + + console.log("B") +>console.log("B") : void +>console.log : (...data: any[]) => void +>console : Console +>log : (...data: any[]) => void +>"B" : "B" + + super(); +>super() : void +>super : typeof A + } +} + diff --git a/tests/cases/compiler/constructorWithSuperAndPrologue.es5.ts b/tests/cases/compiler/constructorWithSuperAndPrologue.es5.ts new file mode 100644 index 0000000000000..1f4fc747648d6 --- /dev/null +++ b/tests/cases/compiler/constructorWithSuperAndPrologue.es5.ts @@ -0,0 +1,17 @@ +// @target: es5 +// https://github.com/microsoft/TypeScript/issues/48761 +"use strict"; + +class A { + public constructor() { + console.log("A") + } +} + +class B extends A { + constructor() { + "ngInject"; + console.log("B") + super(); + } +}