closure-compiler
closure-compiler copied to clipboard
Add Support for Public Class Fields
It is becoming common place to use class fields and this is not yet supported from ES6 to ES5 conversion via closure compiler
https://github.com/tc39/proposal-class-fields
Also Static Class Fields: https://github.com/tc39/proposal-static-class-features/
They are stage 3 features now. https://github.com/tc39/proposals
I wish to see this feature soon in closure compiler, having static fields helps a lot in class feature encapsulation.
class A {
static a = 1;
}
instead of:
class A {}
A.a = 1;
We've been looking forward to this feature making it to stage 4, also. We're not ready to implement it in closure-compiler yet, but it is on our minds.
@brad4d does a feature have to make it to stage 4 before implementing? Browsers will generally implement before stage 4, and all the other compilers I know of support class fields.
We've implemented features at stage 3 before. It's just a matter of priority or someone willing to contribute the work.
At stage 3 now and shipping in V8.
https://github.com/tc39/proposal-class-fields https://twitter.com/_gsathya/status/1100845457876541442
Exciting!
Created internal issue: http://b/127859638
@justinfagnani I'm actively working on an official SLO for handling new features. It still requires review, but the current draft calls for us to start working on stage 3 features when we see that browsers have started adding support. (Lots of definition needed of what that means exactly.)
@arv One thing that I find discourages me from prioritizing class fields over other stage 3 features, like BigInt, is that there still are no official tests associated with the proposal according to the TC39 active proposals page. http://go/gh/tc39/proposals/blob/master/README.md
We would like to have these to base our unit tests on. Do you know why there aren't any yet? Thanks.
@brad4d there are a ton of tests for public, private, and static fields and methods: https://github.com/tc39/test262/tree/master/src/class-elements
@justinfagnani Thanks for pointing out those tests. I guess the page I pointed to needs to be updated.
If/when this ships, will it require an opt-in? Perhaps via @language ECMASCRIPT_2017
?
The proposal is still a stage 3 proposal, i.e. not yet part of a language standard, but the current assumption (I think) is that it will become part of ES2020
@blickly Stage 3 is when implementors should implement. Chrome is already shipping public and private class fields. As an implementor, the time for Closure to implement is now, you don't have to wait for Stage 4.
Agreed, I'm just responding to the question of which language version it will be in (i.e. not ES2017)
Ah, sorry then!
@loadedsith if/when this feature ships you'll at least initially have to ask the compiler to handle it by specifying language_in
to be the ES version in which it lands. (Probably ES_2020 as @blickly pointed out.)
When we feel it is safe to do so, we'll likely modify the default for language_in
to be that new ES version, at which point it is no longer an "opt in" feature.
Thank you 3 for the informative replies. I'm looking forward to it.
Hello @brad4d - I am very interested in the SLO you mentioned. Is there a link to this?
The Class Fields proposal has shipped in Chrome, Node LTS, Moddable XS, QuickJS, Babel, TypeScript nightly, and Firefox (public-fields-only). The corresponding test262 tests were declared complete on 10 November 2017. Do you think it is now appropriate to ship in GCC?
I'm afraid the SLO isn't in a publicly accessible place right now, but the gist of it is we want to have support for new JS features added to the compiler and available with --language_in=ES_20XX
within 6 months of ES_20XX
being officially defined.
Although they've been shipped in some form or other by several products, the TC39 committee hasn't discussed moving the relevant proposals for class fields forward to stage 4 (i.e. officially in the next version of the language) since January 2019.
See https://github.com/tc39/proposals/blob/master/README.md
It's possible that they will promote them to stage 4 in the February meeting, making them part of ES_2020
, but we have other things that are definitely in ES_2020
to work on first.
We're currently working on nullish coalescing (https://github.com/tc39/proposal-nullish-coalescing) and optional chaining (https://github.com/tc39/proposal-optional-chaining), which were promoted to stage 4 in December.
Waiting for stage 4 is really the wrong thing for tools like this. Stage 3 is when tools are expected to implement. Stage 4 is recognition that there wasn't some catastrophic failure in stage 3. Shipping is what counts, and class fields have shipped in enough implementations to not be at risk of rollback, (even with previously threatened TC39 consensus shenanigans, which aren't even a potential issue anymore).
Note the wording for stage 3:
The solution is complete and no further work is possible without implementation experience, significant usage and external feedback.
It sounds like the SLO / feature approach, if strictly applied to stage 4 features only, would leave out very widely implemented things like dynamic import()
. I know there's not a readily available other label for a feature set, but the official ES year isn't great either. It doesn't indicate what's actually usable in any implementation.
The fact that V8 has supported this for over a year yet Closure Compiler will immediately throw an error seems a little silly. Support for this would be completely non-breaking, there would be no difference in compilation output for people who did not use static public fields in their source code. Waiting for Stage 4 literally just prevents people from using this pattern at all in code that will be CC'd.
I'm having to do:
class Child extends Parent {
static get a() {
return 4;
}
}
To override a static property right now, if I want my code to compile without doing a class declaration and then setting the field manually (which is horribly disorganized). Replacing with static a = 4
works in Chrome without issue, but the compiler won't take it at all.
Would a PR adding support for static class fields get approved?
Adding a new feature like this to the compiler takes a large number of changes. There's no way to do it in a single PR.
As a sampling:
- New AST node types must be created and
AstValidator
updated to ensure the correct shape of the AST is maintained for them. - The parser and code printer must be updated to parse and print code using the new feature.
- Dozens of compiler passes must be updated to make sure they don't choke on the new AST nodes for the feature.
- A transpilation pass must be written to downlevel the feature to work on older browsers.
And there's more....
Also, class fields behavior as defined by the spec is more complex than one would initially think. Doing this work requires creating a plan, getting agreement that it's a good one, then working through it with regular discussions of problems as they come up.
Sorry. If it were easy, we would have done it already.
This feature is top of my mind when it comes to things to work on after our current efforts to support BigInt and optional chaining.
Thanks for the clarification @brad4d.
I've resorted to transpiling class fields to get
methods until native support for this is added.
adding private fields and methods too?
plzsir my #private fields
Hi
Do you have contemplate include Private class fields soonly ?
Currently I get this error:
`ERROR - [JSC_PARSE_ERROR] Parse error. '}' expected #cOps ^
1 error(s), 0 warning(s)`
thanks
@helenlpang is currently working on support for public fields (both static and non), but #private
fields will unfortunately have to wait until after that is done.
Just a note, Class Fields are now Stage 4 and included in the ECMAScript 2022 draft specification. https://tc39.es/ecma262/#sec-classfielddefinition-record-specification-type