-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
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
Greater spec compliance for class properties #4544
Conversation
Object.defineProperty(_this, "scopedFunctionWithThis", { | ||
enumerable: true, | ||
writable: true, | ||
value: function value() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
value: function value()
^^^^^
Kinda meaningless function name inference here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, yeah seems like we'd ideally want to implement name inference here better, though it doesn't appear to be officially in the class-properties spec text anyway: tc39/proposal-class-public-fields#48
console.log(_this); | ||
}); | ||
|
||
return function value() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return function value() {
^^^^^
Kinda meaningless function name inference here. Also, the surrounding IIFE's sole purpose is to rename the function returned from asyncToGenerator
.
Current coverage is 88.83% (diff: 100%)
|
Commented on #4463 (comment) but duplicating over here: I think the fact that the Node REPL disagrees with the spec doesn't necessarily make this an obvious non-breaking change. I totally agree we should land this change, but since at least according to the spec it has the potential to be a breaking change, I'd prefer if we perhaps initially landed it as an opt-in option for the class property transform or something. As-is, this will also break |
We could do a loose mode for class properties as well? (although since it's breaking it would be the opposite atm) |
Yeah, perhaps we should go with |
Nevermind, I just didn't read the spec right :P We should be good as far as I'm all for this, but I do think it will need to be opt-in unfortunately, until we bump our major version anyway. |
Ok 👍 looks something like https://github.com/babel/babel/blob/master/packages/babel-plugin-transform-es2015-arrow-functions/src/index.js#L4-L5 https://github.com/babel/babel/blob/master/packages/babel-plugin-transform-es2015-arrow-functions/README.md |
Alrighty. The two new behaviors in this PR ( |
@@ -1,5 +1,5 @@ | |||
/* eslint max-len: 0 */ | |||
// todo: define instead of assign | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we drop this extra newline?
loose: (ref, {key, value}) => t.expressionStatement( | ||
t.assignmentExpression("=", t.memberExpression(ref, key), value) // TODO(motiz88): handle computed key | ||
) | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'd be better off using babel-template
for these, e.g.
import templates from 'babel-templates';
const buildPropertySpec = template(`
Object.defineProperty(REF, KEY, {
// configurable is false by default
enumerable: true,
writable: true,
value: VALUE,
});
`);
const buildProperty = template(`
REF[KEY] = VALUE;
`);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And per my example, let's not call the old behavior "loose" since it's not technically "loose" mode and that might lead to confusion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can also use template from the babel parameter - export default function ({ types: t, template }) {
but it would be created inside the function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That works too, though I think most of our plugins import it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've now implemented this change, but kept buildProperty
as a "raw" AST expression due to logic surrounding computed properties I'm not sure how to efficiently pack into template form.
@@ -55,18 +79,16 @@ export default function ({ types: t }) { | |||
for (let prop of props) { | |||
let propNode = prop.node; | |||
if (propNode.decorators && propNode.decorators.length > 0) continue; | |||
if (!propNode.value) continue; | |||
|
|||
if (!state.opts.spec && !propNode.value) continue; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feels like this could use a comment to make it clear why this is done.
c0d0f5e
to
935d7e8
Compare
I think this is it, as far as the requested changes go. I'm not crazy about the names |
Gave the helper functions new names, updated to latest master, everything works! 😀 Are we good to go? @loganfsmyth |
* Desugar class properties to Object.defineProperty per spec * Define uninitialized static class properties with value=undefined * Make class-properties increased spec compliance opt-in (spec: true)
Object.defineProperty
calls, following the latest proposed spec for instance fields and static fields.Oddities
In a couple of places (see commit comments), function name inference apparently kicks in on the intermediate code, e.g. turning
Object.defineProperty(..., {value: function() {}})
into... value: function value() {} ....
. This may not be desired.Future work
Object.defineProperties
calls?