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

Transform class static block #12143

Conversation

@JLHwung
Copy link
Contributor

@JLHwung JLHwung commented Oct 6, 2020

Q                       A
Minor: New Feature? Yes
Tests Added + Pass? Yes
Documentation PR Link babel/website#2398
Any Dependency Changes?
License MIT

This PR implements Stage 2 Class static block proposal. It is an early draft as more test cases are required.

This idea is to transform static { } to a private static field initializer. So

class Foo {
static {
this.foo = this.bar;
}
static bar = 42;
}

will be transformed as
class Foo {
static bar = 42;
static #_ = (() => {
this.foo = this.bar;
})();
}

You can also try out at Babel REPL.

/cc @rbuckton This approach is slightly different to the "Motivation" section of the proposal, where the static block statements are inserted after class definitions. I think this approach will be more convenient for implementors. They can reuse static methods which already provide proper access to private elements and super properties.

I didn't try to implement this feature in @babel/plugin-helper-create-class-features-plugin because I think the class static block features can be polyfilled by static class methods mentioned above. So it does not rely on how other class features (properties, private methods) are transformed.

@babel-bot
Copy link
Collaborator

@babel-bot babel-bot commented Oct 6, 2020

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

@JLHwung JLHwung added this to the v7.12.0 milestone Oct 6, 2020
@codesandbox
Copy link

@codesandbox codesandbox bot commented Oct 6, 2020

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 4154ffa:

Sandbox Source
babel-repl-custom-plugin Configuration
babel-plugin-multi-config Configuration
@nicolo-ribaudo
Copy link
Member

@nicolo-ribaudo nicolo-ribaudo commented Oct 6, 2020

What about this?

class Foo { 
  static { 
    this.foo = 42; 
  } 
} 
class Foo {
  #_ = (() => {
    this.foo = 42; 
  })();
}

It is completely self-contained (it doesn't leak .init()), and we don't need to transpile it further in browsers with support for static private fields.

@nicolo-ribaudo nicolo-ribaudo mentioned this pull request Oct 6, 2020
2 of 2 tasks complete
@JLHwung JLHwung force-pushed the JLHwung:transform-class-static-block branch from 4ce6931 to ca389fb Oct 6, 2020
@JLHwung JLHwung changed the base branch from main to feat-7.12.0/class-static-block Oct 6, 2020
@JLHwung
Copy link
Contributor Author

@JLHwung JLHwung commented Oct 6, 2020

@nicolo-ribaudo The class element initializer does not have access to the initialized class name binding.

class Foo {
  #_ = (() => {
    Foo.foo = 42; // <-- Foo here is undefined
  })();
}
@nicolo-ribaudo
Copy link
Member

@nicolo-ribaudo nicolo-ribaudo commented Oct 6, 2020

My mistake, I meant the private field to be static:

class Foo {
  static #_ = (() => {
    this.foo = 42; 
    console.log(Foo);
  })();
}

In chromium this works, I'm now checking the spec to understand where the binding is initialized.

EDIT: https://tc39.es/proposal-static-class-features/#runtime-semantics-class-definition-evaluation - The binding is initialized at step 30.a, and the static field is evaluated at step 34.a.

export default declare(({ types: t, template, assertVersion }) => {
// todo remove this check after Babel 7.12.0 is published
if (process.env.NODE_ENV !== "test") {
assertVersion("^7.12.0");

This comment has been minimized.

@JLHwung

JLHwung Oct 6, 2020
Author Contributor

As a new package it requires @babel/core 7.12.0. It depends on @babel/type 7.12.0 and @babel/parser 7.12.0.

Co-Authored-By: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>
@JLHwung JLHwung force-pushed the JLHwung:transform-class-static-block branch from 8523873 to ffa4a78 Oct 6, 2020
@JLHwung JLHwung force-pushed the JLHwung:transform-class-static-block branch from 474cc03 to cf10e41 Oct 6, 2020
@nicolo-ribaudo
Copy link
Member

@nicolo-ribaudo nicolo-ribaudo commented Oct 6, 2020

We should also test how this behaves with the private fields transform (plugin ordering 😛).

@nicolo-ribaudo
Copy link
Member

@nicolo-ribaudo nicolo-ribaudo commented Oct 6, 2020

(If we detect the wrong order, we can just throw an error asking users to swap the two plugins)

@JLHwung
Copy link
Contributor Author

@JLHwung JLHwung commented Oct 6, 2020

We should also test how this behaves with the private fields transform (plugin ordering 😛).

@nicolo-ribaudo Yes that is how I am gonna fix "you should specify a test" error on node 10.

@JLHwung JLHwung force-pushed the JLHwung:transform-class-static-block branch from adc83d8 to bc467f5 Oct 6, 2020
@JLHwung JLHwung force-pushed the JLHwung:transform-class-static-block branch from bc467f5 to bed0bd4 Oct 6, 2020
@JLHwung

This comment has been hidden.

Co-authored-by: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>
Co-authored-by: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>
@JLHwung JLHwung force-pushed the JLHwung:transform-class-static-block branch from d6d40d9 to 09d1f8a Oct 11, 2020
JLHwung and others added 2 commits Oct 13, 2020
Co-authored-by: Brian Ng <bng412@gmail.com>
@nicolo-ribaudo nicolo-ribaudo merged commit 413892f into babel:feat-7.12.0/class-static-block Oct 14, 2020
15 of 16 checks passed
15 of 16 checks passed
Prepare Cache
Details
Test on Node.js Latest
Details
Build Babel Artifacts
Details
Test on Node.js (13)
Details
Test on Node.js (12)
Details
Test on Node.js (10)
Details
Test on Node.js (8)
Details
Test on Node.js (6)
Details
test262-pr Workflow: test262-pr
Details
Gitpod Open an online workspace in Gitpod
Details
Travis CI - Pull Request Build Passed
Details
babel/repl REPL preview is available
Details
build-standalone Workflow: build-standalone
Details
ci/codesandbox Building packages succeeded.
Details
codecov/project 91.76% (target 90.00%)
Details
e2e Workflow: e2e
Details
@nicolo-ribaudo nicolo-ribaudo deleted the JLHwung:transform-class-static-block branch Oct 14, 2020
nicolo-ribaudo added a commit that referenced this pull request Oct 14, 2020
Co-authored-by: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>
Co-authored-by: Brian Ng <bng412@gmail.com>
nicolo-ribaudo added a commit that referenced this pull request Oct 14, 2020
Co-authored-by: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>
Co-authored-by: Brian Ng <bng412@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

4 participants
You can’t perform that action at this time.