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

add class features #222

Merged
merged 10 commits into from Jul 7, 2020
Merged

add class features #222

merged 10 commits into from Jul 7, 2020

Conversation

JLHwung
Copy link
Contributor

@JLHwung JLHwung commented May 28, 2020

View Rendered Text

This PR adds support to three stage-3 class features proposals. It shows Babel's current approach except for the following node type naming differences:

Babel This PR
ClassProperty PropertyDefinition
ClassPrivateProperty PrivatePropertyDefinition
ClassPrivateMethod PrivateMethodDefinition

It is named in the *Definition pattern, aligning to the MethodDefinition defined in es2015.

This PR also offers an alternative design of #180. In #180 PrivateMemberExpression has been introduced for MemberExpression[property=PrivateName] in this PR, which will have impact on #204 given that this?.#priv is now supported.

As the class proposals have been out there for quite some time and they are widely adopted in React/TypeScript communities, especially the class fields proposal, I will expect some tools are depending on Babel class features AST. Building consensus based on this approach can minimize the friction supporting new ESTree releases.

Fixes #154
Closes #180

--- Edits ---
Updated according to review comments. PTAL.

Copy link
Contributor

@nzakas nzakas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems reasonable at this phase.

@mysticatea
Copy link
Contributor

I wonder if the Private* prefix is needed or not. I love consistency.

  • MemberExpression handles both public and private.
  • There are four kinds of namespaces: public keys, static public keys, private keys, and static private keys. MethodDefinition doesn't have Static* prefix for static keys. (also I'm afraid of the combination explosion of such prefixes.)


A private name refers to private class elements. For a private name `#a`, its `id.name` is `a`.

When the property of a member expression is a private name, its `computed` is always `false`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems pretty bad. Why not just have a PrivateMemberExpression? The reason to unify them would be that we expect people to consider them similar for some purpose. I don't expect too much of that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some reasons that I can tell

  • Babel has OptionalMemberExpression which corresponds to OptionalChain
  • PrivateOptionalMemberExpression for obj?.#x can be confusing
  • There is no PrivateMemberExpression like production in the spec

@JLHwung JLHwung requested a review from nzakas June 5, 2020 03:15
@bradzacher
Copy link

I understand the want to align with MethodDefinition, but I question if it's a good idea to rename ClassProperty to PropertyDefinition. The ClassProperty name has existed for quite a long time, and as such it has been used for a long time. It is very, very prolific throughout the ecosystem.

Unlike the optional chaining changes, which apply to a feature that has only recently been implemented in most of the ecosystem, renaming class properties will be a pretty significant breaking change and will likely be a pretty painful change for users to navigate.

value: Expression;
computed: boolean;
static: boolean;
private: boolean;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love consistency. If we add private:boolean to (Method|Property)Definition, I'd like to add it to MemberExpression as well. Or remove it from both.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's best to remove from both; otherwise we're duplicating same information which explicitly goes against one of the design goeals ("Unique") in the Philosophy.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree on @RReverser that we don't need .private if we can check .key.type === "PrivateIdentifier". While I admit that .private is handier, the ergonomic trade-off here is still acceptable.

Should another private-like key (PrivateComputedExpression?) be supported in the future, we can introduce .private at that time.

@JLHwung
Copy link
Contributor Author

JLHwung commented Jun 5, 2020

@bradzacher The ClassProperty is used in Babel AST. Given that PropertyDefinition now deviates a lot from Babel AST design. I would rather stay on the current names instead of silently breaking tools. (i.e. private: boolean is added)

JLHwung and others added 2 commits June 5, 2020 15:02
Co-authored-by: Ingvar Stepanyan <me@rreverser.com>
@bradzacher

This comment has been minimized.

@JLHwung
Copy link
Contributor Author

JLHwung commented Jun 17, 2020

@RReverser friendly ping, does the current AST design look good to you?

@RReverser
Copy link
Member

Oh yeah, sorry, I haven't noticed that private: boolean has been removed since my last review; LGTM, especially for experimental :)

@bradzacher
Copy link

Given that PropertyDefinition now deviates a lot from Babel AST design

Sorry, could you clarify how? I don't see how this deviates from the babel AST (or the AST emitted from babel-eslint).

It looks like the current ClassProperty spec introduced by babel and used in the ESLint ecosystem for many years matches your proposed spec exactly (with the only variance being the private property piece)

AST explorer example:
https://astexplorer.net/#/gist/592095bc625a5243ab44009fd1d62863/15d212b3d4439339de5fd36cb0b057d293d0d003

TS-ESTree spec (which was built to match the babel implementation):
https://github.com/typescript-eslint/typescript-eslint/blob/4c9293bd5ecfb475bfd4f2240fb6e55186ff3e55/packages/typescript-estree/src/ts-estree/ts-estree.ts#L583-L606

The ClassProperty name has been around and in use for many, many years, so this will cause a lot of pain for tool owners and users to migrate to.

If that's what the direction going forward is - that's fine. I just want to ensure it's a conscious decision to introduce the breakage.

@JLHwung
Copy link
Contributor Author

JLHwung commented Jun 18, 2020

The differences between current approach and Babel's approach can be viewed here

Notable changes are:

  • ClassPrivateProperty and ClassProperty is merged, likewise ClassPrivateMethod
  • Naming differences
  • PrivateName has been replaced by PrivateIdentifier

On the AST policy of babel and estree, we haven't stated formally on our website but I believe what @nicolo-ribaudo proposed here is close to the team consensus, that estree does not include experimental features and Babel's proposal AST design should be considered experimental, too. That said, we as Babel team don't intend to bring more fragments to the ECMAScript AST, that's why we have proposed an update of our process to work with estree since stage-1.

Babel introduced ClassPrivateProperty in babel/babylon#260 and back that time there have been discussions about naming conventions. The decision at that time was to merge ClassPrivateProperty and ClassProperty when the class proposals reached stage-3. Now that they are stage-3 and we may consider merging ClassPrivateProperty and ClassProperty.

The ClassProperty name has been around and in use for many, many years, so this will cause a lot of pain for tool owners and users to migrate to.

Yeah I understand the frictions here, but keep in mind that class proposals are still stage-3, which means they are still experimental, and by nature, open to breaking changes. It's a short time window that we still have opportunities to value long term AST consistency/teachability over short term community frictions.

@JLHwung
Copy link
Contributor Author

JLHwung commented Jul 3, 2020

@nzakas I think we have reached consensus and it can merged as-is.

@nzakas
Copy link
Contributor

nzakas commented Jul 7, 2020

Sounds good!

@nzakas nzakas merged commit 2218fde into estree:master Jul 7, 2020
@piranna
Copy link

piranna commented Jul 7, 2020

In what Babel version will this be available?

@JLHwung JLHwung deleted the add-class-features branch July 7, 2020 20:44
@JLHwung
Copy link
Contributor Author

JLHwung commented Jul 7, 2020

@piranna Babel has different AST shape with ESTree: https://github.com/babel/babel/blob/main/packages/babel-parser/ast/spec.md#classproperty

All stage-3 class features are supported on Babel 7.10.

@piranna
Copy link

piranna commented Jul 8, 2020

@piranna Babel has different AST shape with ESTree: babel/babel:packages/babel-parser/ast/spec.md@main#classproperty

All stage-3 class features are supported on Babel 7.10.

Sorry, I wanted to say eslint.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Private Class Field representation
7 participants