Skip to content

Commit

Permalink
Fix evaluation order of decorators with cached receiver (babel#16281)
Browse files Browse the repository at this point in the history
* Add failing test

* Fix evaluation order of decorators with cached receiver

* Use one temp var per decorated element

* Use one temp var per class
  • Loading branch information
nicolo-ribaudo authored and liuxingbaoyu committed Mar 5, 2024
1 parent 47a20ce commit 9194337
Show file tree
Hide file tree
Showing 18 changed files with 111 additions and 91 deletions.
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
method() {}
}

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

Original file line number Diff line number Diff line change
@@ -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;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
let fn, obj;
class A {
@fn()
@obj.prop.foo
method() {}
}

Original file line number Diff line number Diff line change
@@ -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() {}
}

0 comments on commit 9194337

Please sign in to comment.