Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix evaluation order of decorators with cached receiver #16281

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -909,6 +909,7 @@ function transformClass(
const decoratedPrivateMethods = new Set<string>();

let classInitLocal: t.Identifier, classIdLocal: t.Identifier;
let decoratorReceiverId: t.Identifier | null = null;

// Memoise the this value `a.b` of decorator member expressions `@a.b.dec`,
type HandleDecoratorExpressionsResult = {
Expand All @@ -929,16 +930,19 @@ function transformClass(
(!process.env.BABEL_8_BREAKING && version === "2023-05")) &&
t.isMemberExpression(expression)
) {
if (
t.isSuper(expression.object) ||
t.isThisExpression(expression.object)
) {
object = memoiseExpression(t.thisExpression(), "obj");
} else {
if (!scopeParent.isStatic(expression.object)) {
expression.object = memoiseExpression(expression.object, "obj");
}
if (t.isSuper(expression.object)) {
object = t.thisExpression();
} else if (scopeParent.isStatic(expression.object)) {
object = t.cloneNode(expression.object);
} else {
decoratorReceiverId ??=
scopeParent.generateDeclaredUidIdentifier("obj");
object = t.assignmentExpression(
"=",
t.cloneNode(decoratorReceiverId),
expression.object,
);
expression.object = t.cloneNode(decoratorReceiverId);
}
}
decoratorsThis.push(object);
Expand Down
@@ -1,10 +1,8 @@
class A extends B {
m() {
var _initProto, _initClass, _obj, _classDecs, _obj2, _m2Decs, _C2;
_obj = this;
_classDecs = [_obj, super.dec1];
_obj2 = this;
_m2Decs = [_obj2, super.dec2];
var _initProto, _initClass, _classDecs, _m2Decs, _C2;
_classDecs = [this, super.dec1];
_m2Decs = [this, super.dec2];
let _C;
class C {
constructor() {
Expand Down
@@ -1,12 +1,7 @@
var _initClass, _obj, _obj2, _classDecs, _obj3, _obj4, _xDecs, _init_x, _obj5, _yDecs, _init_y, _A2;
_obj = o1;
_obj2 = o2;
_classDecs = [_obj, _obj.dec, void 0, dec, _obj2, _obj2.dec];
_obj3 = o2;
_obj4 = o3.o;
_xDecs = [_obj3, _obj3.dec, _obj4, _obj4.dec];
_obj5 = o2;
_yDecs = [_obj5, _obj5.dec, void 0, dec];
var _initClass, _obj, _classDecs, _xDecs, _init_x, _yDecs, _init_y, _A2;
_classDecs = [_obj = o1, _obj.dec, void 0, dec, _obj = o2, _obj.dec];
_xDecs = [_obj = o2, _obj.dec, _obj = o3.o, _obj.dec];
_yDecs = [_obj = o2, _obj.dec, void 0, dec];
let _A;
class A {
constructor() {
Expand Down
@@ -1,9 +1,7 @@
var _initProto, _initClass, _obj, _classDecs, _obj2, _methodDecs, _Foo2;
var _initProto, _initClass, _obj, _classDecs, _methodDecs, _Foo2;
const dec = () => {};
_obj = array;
_classDecs = [void 0, dec, void 0, call(), void 0, chain.expr(), void 0, arbitrary + expr, _obj, _obj[expr]];
_obj2 = array;
_methodDecs = [void 0, dec, void 0, call(), void 0, chain.expr(), void 0, arbitrary + expr, _obj2, _obj2[expr]];
_classDecs = [void 0, dec, void 0, call(), void 0, chain.expr(), void 0, arbitrary + expr, _obj = array, _obj[expr]];
_methodDecs = [void 0, dec, void 0, call(), void 0, chain.expr(), void 0, arbitrary + expr, _obj = array, _obj[expr]];
let _Foo;
var _a = /*#__PURE__*/new WeakMap();
class Foo {
Expand Down
@@ -1,10 +1,8 @@
class A extends B {
m() {
var _initProto, _initClass, _obj, _classDecs, _obj2, _m2Decs;
_obj = this;
_classDecs = [_obj, super.dec1];
_obj2 = this;
_m2Decs = [_obj2, super.dec2];
var _initProto, _initClass, _classDecs, _m2Decs;
_classDecs = [this, super.dec1];
_m2Decs = [this, super.dec2];
let _C;
class C {
static {
Expand Down
@@ -1,12 +1,7 @@
var _initClass, _obj, _obj2, _classDecs, _obj3, _obj4, _xDecs, _init_x, _obj5, _yDecs, _init_y;
_obj = o1;
_obj2 = o2;
_classDecs = [_obj, _obj.dec, void 0, dec, _obj2, _obj2.dec];
_obj3 = o2;
_obj4 = o3.o;
_xDecs = [_obj3, _obj3.dec, _obj4, _obj4.dec];
_obj5 = o2;
_yDecs = [_obj5, _obj5.dec, void 0, dec];
var _initClass, _obj, _classDecs, _xDecs, _init_x, _yDecs, _init_y;
_classDecs = [_obj = o1, _obj.dec, void 0, dec, _obj = o2, _obj.dec];
_xDecs = [_obj = o2, _obj.dec, _obj = o3.o, _obj.dec];
_yDecs = [_obj = o2, _obj.dec, void 0, dec];
let _A;
class A {
static {
Expand Down
@@ -1,9 +1,7 @@
var _initProto, _initClass, _obj, _classDecs, _obj2, _methodDecs;
var _initProto, _initClass, _obj, _classDecs, _methodDecs;
const dec = () => {};
_obj = array;
_classDecs = [void 0, dec, void 0, call(), void 0, chain.expr(), void 0, arbitrary + expr, _obj, _obj[expr]];
_obj2 = array;
_methodDecs = [void 0, dec, void 0, call(), void 0, chain.expr(), void 0, arbitrary + expr, _obj2, _obj2[expr]];
_classDecs = [void 0, dec, void 0, call(), void 0, chain.expr(), void 0, arbitrary + expr, _obj = array, _obj[expr]];
_methodDecs = [void 0, dec, void 0, call(), void 0, chain.expr(), void 0, arbitrary + expr, _obj = array, _obj[expr]];
let _Foo;
class Foo {
static {
Expand All @@ -15,8 +13,8 @@ class Foo {
#a = void _initProto(this);
method() {}
makeClass() {
var _obj3, _barDecs, _init_bar;
return _obj3 = this, _barDecs = [_obj3, this.#a], class Nested {
var _barDecs, _init_bar;
return _barDecs = [this, this.#a], class Nested {
static {
[_init_bar] = babelHelpers.applyDecs2305(this, [[_barDecs, 16, "bar"]], []).e;
}
Expand Down
@@ -1,10 +1,8 @@
class A extends B {
m() {
var _initProto, _initClass, _obj, _classDecs, _obj2, _m2Decs, _C2;
_obj = this;
_classDecs = [_obj, super.dec1];
_obj2 = this;
_m2Decs = [_obj2, super.dec2];
var _initProto, _initClass, _classDecs, _m2Decs, _C2;
_classDecs = [this, super.dec1];
_m2Decs = [this, super.dec2];
let _C;
class C {
constructor() {
Expand Down
@@ -1,12 +1,7 @@
var _initClass, _obj, _obj2, _classDecs, _obj3, _obj4, _xDecs, _init_x, _init_extra_x, _obj5, _yDecs, _init_y, _init_extra_y, _A2;
_obj = o1;
_obj2 = o2;
_classDecs = [_obj, _obj.dec, void 0, dec, _obj2, _obj2.dec];
_obj3 = o2;
_obj4 = o3.o;
_xDecs = [_obj3, _obj3.dec, _obj4, _obj4.dec];
_obj5 = o2;
_yDecs = [_obj5, _obj5.dec, void 0, dec];
var _initClass, _obj, _classDecs, _xDecs, _init_x, _init_extra_x, _yDecs, _init_y, _init_extra_y, _A2;
_classDecs = [_obj = o1, _obj.dec, void 0, dec, _obj = o2, _obj.dec];
_xDecs = [_obj = o2, _obj.dec, _obj = o3.o, _obj.dec];
_yDecs = [_obj = o2, _obj.dec, void 0, dec];
let _A;
class A {
constructor() {
Expand Down
@@ -1,9 +1,7 @@
var _initProto, _initClass, _obj, _classDecs, _obj2, _methodDecs, _Foo2;
var _initProto, _initClass, _obj, _classDecs, _methodDecs, _Foo2;
const dec = () => {};
_obj = array;
_classDecs = [void 0, dec, void 0, call(), void 0, chain.expr(), void 0, arbitrary + expr, _obj, _obj[expr]];
_obj2 = array;
_methodDecs = [void 0, dec, void 0, call(), void 0, chain.expr(), void 0, arbitrary + expr, _obj2, _obj2[expr]];
_classDecs = [void 0, dec, void 0, call(), void 0, chain.expr(), void 0, arbitrary + expr, _obj = array, _obj[expr]];
_methodDecs = [void 0, dec, void 0, call(), void 0, chain.expr(), void 0, arbitrary + expr, _obj = array, _obj[expr]];
let _Foo;
var _a = /*#__PURE__*/new WeakMap();
class Foo {
Expand Down
@@ -1,10 +1,8 @@
class A extends B {
m() {
var _initProto, _initClass, _obj, _classDecs, _obj2, _m2Decs;
_obj = this;
_classDecs = [_obj, super.dec1];
_obj2 = this;
_m2Decs = [_obj2, super.dec2];
var _initProto, _initClass, _classDecs, _m2Decs;
_classDecs = [this, super.dec1];
_m2Decs = [this, super.dec2];
let _C;
class C {
static {
Expand Down
@@ -1,14 +1,7 @@
var _initClass, _obj, _obj2, _obj3, _classDecs, _obj4, _obj5, _obj6, _xDecs, _init_x, _init_extra_x, _obj7, _yDecs, _init_y, _init_extra_y;
_obj = o1;
_obj2 = o2;
_obj3 = o4.o();
_classDecs = [_obj, _obj.dec, void 0, dec, _obj2, _obj2.dec, _obj3, _obj3.dec];
_obj4 = o2;
_obj5 = o3.o;
_obj6 = o4.o();
_xDecs = [_obj4, _obj4.dec, _obj5, _obj5.dec, _obj6, _obj6.dec];
_obj7 = o2;
_yDecs = [_obj7, _obj7.dec, void 0, dec];
var _initClass, _obj, _classDecs, _xDecs, _init_x, _init_extra_x, _yDecs, _init_y, _init_extra_y;
_classDecs = [_obj = o1, _obj.dec, void 0, dec, _obj = o2, _obj.dec, _obj = o4.o(), _obj.dec];
_xDecs = [_obj = o2, _obj.dec, _obj = o3.o, _obj.dec, _obj = o4.o(), _obj.dec];
_yDecs = [_obj = o2, _obj.dec, void 0, dec];
let _A;
class A {
static {
Expand Down
@@ -1,9 +1,7 @@
var _initProto, _initClass, _obj, _classDecs, _obj2, _methodDecs;
var _initProto, _initClass, _obj, _classDecs, _methodDecs;
const dec = () => {};
_obj = array;
_classDecs = [void 0, dec, void 0, call(), void 0, chain.expr(), void 0, arbitrary + expr, _obj, _obj[expr]];
_obj2 = array;
_methodDecs = [void 0, dec, void 0, call(), void 0, chain.expr(), void 0, arbitrary + expr, _obj2, _obj2[expr]];
_classDecs = [void 0, dec, void 0, call(), void 0, chain.expr(), void 0, arbitrary + expr, _obj = array, _obj[expr]];
_methodDecs = [void 0, dec, void 0, call(), void 0, chain.expr(), void 0, arbitrary + expr, _obj = array, _obj[expr]];
let _Foo;
class Foo {
static {
Expand All @@ -15,8 +13,8 @@ class Foo {
#a = void _initProto(this);
method() {}
makeClass() {
var _obj3, _barDecs, _init_bar, _init_extra_bar;
return _obj3 = this, _barDecs = [_obj3, this.#a], class Nested {
var _barDecs, _init_bar, _init_extra_bar;
return _barDecs = [this, this.#a], class Nested {
static {
[_init_bar, _init_extra_bar] = babelHelpers.applyDecs2311(this, [[_barDecs, 16, "bar"]], []).e;
}
Expand Down
@@ -0,0 +1,17 @@
let result = [];
const fn = () => { result.push(1); return () => {} }
const obj = {
get prop() {
result.push(2);
return {
get foo() { result.push(3); return () => {} }
}
}
};
class A {
@fn()
@obj.prop.foo
JLHwung marked this conversation as resolved.
Show resolved Hide resolved
method() {}
}

expect(result).toEqual([1, 2, 3]);
@@ -0,0 +1,7 @@
let fn, obj;
class A {
@fn()
@obj.prop.foo
method() {}
}

@@ -0,0 +1,11 @@
var _initProto, _obj, _methodDecs, _A;
let fn, obj;
_methodDecs = [void 0, fn(), _obj = obj.prop, _obj.foo];
class A {
constructor() {
_initProto(this);
}
method() {}
}
_A = A;
[_initProto] = babelHelpers.applyDecs2311(_A, [[_methodDecs, 18, "method"]], []).e;
@@ -0,0 +1,7 @@
let fn, obj;
class A {
@fn()
@obj.prop.foo
method() {}
}

@@ -0,0 +1,12 @@
var _initProto, _obj, _methodDecs;
let fn, obj;
_methodDecs = [void 0, fn(), _obj = obj.prop, _obj.foo];
class A {
static {
[_initProto] = babelHelpers.applyDecs2311(this, [[_methodDecs, 18, "method"]], []).e;
}
constructor() {
_initProto(this);
}
method() {}
}