From 71f24f3d7473d67067850fa478751695c80b1f63 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Wed, 15 Mar 2023 17:10:52 +0200 Subject: [PATCH 1/2] fix(53204): call __runInitializers after super() call --- src/compiler/transformers/esDecorators.ts | 2 +- ...Decorators-classExpression-classSuper.7.js | 44 +++++++++++++++++++ ...Decorators-classExpression-classSuper.7.ts | 21 +++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/esDecorators-classExpression-classSuper.7.js create mode 100644 tests/cases/conformance/esDecorators/classExpression/classSuper/esDecorators-classExpression-classSuper.7.ts diff --git a/src/compiler/transformers/esDecorators.ts b/src/compiler/transformers/esDecorators.ts index d0614bf9f907d..0a3579d1e34f3 100644 --- a/src/compiler/transformers/esDecorators.ts +++ b/src/compiler/transformers/esDecorators.ts @@ -1072,8 +1072,8 @@ export function transformESDecorators(context: TransformationContext): (x: Sourc if (initializerStatements) { const statements: Statement[] = []; const nonPrologueStart = factory.copyPrologue(node.body.statements, statements, /*ensureUseStrict*/ false, visitor); - addRange(statements, initializerStatements); addRange(statements, visitNodes(node.body.statements, visitor, isStatement, nonPrologueStart)); + addRange(statements, initializerStatements); body = factory.createBlock(statements, /*multiLine*/ true); setOriginalNode(body, node.body); setTextRange(body, node.body); diff --git a/tests/baselines/reference/esDecorators-classExpression-classSuper.7.js b/tests/baselines/reference/esDecorators-classExpression-classSuper.7.js new file mode 100644 index 0000000000000..1558ab60ab93a --- /dev/null +++ b/tests/baselines/reference/esDecorators-classExpression-classSuper.7.js @@ -0,0 +1,44 @@ +//// [esDecorators-classExpression-classSuper.7.ts] +class A {} +class B extends A { + public constructor() { + super(); + } + + @foo + public m(): void {} +} + +function foo(method: any, _context: any): any { + return function (this: any) { + method.call(this); + }; +} + +new B(); + + +//// [esDecorators-classExpression-classSuper.7.js] +class A { +} +let B = (() => { + let _instanceExtraInitializers = []; + let _m_decorators; + return class B extends A { + static { + _m_decorators = [foo]; + __esDecorate(this, null, _m_decorators, { kind: "method", name: "m", static: false, private: false, access: { has: obj => "m" in obj, get: obj => obj.m } }, null, _instanceExtraInitializers); + } + constructor() { + super(); + __runInitializers(this, _instanceExtraInitializers); + } + m() { } + }; +})(); +function foo(method, _context) { + return function () { + method.call(this); + }; +} +new B(); diff --git a/tests/cases/conformance/esDecorators/classExpression/classSuper/esDecorators-classExpression-classSuper.7.ts b/tests/cases/conformance/esDecorators/classExpression/classSuper/esDecorators-classExpression-classSuper.7.ts new file mode 100644 index 0000000000000..1a931f0edeca1 --- /dev/null +++ b/tests/cases/conformance/esDecorators/classExpression/classSuper/esDecorators-classExpression-classSuper.7.ts @@ -0,0 +1,21 @@ +// @target: es2022 +// @noEmitHelpers: true +// @noTypesAndSymbols: true + +class A {} +class B extends A { + public constructor() { + super(); + } + + @foo + public m(): void {} +} + +function foo(method: any, _context: any): any { + return function (this: any) { + method.call(this); + }; +} + +new B(); From 9ce27800166254e58a15e479fbb98219b6401dc7 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Wed, 15 Mar 2023 19:14:17 +0200 Subject: [PATCH 2/2] call __runInitializers exclusively after super() call --- src/compiler/transformers/esDecorators.ts | 6 +++++- .../reference/esDecorators-classExpression-classSuper.7.js | 6 ++++++ .../classSuper/esDecorators-classExpression-classSuper.7.ts | 3 +++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/compiler/transformers/esDecorators.ts b/src/compiler/transformers/esDecorators.ts index 0a3579d1e34f3..ede888850b445 100644 --- a/src/compiler/transformers/esDecorators.ts +++ b/src/compiler/transformers/esDecorators.ts @@ -36,6 +36,7 @@ import { Expression, ExpressionStatement, findComputedPropertyNameCacheAssignment, + findSuperStatementIndex, firstOrUndefined, forEachEntry, ForStatement, @@ -1072,8 +1073,11 @@ export function transformESDecorators(context: TransformationContext): (x: Sourc if (initializerStatements) { const statements: Statement[] = []; const nonPrologueStart = factory.copyPrologue(node.body.statements, statements, /*ensureUseStrict*/ false, visitor); - addRange(statements, visitNodes(node.body.statements, visitor, isStatement, nonPrologueStart)); + const superStatementIndex = findSuperStatementIndex(node.body.statements, nonPrologueStart); + const indexOfFirstStatementAfterSuper = superStatementIndex >= 0 ? superStatementIndex + 1 : undefined; + addRange(statements, visitNodes(node.body.statements, visitor, isStatement, nonPrologueStart, indexOfFirstStatementAfterSuper ? indexOfFirstStatementAfterSuper - nonPrologueStart : undefined)); addRange(statements, initializerStatements); + addRange(statements, visitNodes(node.body.statements, visitor, isStatement, indexOfFirstStatementAfterSuper)); body = factory.createBlock(statements, /*multiLine*/ true); setOriginalNode(body, node.body); setTextRange(body, node.body); diff --git a/tests/baselines/reference/esDecorators-classExpression-classSuper.7.js b/tests/baselines/reference/esDecorators-classExpression-classSuper.7.js index 1558ab60ab93a..b496925f6861f 100644 --- a/tests/baselines/reference/esDecorators-classExpression-classSuper.7.js +++ b/tests/baselines/reference/esDecorators-classExpression-classSuper.7.js @@ -2,7 +2,10 @@ class A {} class B extends A { public constructor() { + 'inject'; super(); + const a = 1; + const b = 1; } @foo @@ -30,8 +33,11 @@ let B = (() => { __esDecorate(this, null, _m_decorators, { kind: "method", name: "m", static: false, private: false, access: { has: obj => "m" in obj, get: obj => obj.m } }, null, _instanceExtraInitializers); } constructor() { + 'inject'; super(); __runInitializers(this, _instanceExtraInitializers); + const a = 1; + const b = 1; } m() { } }; diff --git a/tests/cases/conformance/esDecorators/classExpression/classSuper/esDecorators-classExpression-classSuper.7.ts b/tests/cases/conformance/esDecorators/classExpression/classSuper/esDecorators-classExpression-classSuper.7.ts index 1a931f0edeca1..2c1452bbcbf4e 100644 --- a/tests/cases/conformance/esDecorators/classExpression/classSuper/esDecorators-classExpression-classSuper.7.ts +++ b/tests/cases/conformance/esDecorators/classExpression/classSuper/esDecorators-classExpression-classSuper.7.ts @@ -5,7 +5,10 @@ class A {} class B extends A { public constructor() { + 'inject'; super(); + const a = 1; + const b = 1; } @foo