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

Ensure class decorators can access decorated non-static members #15332

Merged
merged 7 commits into from
Jan 18, 2023

Conversation

JLHwung
Copy link
Contributor

@JLHwung JLHwung commented Jan 6, 2023

Q                       A
Fixed Issues? Fixes #15325
Patch: Bug Fix? Yes
Major: Breaking Change?
Minor: New Feature?
Tests Added + Pass? Yes
Documentation PR Link
Any Dependency Changes?
License MIT
  • Introduce a new runtime helper applyDecs2203R based on applyDecs2203, which lazily apply class decorations so that the class decorate will have access to the decorated non-static class elements. Because the return type is changed, we have to create a new runtime. In Babel 8 we can remove deprecated helpers applyDecs2203 and applyDecs
  • Optimize the output when only the class is decorated or elements are decorated

This PR slightly increases the output size:

// before
[_init_a, _initProto] = babelHelpers.applyDecs2203(Foo, [[dec, 1, "a"]], []);
// after
[_init_a, _initProto] = babelHelpers.applyDecs2203R(Foo, [[dec, 1, "a"]], []).e;

We could preserve the output size if applyDecs2203R can return a customized iterator, i.e.

yield* applyMemberDecs(targetClass, memberDecs);
yield* applyClassDecs(targetClass, classDecs);

but then our runtime helper will not be ES5-compliant. We can revisit this approach if we bump helper targets in the future.

@JLHwung JLHwung added PR: Bug Fix 🐛 A type of pull request used for our changelog categories Spec: Decorators labels Jan 6, 2023
Comment on lines +625 to +627
get c() {
return applyClassDecs(targetClass, classDecs);
},
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 class decorators are applied after member decorators are applied and bound to the initializer locals, such as initA, initProto, etc.

@babel-bot
Copy link
Collaborator

babel-bot commented Jan 6, 2023

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

@liuxingbaoyu
Copy link
Member

The CI failure looks related.

@JLHwung
Copy link
Contributor Author

JLHwung commented Jan 9, 2023

Yes. CI is failing for the same reason of #14836 (comment). I will investigate how I can resolve it without renaming functions.

@nicolo-ribaudo
Copy link
Member

Helper diff: https://www.diffchecker.com/wMz5rhsx/

@JLHwung
Copy link
Contributor Author

JLHwung commented Jan 9, 2023

The e2e build was failing because we simply concat all helper codes in build-external-helpers:

helpers.list.forEach(function (name) {
if (allowlist && allowlist.indexOf(name) < 0) return;
const ref = (refs[name] = getHelperReference(name));
helpers.ensure(name, File);
const { nodes } = helpers.get(name, getHelperReference, ref);
body.push(...nodes);
});

which forms the content of the virtual \u0000RollupPluginBabelHelpers module created by the rollup Babel plugin.

A proper fix would be to handle function name collisions in build-external-helpers, but given that in most cases, the function names collide because we intend to replace the runtime with a new version. With the old runtime deprecated and hopefully removed in the next major, I think wrapping it into a factory is sufficient.

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.

@JLHwung The Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: error has been removed from the new helper: is it now supported, or was that error just unreachable?

This PR slightly increases the output size:

It's fine, decorators are already considered heavy and this is just a few more bytes.

@JLHwung
Copy link
Contributor Author

JLHwung commented Jan 9, 2023

The Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: error has been removed from the new helper

That part is not changed:

5dbfd3d#diff-1055897236adecf62778dc76b5b6168bc5c14344106b32a8a14c78479f601cb2R397

The only revisions are that applyMemberDecs and applyClassDecs now return the ret array, and the applyDecs returns an object served as a 2-item iterator. I can rewrite the commit history so we can easily review the difference.

…-03.ts

Co-authored-by: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>
@JLHwung JLHwung merged commit 0f68471 into babel:main Jan 18, 2023
@JLHwung JLHwung deleted the fix-15325 branch January 18, 2023 02:27
@github-actions github-actions bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Apr 20, 2023
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 20, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
outdated A closed issue/PR that is archived due to age. Recommended to make a new issue 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]: Stage 3 decorators: initializers are undefined in Custom Element constructors
4 participants