-
-
Notifications
You must be signed in to change notification settings - Fork 258
Conversation
Parse stage 0 decorators when "decorators" plugin is active and parse stage 2 decorators when "decorators-stage-2" plugin is active
And add tests to reflect the same
For stage 2 decorators
Add tests for static properties and private properties
Codecov Report
@@ Coverage Diff @@
## master #587 +/- ##
========================================
- Coverage 98.15% 98% -0.15%
========================================
Files 22 22
Lines 3680 3712 +32
Branches 1026 1036 +10
========================================
+ Hits 3612 3638 +26
- Misses 25 27 +2
- Partials 43 47 +4
Continue to review full report at Codecov.
|
I don't like the |
That's a valid point. We could also name it |
@nicolo-ribaudo depends on if stage 3 means more changes. Either way we would need to fork the logic again with a new plugin/name |
@vjeux brought up a good point about whether the start position of the class/function part of the decorator should change? https://twitter.com/Vjeux/status/876213458622005249 |
@hzoo Though in case stage 3 brings mostly non-breaking changes, we could easily make additions to this new decorators plugin instead of forking logic into a new one. So we should definitely choose a plugin name that's not tied to stage 2 |
Would a test to assert the output of the following make sense? export default @thing
class Stuff { } |
@basicdays yep, I think this is the preferred way to do it since decorators and class tail together make up the class, and then you can export that like you export an undecorated class I will add a test for this |
src/index.js
Outdated
@@ -62,6 +62,10 @@ function getParserClass(pluginsFromOptions: $ReadOnlyArray<string>): Class<Parse | |||
pluginList.unshift("estree"); | |||
} | |||
|
|||
if (pluginList.indexOf("decorators") >= 0 && pluginList.indexOf("decoratorsStage2") >= 0) { |
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.
Don't have to do this now, but we should figure out a better solution to this in the future (regarding multiple versions of the same kind plugin). Same kind of error as TS + Flow
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.
Huge fan of the design decisions in this patch, to follow the current draft spec, no more no less, and to make a separate flag. To bikeshed about the name, how about "standardDecorators"?
What's your long-term vision for this mode? Ultimately, it would be great if, in Babel 7.0 (or 8.0), this new syntax (and a new matching transform) would be the only decorators implementation, or at least the only one selected by the staged presets, but maybe this is too big of a breaking change.
@@ -0,0 +1,6 @@ | |||
class Foo { | |||
@bar[bizz] |
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.
This is a great test; you could also add tests for cases like @(bar.baz)
and @foo().bar
, which one might expect to work. The grammar is extremely restrictive here, and you seem to implement the restrictions well (so well that I had to go back to the spec and ask, is it really that restrictive? yes).
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.
👍
@vjeux trying to find the reason for this in the proposals document. Is it because the productions look like
So we'd consider ClassDeclaration to start at the begining of the first decorator? (And similarly for class expression and methods) ?? |
All the other parent nodes include the location of the children node except for decorators. We use this property in prettier to attach comments by going down the ast looking at ranges, but it breaks for decorators. If you could fix it that would remove one hack we have to do. |
Yeah the reason is just that you'd have to backtrack to know the start of the "decorated node" |
@hzoo I've found an easy way to do it though using |
Cool didn't know about that one 😄 |
Latest changes in last 3 commits:
These two edits have caused a lot of minor changes to a lot of files so it might be a pain to review. The only logic changes to source folder is by this commit in the file I also can't figure out how to increase coverage, the uncovered lines aren't making any sense to me (they existed in codebase before this PR). So if that's not a problem then I think we're good to merge (perhaps after latest changes relating to start location have been reviewed?) |
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.
👍
@@ -47,6 +47,11 @@ const parserClassCache: { [key: string]: Class<Parser> } = {}; | |||
|
|||
/** Get a Parser class with plugins applied. */ | |||
function getParserClass(pluginsFromOptions: $ReadOnlyArray<string>): Class<Parser> { | |||
|
|||
if (pluginsFromOptions.indexOf("decorators") >= 0 && pluginsFromOptions.indexOf("decorators2") >= 0) { |
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'd say to use Array.prototype.includes
instead...... but that doesn't work on Node 4 😢
@@ -0,0 +1,4 @@ | |||
{ | |||
"plugins": ["decorators2", "classProperties"], | |||
"throws": "Stage 2 decorators may only be used with a class or a class method (2:2)" |
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.
Should this error message mention no computed instead?
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 will have to explain this in documentation or some other way.
the problem is that with classProperties enabled and due to the fact that the computed property isn't considered a part of the decorator, we can't really tell if the code is trying to access decorator's member or trying to decorate a computed class property.
So in this example it thinks that [bizz]
is a class property.
If you disable class properties altogether you will get a syntax error at abc since it is expecting opening bracket right after the method name [bizz]
@@ -0,0 +1,4 @@ | |||
{ | |||
"sourceType": "module", | |||
"throws": "Leading decorators must be attached to a class declaration (2:0)" |
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.
is it useful to say: instead of the export
? or to explain it via example?
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.
good idea
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.
Looks awesome! An amazing first PR @peey, having to check the spec, and getting all these reviews!
I think maybe we can work on the error messages still if that's not difficult to change?
Followup PR #590 |
decoratorsStage2
plugin which can be used instead ofdecorators
plugin but both cannot be used together3.1. Computed key on decorator e.g.
@dec[foo]
3.2. Parameter decorators
3.3. Object methods
3.4.
export
keyword in between of class body and decorators4.1 Decoration of computed class method names (Decorators on computed class method names #33)
4.2 Decoration of generator functions (Unable to decorate generator functions #13)
In some places, I've chosen to throw custom errors like "Stage 2 decorators do not allow parameter decoration" instead of throwing unexpected token so as to help people migrate and to make these changes explicit and less confusing.
Rationale for PR
The disallowed features are much loved but unfortunately either aren't a part of the proposal yet or have been discarded, therefore there is no clear answer on how to transform them.
This PR and associated plugin for stage-2 decorators is going to be opt-in for those who want to start writing what's currently stage-2 approved in the decorators proposal.
Ping @bakkot - #353; @DrewML - #236