Skip to content

Commit

Permalink
Class binding is in TDZ during decorators initialization (#16138)
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolo-ribaudo committed Nov 29, 2023
1 parent a31c4b9 commit d4f3a22
Show file tree
Hide file tree
Showing 31 changed files with 78 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -103,19 +103,20 @@ function createLazyPrivateUidGeneratorForClass(
*/
function replaceClassWithVar(
path: NodePath<t.ClassDeclaration | t.ClassExpression>,
): [t.Identifier, NodePath<t.ClassDeclaration | t.ClassExpression>] {
): {
id: t.Identifier;
path: NodePath<t.ClassDeclaration | t.ClassExpression>;
needsDeclaration: boolean;
} {
if (path.type === "ClassDeclaration") {
const varId = path.scope.generateUidIdentifierBasedOnNode(path.node.id);
const classId = t.identifier(path.node.id.name);

path.scope.rename(classId.name, varId.name);

path.insertBefore(
t.variableDeclaration("let", [t.variableDeclarator(varId)]),
);
path.get("id").replaceWith(classId);

return [t.cloneNode(varId), path];
return { id: t.cloneNode(varId), path, needsDeclaration: true };
} else {
let className: string;
let varId: t.Identifier;
Expand Down Expand Up @@ -145,10 +146,11 @@ function replaceClassWithVar(
t.sequenceExpression([newClassExpr, varId]),
);

return [
t.cloneNode(varId),
newPath.get("expressions.0") as NodePath<t.ClassExpression>,
];
return {
id: t.cloneNode(varId),
path: newPath.get("expressions.0") as NodePath<t.ClassExpression>,
needsDeclaration: false,
};
}
}

Expand Down Expand Up @@ -609,12 +611,15 @@ function transformClass(
}
};

let needsDeclaraionForClassBinding = false;
if (classDecorators) {
classInitLocal = scopeParent.generateDeclaredUidIdentifier("initClass");

const [classId, classPath] = replaceClassWithVar(path);
path = classPath;
classIdLocal = classId;
({
id: classIdLocal,
path,
needsDeclaration: needsDeclaraionForClassBinding,
} = replaceClassWithVar(path));

path.node.decorators = null;

Expand Down Expand Up @@ -1108,6 +1113,14 @@ function transformClass(
// into a SequenceExpression
path.insertBefore(assignments.map(expr => t.expressionStatement(expr)));

if (needsDeclaraionForClassBinding) {
path.insertBefore(
t.variableDeclaration("let", [
t.variableDeclarator(t.cloneNode(classIdLocal)),
]),
);
}

// Recrawl the scope to make sure new identifiers are properly synced
path.scope.crawl();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
var _initClass, _dec, _initClass2, _dec2;
const dec = () => {};
let _Bar;
_dec = dec1;
let _Bar;
class Bar {
static {
[_Bar, _initClass] = babelHelpers.applyDecs(this, [], [_dec]);
Expand All @@ -10,8 +10,8 @@ class Bar {
_initClass();
}
}
let _Foo;
_dec2 = dec2;
let _Foo;
class Foo extends _Bar {
static {
[_Foo, _initClass2] = babelHelpers.applyDecs(this, [], [_dec2]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
var _initClass, _dec;
let _A;
_dec = dec;
let _A;
class A {
static {
[_A, _initClass] = babelHelpers.applyDecs(this, [], [_dec]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
var _initClass, _dec;
let _default2;
_dec = dec;
let _default2;
class _default {
static {
[_default2, _initClass] = babelHelpers.applyDecs(this, [], [_dec]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
var _initClass, _dec;
let _A;
_dec = dec;
let _A;
class A {
static {
[_A, _initClass] = babelHelpers.applyDecs(this, [], [_dec]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
var _initClass, _dec, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _dec8, _initProto, _class;
const dec = () => {};
let _Foo;
_dec = call();
_dec2 = chain.expr();
_dec3 = arbitrary + expr;
Expand All @@ -9,6 +8,7 @@ _dec5 = call();
_dec6 = chain.expr();
_dec7 = arbitrary + expr;
_dec8 = array[expr];
let _Foo;
var _a = /*#__PURE__*/new WeakMap();
class Foo {
constructor(...args) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
var _initClass, _dec, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _dec8, _initProto;
const dec = () => {};
let _Foo;
_dec = call();
_dec2 = chain.expr();
_dec3 = arbitrary + expr;
Expand All @@ -9,6 +8,7 @@ _dec5 = call();
_dec6 = chain.expr();
_dec7 = arbitrary + expr;
_dec8 = array[expr];
let _Foo;
class Foo {
static {
[_initProto, _Foo, _initClass] = babelHelpers.applyDecs(this, [[[dec, _dec5, _dec6, _dec7, _dec8], 2, "method"]], [dec, _dec, _dec2, _dec3, _dec4]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
var _initClass, _dec, _initClass2, _dec2;
const dec = () => {};
let _Bar;
_dec = dec1;
let _Bar;
class Bar {
static {
[_Bar, _initClass] = babelHelpers.applyDecs2203R(this, [], [_dec]).c;
Expand All @@ -10,8 +10,8 @@ class Bar {
_initClass();
}
}
let _Foo;
_dec2 = dec2;
let _Foo;
class Foo extends _Bar {
static {
[_Foo, _initClass2] = babelHelpers.applyDecs2203R(this, [], [_dec2]).c;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
var _initClass, _dec;
let _A;
_dec = dec;
let _A;
class A {
static {
[_A, _initClass] = babelHelpers.applyDecs2203R(this, [], [_dec]).c;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
var _initClass, _dec;
let _default2;
_dec = dec;
let _default2;
class _default {
static {
[_default2, _initClass] = babelHelpers.applyDecs2203R(this, [], [_dec]).c;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
var _initClass, _dec;
let _A;
_dec = dec;
let _A;
class A {
static {
[_A, _initClass] = babelHelpers.applyDecs2203R(this, [], [_dec]).c;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
var _initClass, _dec, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _dec8, _initProto, _class;
const dec = () => {};
let _Foo;
_dec = call();
_dec2 = chain.expr();
_dec3 = arbitrary + expr;
Expand All @@ -9,6 +8,7 @@ _dec5 = call();
_dec6 = chain.expr();
_dec7 = arbitrary + expr;
_dec8 = array[expr];
let _Foo;
var _a = /*#__PURE__*/new WeakMap();
class Foo {
constructor(...args) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
var _initClass, _dec, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _dec8, _initProto;
const dec = () => {};
let _Foo;
_dec = call();
_dec2 = chain.expr();
_dec3 = arbitrary + expr;
Expand All @@ -9,6 +8,7 @@ _dec5 = call();
_dec6 = chain.expr();
_dec7 = arbitrary + expr;
_dec8 = array[expr];
let _Foo;
class Foo {
static {
({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
var _initClass, _dec, _initClass2, _dec2;
const dec = () => {};
let _Bar;
_dec = dec1;
let _Bar;
class Bar {
static {
[_Bar, _initClass] = babelHelpers.applyDecs2301(this, [], [_dec]).c;
Expand All @@ -10,8 +10,8 @@ class Bar {
_initClass();
}
}
let _Foo;
_dec2 = dec2;
let _Foo;
class Foo extends _Bar {
static {
[_Foo, _initClass2] = babelHelpers.applyDecs2301(this, [], [_dec2]).c;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
var _initClass, _dec;
let _A;
_dec = dec;
let _A;
class A {
static {
[_A, _initClass] = babelHelpers.applyDecs2301(this, [], [_dec]).c;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
var _initClass, _dec;
let _default2;
_dec = dec;
let _default2;
class _default {
static {
[_default2, _initClass] = babelHelpers.applyDecs2301(this, [], [_dec]).c;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
var _initClass, _dec;
let _A;
_dec = dec;
let _A;
class A {
static {
[_A, _initClass] = babelHelpers.applyDecs2301(this, [], [_dec]).c;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
var _initClass, _dec, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _dec8, _initProto, _class;
const dec = () => {};
let _Foo;
_dec = call();
_dec2 = chain.expr();
_dec3 = arbitrary + expr;
Expand All @@ -9,6 +8,7 @@ _dec5 = call();
_dec6 = chain.expr();
_dec7 = arbitrary + expr;
_dec8 = array[expr];
let _Foo;
var _a = /*#__PURE__*/new WeakMap();
class Foo {
constructor(...args) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
var _initClass, _dec, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _dec8, _initProto;
const dec = () => {};
let _Foo;
_dec = call();
_dec2 = chain.expr();
_dec3 = arbitrary + expr;
Expand All @@ -9,6 +8,7 @@ _dec5 = call();
_dec6 = chain.expr();
_dec7 = arbitrary + expr;
_dec8 = array[expr];
let _Foo;
class Foo {
static {
({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
var _initClass, _dec, _initClass2, _dec2, _Bar2;
const dec = () => {};
let _Bar;
_dec = dec1;
let _Bar;
class Bar {
static {
[_Bar, _initClass] = babelHelpers.applyDecs2305(this, [], [_dec]).c;
Expand All @@ -10,8 +10,8 @@ class Bar {
_initClass();
}
}
let _Foo;
_dec2 = dec2;
let _Foo;
class Foo extends (_Bar2 = _Bar) {
static {
[_Foo, _initClass2] = babelHelpers.applyDecs2305(this, [], [_dec2], 0, void 0, _Bar2).c;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
var _initClass, _dec;
let _A;
_dec = dec;
let _A;
class A {
static {
[_A, _initClass] = babelHelpers.applyDecs2305(this, [], [_dec]).c;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
var _initClass, _dec;
let _default2;
_dec = dec;
let _default2;
class _default {
static {
[_default2, _initClass] = babelHelpers.applyDecs2305(this, [], [_dec]).c;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
var _initClass, _dec;
let _A;
_dec = dec;
let _A;
class A {
static {
[_A, _initClass] = babelHelpers.applyDecs2305(this, [], [_dec]).c;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
class A extends B {
m() {
var _initClass, _obj, _dec, _obj2, _dec2, _initProto, _class;
let _C;
_obj = this;
_dec = super.dec1;
_obj2 = this;
_dec2 = super.dec2;
let _C;
class C {
constructor(...args) {
_initProto(this);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
var _initClass, _obj, _dec, _dec2, _obj2, _dec3, _obj3, _dec4, _obj4, _dec5, _init_x, _obj5, _dec6, _dec7, _init_y, _class;
let _A;
_obj = o1;
_dec = _obj.dec;
_dec2 = dec;
Expand All @@ -12,6 +11,7 @@ _dec5 = _obj4.dec;
_obj5 = o2;
_dec6 = _obj5.dec;
_dec7 = dec;
let _A;
class A {
constructor() {
babelHelpers.defineProperty(this, "x", _init_x(this));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
var _initClass, _dec, _dec2, _dec3, _obj, _dec4, _dec5, _dec6, _dec7, _obj2, _dec8, _initProto, _class;
const dec = () => {};
let _Foo;
_dec = call();
_dec2 = chain.expr();
_dec3 = arbitrary + expr;
Expand All @@ -11,6 +10,7 @@ _dec6 = chain.expr();
_dec7 = arbitrary + expr;
_obj2 = array;
_dec8 = _obj2[expr];
let _Foo;
var _a = /*#__PURE__*/new WeakMap();
class Foo {
constructor(...args) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
let didRun = false;

function dec(fn) {
fn();
return () => {};
}

@dec(() => {
expect(() => Foo).toThrow(ReferenceError);
didRun = true;
}) class Foo {}

expect(didRun).toBe(true);

0 comments on commit d4f3a22

Please sign in to comment.