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 decorator evaluation private environment #16325

Merged

Conversation

JLHwung
Copy link
Contributor

@JLHwung JLHwung commented Mar 5, 2024

Q                       A
Fixed Issues? Fixes #16295
Patch: Bug Fix? Yes
Major: Breaking Change?
Minor: New Feature?
Tests Added + Pass? Yes
Documentation PR Link
Any Dependency Changes?
License MIT

In this PR we move the element decorator evaluation from the preface of class declaration into computed key.

Previously they are evaluated outside the class, immediate after class decorator evaluations. However, because the element decorators are defined within the class syntax, they should have access to the private variables defined in the current class.

The current evaluation storage:

  1. The computed key are the ideal place to store element decorator evaluations because they share the same scope.
  2. If a computed key is not available, we will convert the first public key into a computed key.
  3. If there is no public element, we will inject a temporary static field to host the evaluation. The field will be deleted immediately after it is defined.
    If a class has only private elements and static blocks, we will insert the decorator evaluations before the applyDecs call. We will replace all function context usage before moving them into the static block. However, this is still not safe because decorators expressions / computed keys inherit the outer level [Yield] and [Await] production parameter, while the static block where we insert applyDecs call can not be a generator / async function. Given that the scenaraio of private-only class is rare, I would like to trade it with this general private fix.

I suggest review this PR by commits.

@JLHwung JLHwung added PR: Bug Fix 🐛 A type of pull request used for our changelog categories Spec: Decorators labels Mar 5, 2024
@babel-bot
Copy link
Collaborator

babel-bot commented Mar 5, 2024

Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/56452

}

expect([...A].map(fn => fn(B)).join(",")).toBe("B#X,B#X,B#X,B#X,B#X,B#X,B#X,B#X,B#X,B#X");
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This edge case test is disabled because I can't figure out how to transform it.

Copy link
Contributor Author

@JLHwung JLHwung Mar 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, can we introduce a new public element and delete it immediately after defined?

class C {
  // for demo purpose, the `delete` expression can be directly inserted into staticInitializerAssignments
  @(function(_, context) { context.addInitializer(function() { delete this._ } })
  static [(/* decorator evaluations */, "_")];
}

Of course using delete is a performance killer, but this approach will be only invoked when there is no public class elements, which should be quite rare. By doing so we can get rid of all function context variable replacement since the decorator expressions are guaranteed to be inserted within a computed key.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this case is rare enough that:

  • the perf hit is ok
  • the perf it doesn't actually matter, because you are not going to access properties on instances of this class (because it, well... has no properties)

for delete, let's put it in a static { delete this._ } block at the beginning of the class?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds good to me.
We can even do it when someone needs it. :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for delete, let's put it in a static { delete this._ } block at the beginning of the class?

I plan to insert the delete expression right before the applyDecs call, since its parent block is already the first class element.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is now enabled and merged with decorator-evaluation-yield-private-super-property/exec.js

It also happens to catch a bug in the helper-replace-supers, currently Babel is incorrectly replacing the super in the decorators of the given class method. This should have been handled in the environmentVisitor but the root class method path is not visited because the visitSelf argument of traverse.node is not exposed to the path.traverse.

707b91c

}

B.m();
expect(receivedName).toBe("B");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test was renamed to "decorator-evaluation-this" and then augmented.

Comment on lines -1 to +2
var _initStatic, _init_a, _init_a2, _get_a, _set_a, _init_computedKey, _init_computedKey2, _init_computedKey3, _init_computedKey4, _init_computedKey5, _init_computedKey6, _computedKey, _init_computedKey7, _Foo;
let _computedKey;
var _initStatic, _init_a, _init_a2, _get_a, _set_a, _init_computedKey, _init_computedKey2, _init_computedKey3, _init_computedKey4, _init_computedKey5, _init_computedKey6, _init_computedKey7, _Foo;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we revert this change?

Copy link
Contributor Author

@JLHwung JLHwung Mar 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is intentional as it will fix an integration issue with the class properties transform. For context see https://github.com/babel/babel/pull/10029/files#r287785963

In this REPL example

function noop() {}
const classes = [];
for (let i = 0; i < 5; ++i) {
  classes.push(
    class A {
      @noop
      [i] = "my property";
    }
  );
}
var result = [];
for (const clazz of classes) {
  result.push(Object.getOwnPropertyNames(new clazz())[0]);
}
console.log(result.join())

when we apply the decorators, static block and class properties plugin, it should print 0,1,2,3,4 but currently it prints 4,4,4,4,4.

I can add a new test case for this issue.

If the output size is the concern, I can open a new PR to register all variable as the let binding, as it will introduce much more test output changes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes please add a test!

Regarding to output size, we should first aim at correctness and then optimization.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I didn't notice this was a bug fix, I thought the increased size didn't matter.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nicolo-ribaudo
Copy link
Member

"I suggest review this PR by commits." ~ 13 commits 😛

const expressions = path.get("expressions");
return getComputedKeyCompletion(expressions[expressions.length - 1]);
}
return skipTransparentExprWrappers(path);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this recourse if the result of skipTransparentExprWrappers is a SequenceExpression?

Comment on lines 311 to 312
const key = fieldPath.get("key") as NodePath<t.Expression>;
expressions.push(key.node);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If key is already a sequence expression maybe we should do expression.push(...key.node.expressions)?

Or -- this is probably so rare that it doesn't matter, but in this case could we have a test showing that we generated a "nested" sequence expression?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a key is already a sequence expression, it could be generated by another Babel plugin. The intention here is try to reuse the uid memoiser, for example the computed keys transform can reuse the memoiser _computedKeys generated by the decorator transform:

class C {
  [decs = f(), _computedKey = g(), another_decs = h(), _computedKey];
}

but at this point there is no class features running before decorators, so there aren't much practical examples. I will add a test case for nested sequence expression.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

);
}
} else {
// If the computed key is an uid reference, treat it as
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why if we get to this else branch the key is an uid reference?

EDIT: Oh I see -- could you rename memoiseComputedKey to memoiseComputedKeyIfNotUid, or add a comment before the call saying that it returns undefined if and only if it's a uid?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines 136 to 137
if (isUidReference) {
return;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Move this early return to before const isMemoiseAssignment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

expect([...A].map(fn => fn(B)).join(",")).toBe("B#X,B#X,B#X,B#X,B#X,B#X,B#X,B#X,B#X,B#X");
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this case is rare enough that:

  • the perf hit is ok
  • the perf it doesn't actually matter, because you are not going to access properties on instances of this class (because it, well... has no properties)

for delete, let's put it in a static { delete this._ } block at the beginning of the class?


const computedKeysPath = applyDecoratorWrapperPath.get("body")[0];

// Capture lexical this and super call, replace their usage in computed key assignments
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would

function hoistFunctionEnvironment(
work here? If yes, can we export that function and use it for Babel 8, rather than duplicating the logic forever?

Or maybe we could even "polyfill" it for Babel 7, doing terrible stuff:

function hoistFunctionEnvironment(path) {
  Object.defineProperty(path, "isArrowFunctionExpression", {
    get() {
      delete path.isArrowFunctionExpression;
      return () => true;
    }
  });
  return path.unwrapFunctionEnvironment();
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point! I didn't realize we have such a utility in the traverse library. However I am down to the temporary property approach and hopefully we can remove all the lexical variables capturing logic here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -1659,6 +1672,32 @@ function transformClass(
}

originalClass.body.body.unshift(t.staticBlock([]));
if (computedKeyAssignments.length > 0) {
// todo: the following branch will fail on 2023-05 version
if (version === "2023-11") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

process.env.BABEL_8_BREAKING || version === "2023-11"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check is eventually removed in bdee20d.

static m() {
@noop
class C {
@(receivedName = super.name, noop) p;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a test with a decorator that references both super and a private field in the same decorator?

Copy link
Contributor Author

@JLHwung JLHwung Mar 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this test look good?

class A extends CaptureFactory {
static #X = "A#X";
static *[Symbol.iterator] () {
B = class B {
static #X = "B#X";
@(yield* super.id(_ => _.#X), dummy) method () {}
@(yield* super.id(_ => _.#X), dummy) static method () {}
@(yield* super.id(_ => _.#X), dummy) get getter () {}
@(yield* super.id(_ => _.#X), dummy) static get getter () {}
@(yield* super.id(_ => _.#X), dummy) set setter (v) {}
@(yield* super.id(_ => _.#X), dummy) static set setter (v) {}
@(yield* super.id(_ => _.#X), dummy) property;
@(yield* super.id(_ => _.#X), dummy) static property;
@(yield* super.id(_ => _.#X), dummy) accessor accessor;
@(yield* super.id(_ => _.#X), dummy) static accessor accessor;
}
}
}

Edit: I can add a super-call flavor if you mean super().

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is ok, I somehow missed it.

@liuxingbaoyu
Copy link
Member

liuxingbaoyu commented Mar 5, 2024

test262 seems to be relevant, while the other CI failures are not.

Considering that this PR rebase may be complicated, we can postpone the #16326 merge.

@JLHwung JLHwung force-pushed the fix-decorator-evaluation-private-environment branch from 0b8f0bc to d837c27 Compare March 5, 2024 18:53
static {
_xDecs = dec;
delete this._;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New PR idea: We can optimize them, potentially reusing the usesFnContext diagnostic info of each decorators sequence.

@JLHwung JLHwung force-pushed the fix-decorator-evaluation-private-environment branch from 0b8809e to d33d87b Compare March 5, 2024 19:18

// Recrawl the scope to make sure new identifiers are properly synced
path.scope.crawl();
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This branch is removed because the computed key in a vanilla class accessor is now memoised in place.

@JLHwung
Copy link
Contributor Author

JLHwung commented Mar 5, 2024

I am investigating the test262 error.

try {
t.traverseFast(expression, node => {
if (
t.isThisExpression(node) ||
t.isSuper(node) ||
t.isYieldExpression(node) ||
t.isAwaitExpression(node) ||
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function determines whether the class / element decorator evaluations should be moved into the applyDecs static block. If the decorator expression contains await or yield, we should not move it since the static block can not provide correct function context.

Comment on lines 2 to 12
const dec = () => {};
let _Class;
new class extends babelHelpers.identity {
static {
class Class {
static {
({
e: [_init_m, _call_o, _call_p, _call_q, _init_r, _get_r, _set_r, _init_d, _call_f, _call_g, _call_g2, _init_h, _get_h, _set_h, _init_i, _init_n, _init_a, _init_e, _initProto, _initStatic],
c: [_Class, _initClass]
} = babelHelpers.applyDecs2301(this, [[dec, 7, "j"], [dec, 8, "k"], [dec, 9, "l"], [dec, 6, "m"], [dec, 7, "o", function () {}], [dec, 8, "p", function () {}], [dec, 9, "q", function (v) {}], [dec, 6, "r", o => o.#D, (o, v) => o.#D = v], [dec, 2, "b"], [dec, 3, "c"], [dec, 4, "c"], [dec, 1, "d"], [dec, 2, "f", function () {}], [dec, 3, "g", function () {}], [dec, 4, "g", function (v) {}], [dec, 1, "h", o => o.#B, (o, v) => o.#B = v], [dec, 5, "i"], [dec, 5, "n", o => o.#n, (o, v) => o.#n = v], [dec, 0, "a"], [dec, 0, "e", o => o.#e, (o, v) => o.#e = v]], [dec], _ => #e in _));
_initStatic(this);
}
#f = _call_f;
a = (_initProto(this), _init_a(this));
b() {}
get c() {}
set c(v) {}
#A = _init_d(this);
get d() {
return this.#A;
}
set d(v) {
this.#A = v;
}
#e = _init_e(this);
get #g() {
return _call_g(this);
}
set #g(v) {
_call_g2(this, v);
}
#B = _init_h(this);
set #h(v) {
_set_h(this, v);
}
get #h() {
return _get_h(this);
}
static j() {}
static get k() {}
static set l(v) {}
static get m() {
return this.#C;
}
static set m(v) {
this.#C = v;
}
static [class Class {
static {
({
e: [_init_m, _call_o, _call_p, _call_q, _init_r, _get_r, _set_r, _init_d, _call_f, _call_g, _call_g2, _init_h, _get_h, _set_h, _init_i, _init_n, _init_a, _init_e, _initProto, _initStatic],
c: [_Class, _initClass]
} = babelHelpers.applyDecs2301(this, [[dec, 7, "j"], [dec, 8, "k"], [dec, 9, "l"], [dec, 6, "m"], [dec, 7, "o", function () {}], [dec, 8, "p", function () {}], [dec, 9, "q", function (v) {}], [dec, 6, "r", o => o.#D, (o, v) => o.#D = v], [dec, 2, "b"], [dec, 3, "c"], [dec, 4, "c"], [dec, 1, "d"], [dec, 2, "f", function () {}], [dec, 3, "g", function () {}], [dec, 4, "g", function (v) {}], [dec, 1, "h", o => o.#B, (o, v) => o.#B = v], [dec, 5, "i"], [dec, 5, "n", o => o.#n, (o, v) => o.#n = v], [dec, 0, "a"], [dec, 0, "e", o => o.#e, (o, v) => o.#e = v]], [dec], _ => #e in _));
_initStatic(this);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can optimize this output in the future?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. Though the output here is only one trailing ; more than what we currently have. The output change here is introduced in 2d34eeb, which changes the output static { class { ... } } to static [ class { ... } ];.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if we can merge them into one class. :)
The changes here look good to me, the properties are kept in the outer class which greatly improves readability.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merge them into one class

The non static elements are split because the static fields have to be installed on the replaced class. If we can merge them without too much effort, #16176 will be automatically resolved.

path.stop();
}
},
});
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can directly access the originalClass path according to the AST hierarchy.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return getComputedKeyCompletion(expressions[expressions.length - 1]);
}
return path;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this function is not meant for complex completion cases like path.getCompletionRecord() can handle, e.g. it does not support do expressions, I suggest rename it to getComputedKeyLastElement so that it is not confused with the completion concept in the spec.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const applyDecsBody = applyDecoratorWrapper.body;
if (computedKeyAssignments.length > 0) {
const elements = originalClassPath.get("body.body");
let lastPublicElement: NodePath<t.ClassProperty | t.ClassMethod>;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The computedKeyAssignments hosts decorator and computed keys evaluation results. They will be referenced in the applyDecs call emited in the first static block of the class. I think the output will be slightly more readable if we insert the assignments to the first public element, so that they will not be too far away from where they will be used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

- rename some routines
- improve originalClassPath access, to avoid a full traversal
- add more jsdoc coments
Copy link
Member

@nicolo-ribaudo nicolo-ribaudo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well done!

@JLHwung JLHwung merged commit 206ebf3 into babel:main Mar 6, 2024
50 checks passed
@JLHwung JLHwung deleted the fix-decorator-evaluation-private-environment branch March 6, 2024 14:14
Vylpes pushed a commit to Vylpes/random-bunny that referenced this pull request Apr 15, 2024
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [@babel/traverse](https://babel.dev/docs/en/next/babel-traverse) ([source](https://github.com/babel/babel)) | resolutions | minor | [`7.23.9` -> `7.24.1`](https://renovatebot.com/diffs/npm/@babel%2ftraverse/7.23.9/7.24.1) |

---

### Release Notes

<details>
<summary>babel/babel (@&#8203;babel/traverse)</summary>

### [`v7.24.1`](https://github.com/babel/babel/blob/HEAD/CHANGELOG.md#v7241-2024-03-19)

[Compare Source](babel/babel@v7.24.0...v7.24.1)

##### 🐛 Bug Fix

-   `babel-helper-create-class-features-plugin`, `babel-plugin-proposal-decorators`
    -   [#&#8203;16350](babel/babel#16350) Fix decorated class computed keys ordering ([@&#8203;JLHwung](https://github.com/JLHwung))
    -   [#&#8203;16344](babel/babel#16344) Fix decorated class static field private access ([@&#8203;JLHwung](https://github.com/JLHwung))
-   `babel-plugin-proposal-decorators`, `babel-plugin-proposal-json-modules`, `babel-plugin-transform-async-generator-functions`, `babel-plugin-transform-regenerator`, `babel-plugin-transform-runtime`, `babel-preset-env`
    -   [#&#8203;16329](babel/babel#16329) Respect `moduleName` for `@babel/runtime/regenerator` imports ([@&#8203;nicolo-ribaudo](https://github.com/nicolo-ribaudo))
-   `babel-helper-create-class-features-plugin`, `babel-plugin-proposal-decorators`, `babel-plugin-proposal-pipeline-operator`, `babel-plugin-transform-class-properties`
    -   [#&#8203;16331](babel/babel#16331) Fix decorator memoiser binding kind ([@&#8203;JLHwung](https://github.com/JLHwung))
-   `babel-helper-create-class-features-plugin`, `babel-helper-replace-supers`, `babel-plugin-proposal-decorators`, `babel-plugin-transform-class-properties`
    -   [#&#8203;16325](babel/babel#16325) Fix decorator evaluation private environment ([@&#8203;JLHwung](https://github.com/JLHwung))

##### 📝 Documentation

-   [#&#8203;16319](babel/babel#16319) Update SECURITY.md ([@&#8203;nicolo-ribaudo](https://github.com/nicolo-ribaudo))

##### 🏠 Internal

-   `babel-code-frame`, `babel-highlight`
    -   [#&#8203;16359](babel/babel#16359) Replace `chalk` with `picocolors` ([@&#8203;nicolo-ribaudo](https://github.com/nicolo-ribaudo))
-   `babel-helper-fixtures`, `babel-helpers`, `babel-plugin-bugfix-safari-id-destructuring-collision-in-function-expression`, `babel-plugin-proposal-pipeline-operator`, `babel-plugin-transform-unicode-sets-regex`, `babel-preset-env`, `babel-preset-flow`
    -   [#&#8203;16352](babel/babel#16352) Run Babel transform tests on old node if possible ([@&#8203;JLHwung](https://github.com/JLHwung))
-   `babel-helpers`, `babel-plugin-transform-async-generator-functions`, `babel-plugin-transform-class-properties`, `babel-plugin-transform-class-static-block`, `babel-plugin-transform-modules-commonjs`, `babel-plugin-transform-modules-systemjs`, `babel-plugin-transform-regenerator`, `babel-plugin-transform-runtime`, `babel-preset-env`, `babel-runtime-corejs3`, `babel-runtime`, `babel-standalone`
    -   [#&#8203;16323](babel/babel#16323) Allow separate helpers to be excluded in Babel 8 ([@&#8203;liuxingbaoyu](https://github.com/liuxingbaoyu))
-   `babel-helper-module-imports`, `babel-plugin-proposal-import-wasm-source`, `babel-plugin-proposal-json-modules`, `babel-plugin-proposal-record-and-tuple`, `babel-plugin-transform-react-jsx-development`, `babel-plugin-transform-react-jsx`
    -   [#&#8203;16349](babel/babel#16349) Support merging imports in import injector ([@&#8203;nicolo-ribaudo](https://github.com/nicolo-ribaudo))
-   `babel-helper-create-class-features-plugin`, `babel-plugin-bugfix-safari-id-destructuring-collision-in-function-expression`, `babel-plugin-bugfix-v8-spread-parameters-in-optional-chaining`, `babel-plugin-bugfix-v8-static-class-fields-redefine-readonly`, `babel-plugin-external-helpers`, `babel-plugin-proposal-async-do-expressions`, `babel-plugin-proposal-decorators`, `babel-plugin-proposal-destructuring-private`, `babel-plugin-proposal-do-expressions`, `babel-plugin-proposal-duplicate-named-capturing-groups-regex`, `babel-plugin-proposal-explicit-resource-management`, `babel-plugin-proposal-export-default-from`, `babel-plugin-proposal-function-bind`, `babel-plugin-proposal-function-sent`, `babel-plugin-proposal-import-attributes-to-assertions`, `babel-plugin-proposal-import-defer`, `babel-plugin-proposal-import-wasm-source`, `babel-plugin-proposal-json-modules`, `babel-plugin-proposal-optional-chaining-assign`, `babel-plugin-proposal-partial-application`, `babel-plugin-proposal-pipeline-operator`, `babel-plugin-proposal-record-and-tuple`, `babel-plugin-proposal-regexp-modifiers`, `babel-plugin-proposal-throw-expressions`, `babel-plugin-syntax-async-do-expressions`, `babel-plugin-syntax-decimal`, `babel-plugin-syntax-decorators`, `babel-plugin-syntax-destructuring-private`, `babel-plugin-syntax-do-expressions`, `babel-plugin-syntax-explicit-resource-management`, `babel-plugin-syntax-export-default-from`, `babel-plugin-syntax-flow`, `babel-plugin-syntax-function-bind`, `babel-plugin-syntax-function-sent`, `babel-plugin-syntax-import-assertions`, `babel-plugin-syntax-import-attributes`, `babel-plugin-syntax-import-defer`, `babel-plugin-syntax-import-reflection`, `babel-plugin-syntax-import-source`, `babel-plugin-syntax-jsx`, `babel-plugin-syntax-module-blocks`, `babel-plugin-syntax-optional-chaining-assign`, `babel-plugin-syntax-partial-application`, `babel-plugin-syntax-pipeline-operator`, `babel-plugin-syntax-record-and-tuple`, `babel-plugin-syntax-throw-expressions`, `babel-plugin-syntax-typescript`, `babel-plugin-transform-arrow-functions`, `babel-plugin-transform-async-generator-functions`, `babel-plugin-transform-async-to-generator`, `babel-plugin-transform-block-scoped-functions`, `babel-plugin-transform-block-scoping`, `babel-plugin-transform-class-properties`, `babel-plugin-transform-class-static-block`, `babel-plugin-transform-classes`, `babel-plugin-transform-computed-properties`, `babel-plugin-transform-destructuring`, `babel-plugin-transform-dotall-regex`, `babel-plugin-transform-duplicate-keys`, `babel-plugin-transform-dynamic-import`, `babel-plugin-transform-exponentiation-operator`, `babel-plugin-transform-export-namespace-from`, `babel-plugin-transform-flow-comments`, `babel-plugin-transform-flow-strip-types`, `babel-plugin-transform-for-of`, `babel-plugin-transform-function-name`, `babel-plugin-transform-instanceof`, `babel-plugin-transform-jscript`, `babel-plugin-transform-json-strings`, `babel-plugin-transform-literals`, `babel-plugin-transform-logical-assignment-operators`, `babel-plugin-transform-member-expression-literals`, `babel-plugin-transform-modules-amd`, `babel-plugin-transform-modules-commonjs`, `babel-plugin-transform-modules-systemjs`, `babel-plugin-transform-modules-umd`, `babel-plugin-transform-new-target`, `babel-plugin-transform-nullish-coalescing-operator`, `babel-plugin-transform-numeric-separator`, `babel-plugin-transform-object-assign`, `babel-plugin-transform-object-rest-spread`, `babel-plugin-transform-object-set-prototype-of-to-assign`, `babel-plugin-transform-object-super`, `babel-plugin-transform-optional-catch-binding`, `babel-plugin-transform-optional-chaining`, `babel-plugin-transform-parameters`, `babel-plugin-transform-private-methods`, `babel-plugin-transform-private-property-in-object`, `babel-plugin-transform-property-literals`, `babel-plugin-transform-property-mutators`, `babel-plugin-transform-proto-to-assign`, `babel-plugin-transform-react-constant-elements`, `babel-plugin-transform-react-display-name`, `babel-plugin-transform-react-inline-elements`, `babel-plugin-transform-react-jsx-compat`, `babel-plugin-transform-react-jsx-self`, `babel-plugin-transform-react-jsx-source`, `babel-plugin-transform-react-pure-annotations`, `babel-plugin-transform-regenerator`, `babel-plugin-transform-reserved-words`, `babel-plugin-transform-runtime`, `babel-plugin-transform-shorthand-properties`, `babel-plugin-transform-spread`, `babel-plugin-transform-sticky-regex`, `babel-plugin-transform-strict-mode`, `babel-plugin-transform-template-literals`, `babel-plugin-transform-typeof-symbol`, `babel-plugin-transform-typescript`, `babel-plugin-transform-unicode-escapes`, `babel-plugin-transform-unicode-property-regex`, `babel-plugin-transform-unicode-regex`, `babel-plugin-transform-unicode-sets-regex`, `babel-preset-env`, `babel-preset-flow`, `babel-preset-react`, `babel-preset-typescript`
    -   [#&#8203;16332](babel/babel#16332) Test Babel 7 plugins compatibility with Babel 8 core ([@&#8203;nicolo-ribaudo](https://github.com/nicolo-ribaudo))
-   `babel-compat-data`, `babel-plugin-transform-object-rest-spread`, `babel-preset-env`
    -   [#&#8203;16318](babel/babel#16318) \[babel 8] Fix `@babel/compat-data` package.json ([@&#8203;nicolo-ribaudo](https://github.com/nicolo-ribaudo))

##### 🔬 Output optimization

-   `babel-helper-replace-supers`, `babel-plugin-transform-class-properties`, `babel-plugin-transform-classes`, `babel-plugin-transform-parameters`, `babel-plugin-transform-runtime`
    -   [#&#8203;16345](babel/babel#16345) Optimize the use of `assertThisInitialized` after `super()` ([@&#8203;liuxingbaoyu](https://github.com/liuxingbaoyu))
-   `babel-plugin-transform-class-properties`, `babel-plugin-transform-classes`
    -   [#&#8203;16343](babel/babel#16343) Use simpler `assertThisInitialized` more often ([@&#8203;liuxingbaoyu](https://github.com/liuxingbaoyu))
-   `babel-plugin-proposal-decorators`, `babel-plugin-transform-class-properties`, `babel-plugin-transform-object-rest-spread`, `babel-traverse`
    -   [#&#8203;16342](babel/babel#16342) Consider well-known and registered symbols as literals ([@&#8203;nicolo-ribaudo](https://github.com/nicolo-ribaudo))
-   `babel-core`, `babel-plugin-external-helpers`, `babel-plugin-proposal-decorators`, `babel-plugin-proposal-function-bind`, `babel-plugin-transform-class-properties`, `babel-plugin-transform-classes`, `babel-plugin-transform-flow-comments`, `babel-plugin-transform-flow-strip-types`, `babel-plugin-transform-function-name`, `babel-plugin-transform-modules-systemjs`, `babel-plugin-transform-parameters`, `babel-plugin-transform-private-property-in-object`, `babel-plugin-transform-react-jsx`, `babel-plugin-transform-runtime`, `babel-plugin-transform-spread`, `babel-plugin-transform-typescript`, `babel-preset-env`
    -   [#&#8203;16326](babel/babel#16326) Reduce the use of class names ([@&#8203;liuxingbaoyu](https://github.com/liuxingbaoyu))

### [`v7.24.0`](https://github.com/babel/babel/blob/HEAD/CHANGELOG.md#v7240-2024-02-28)

[Compare Source](babel/babel@v7.23.9...v7.24.0)

##### 🚀 New Feature

-   `babel-standalone`
    -   [#&#8203;11696](babel/babel#11696) Export babel tooling packages in `@babel/standalone` ([@&#8203;ajihyf](https://github.com/ajihyf))
-   `babel-core`, `babel-helper-create-class-features-plugin`, `babel-helpers`, `babel-plugin-transform-class-properties`
    -   [#&#8203;16267](babel/babel#16267) Implement `noUninitializedPrivateFieldAccess` assumption ([@&#8203;nicolo-ribaudo](https://github.com/nicolo-ribaudo))
-   `babel-helper-create-class-features-plugin`, `babel-helpers`, `babel-plugin-proposal-decorators`, `babel-plugin-proposal-pipeline-operator`, `babel-plugin-syntax-decorators`, `babel-plugin-transform-class-properties`, `babel-runtime-corejs2`, `babel-runtime-corejs3`, `babel-runtime`
    -   [#&#8203;16242](babel/babel#16242) Support decorator 2023-11 normative updates ([@&#8203;JLHwung](https://github.com/JLHwung))
-   `babel-preset-flow`
    -   [#&#8203;16309](babel/babel#16309) \[babel 7] Allow setting `ignoreExtensions` in Flow preset ([@&#8203;nicolo-ribaudo](https://github.com/nicolo-ribaudo))
    -   [#&#8203;16284](babel/babel#16284) Add `experimental_useHermesParser` option in `preset-flow` ([@&#8203;liuxingbaoyu](https://github.com/liuxingbaoyu))
-   `babel-helper-import-to-platform-api`, `babel-plugin-proposal-import-wasm-source`, `babel-plugin-proposal-json-modules`, `babel-standalone`
    -   [#&#8203;16172](babel/babel#16172) Add transform support for JSON modules imports ([@&#8203;nicolo-ribaudo](https://github.com/nicolo-ribaudo))
-   `babel-plugin-transform-runtime`
    -   [#&#8203;16241](babel/babel#16241) Add back `moduleName` option to `@babel/plugin-transform-runtime` ([@&#8203;nicolo-ribaudo](https://github.com/nicolo-ribaudo))
-   `babel-parser`, `babel-types`
    -   [#&#8203;16277](babel/babel#16277) Allow import attributes for `TSImportType` ([@&#8203;sosukesuzuki](https://github.com/sosukesuzuki))

##### 🐛 Bug Fix

-   `babel-plugin-proposal-do-expressions`, `babel-traverse`
    -   [#&#8203;16305](babel/babel#16305) fix: avoid `popContext` on unvisited node paths ([@&#8203;JLHwung](https://github.com/JLHwung))
-   `babel-helper-create-class-features-plugin`, `babel-plugin-transform-private-methods`, `babel-plugin-transform-private-property-in-object`
    -   [#&#8203;16312](babel/babel#16312) Fix class private properties when `privateFieldsAsSymbols` ([@&#8203;liuxingbaoyu](https://github.com/liuxingbaoyu))
-   `babel-helper-create-class-features-plugin`, `babel-plugin-transform-private-methods`
    -   [#&#8203;16307](babel/babel#16307) Fix the support of `arguments` in private `get/set` method ([@&#8203;liuxingbaoyu](https://github.com/liuxingbaoyu))
-   `babel-helper-create-class-features-plugin`, `babel-helpers`, `babel-plugin-proposal-decorators`
    -   [#&#8203;16287](babel/babel#16287) Reduce decorator static property size ([@&#8203;liuxingbaoyu](https://github.com/liuxingbaoyu))
-   `babel-helper-create-class-features-plugin`, `babel-plugin-proposal-decorators`
    -   [#&#8203;16281](babel/babel#16281) Fix evaluation order of decorators with cached receiver ([@&#8203;nicolo-ribaudo](https://github.com/nicolo-ribaudo))
    -   [#&#8203;16279](babel/babel#16279) Fix decorator this memoization ([@&#8203;JLHwung](https://github.com/JLHwung))
    -   [#&#8203;16266](babel/babel#16266) Preserve `static` on decorated private `accessor` ([@&#8203;nicolo-ribaudo](https://github.com/nicolo-ribaudo))
    -   [#&#8203;16258](babel/babel#16258) fix: handle decorated async private method and generator ([@&#8203;JLHwung](https://github.com/JLHwung))
-   `babel-helper-create-class-features-plugin`, `babel-plugin-proposal-decorators`, `babel-plugin-transform-async-generator-functions`, `babel-plugin-transform-private-methods`, `babel-plugin-transform-private-property-in-object`, `babel-plugin-transform-typescript`, `babel-preset-env`
    -   [#&#8203;16275](babel/babel#16275) Fix class private properties when `privateFieldsAsProperties` ([@&#8203;liuxingbaoyu](https://github.com/liuxingbaoyu))
-   `babel-helpers`
    -   [#&#8203;16268](babel/babel#16268) Do not consider `arguments` in a helper as a global reference ([@&#8203;nicolo-ribaudo](https://github.com/nicolo-ribaudo))
-   `babel-helpers`, `babel-plugin-proposal-decorators`
    -   [#&#8203;16270](babel/babel#16270) Handle symbol key class elements decoration ([@&#8203;JLHwung](https://github.com/JLHwung))
    -   [#&#8203;16265](babel/babel#16265) Do not define `access.get` for public setter decorators ([@&#8203;nicolo-ribaudo](https://github.com/nicolo-ribaudo))

##### 💅 Polish

-   `babel-core`, `babel-helper-create-class-features-plugin`, `babel-preset-env`
    -   [#&#8203;12428](babel/babel#12428) Suggest using `BABEL_SHOW_CONFIG_FOR` for config problems ([@&#8203;nicolo-ribaudo](https://github.com/nicolo-ribaudo))

##### 🏠 Internal

-   `babel-helper-transform-fixture-test-runner`
    -   [#&#8203;16278](babel/babel#16278) Continue writing `output.js` when `exec.js` throws ([@&#8203;liuxingbaoyu](https://github.com/liuxingbaoyu))

##### 🔬 Output optimization

-   `babel-helper-create-class-features-plugin`, `babel-plugin-proposal-decorators`
    -   [#&#8203;16306](babel/babel#16306) Avoid intermediate functions for private accessors with decs ([@&#8203;nicolo-ribaudo](https://github.com/nicolo-ribaudo))
-   `babel-helper-create-class-features-plugin`, `babel-helpers`, `babel-plugin-proposal-decorators`, `babel-plugin-proposal-pipeline-operator`, `babel-plugin-transform-class-properties`
    -   [#&#8203;16294](babel/babel#16294) More aggressively inline decorators in the static block ([@&#8203;nicolo-ribaudo](https://github.com/nicolo-ribaudo))
-   `babel-helper-create-class-features-plugin`, `babel-helpers`, `babel-plugin-transform-private-methods`
    -   [#&#8203;16283](babel/babel#16283) Do not use `classPrivateMethodGet` ([@&#8203;liuxingbaoyu](https://github.com/liuxingbaoyu))
-   `babel-helper-create-class-features-plugin`, `babel-helpers`, `babel-plugin-proposal-decorators`
    -   [#&#8203;16287](babel/babel#16287) Reduce decorator static property size ([@&#8203;liuxingbaoyu](https://github.com/liuxingbaoyu))
-   `babel-helper-create-class-features-plugin`, `babel-plugin-proposal-decorators`, `babel-plugin-transform-class-properties`
    -   [#&#8203;16280](babel/babel#16280) Reduce element decorator temp variables ([@&#8203;JLHwung](https://github.com/JLHwung))
-   `babel-helper-create-class-features-plugin`, `babel-helper-fixtures`, `babel-helpers`, `babel-plugin-bugfix-v8-spread-parameters-in-optional-chaining`, `babel-plugin-proposal-decorators`, `babel-plugin-proposal-destructuring-private`, `babel-plugin-proposal-optional-chaining-assign`, `babel-plugin-transform-class-properties`, `babel-plugin-transform-class-static-block`, `babel-plugin-transform-private-methods`, `babel-plugin-transform-private-property-in-object`, `babel-preset-env`, `babel-runtime-corejs2`, `babel-runtime-corejs3`, `babel-runtime`
    -   [#&#8203;16261](babel/babel#16261) Do not use descriptors for private class elements ([@&#8203;nicolo-ribaudo](https://github.com/nicolo-ribaudo))
-   `babel-helpers`, `babel-plugin-proposal-decorators`
    -   [#&#8203;16263](babel/babel#16263) Reduce helper size for decorator 2023-11 ([@&#8203;liuxingbaoyu](https://github.com/liuxingbaoyu))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4wLjAiLCJ1cGRhdGVkSW5WZXIiOiIzNy4wLjAiLCJ0YXJnZXRCcmFuY2giOiJkZXZlbG9wIn0=-->

Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/random-bunny/pulls/156
Co-authored-by: Renovate Bot <renovate@vylpes.com>
Co-committed-by: Renovate Bot <renovate@vylpes.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PR: Bug Fix 🐛 A type of pull request used for our changelog categories Spec: Decorators
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug]: Element decorator referencing both this and local private field is not compiled properly
4 participants