-
-
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
add class.hasInstance proposal (Stage 1) support #13959
Conversation
Can you open an PR to ESTree on the AST shape of Since it is an early draft, we will not review until you mark it as ready. Take your time and happy hacking. If you have any questions, please reach out at Slack. |
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.
Left some comments on the parsing part. Will do another review on the transformer later.
Update: we should also take a look at the statement parsing:
case tt._class: |
class.hasInstance(foo)
as an ExpressionStatement should be valid.
@@ -359,3 +359,9 @@ export function ModuleExpression(node: t.ModuleExpression) { | |||
this.rightBrace(); | |||
} | |||
} | |||
|
|||
export function ClassHasInstanceExpression(node: t.ClassHasInstanceExpression) { |
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 should ensure @babel/generator
prints the code according to the AST:
export function ClassHasInstanceExpression(node: t.ClassHasInstanceExpression) { | |
export function ClassHasInstanceExpression(node: t.ClassHasInstanceExpression) { | |
this.word("class"); | |
this.token("."); | |
this.word("hasInstance"); | |
this.printInnerComments(node); |
Please also add a test case to babel-generator/test/fixtures/class-brand-check
:
class Range {
equals(obj) {
class.hasInstance(obj)
class/* 1 */./* 2 */hasInstance/* 3 */(obj)
}
}
We already have an AST node for meta properties: babel/packages/babel-parser/src/types.js Lines 887 to 891 in efe0188
We should keep using it instead of creating a new one. You can take inspiration from where we call the |
The current AST spec follows ESTree proposal in estree/estree#260. The The ClassHasInstanceExpression approach is more abstract than the MetaProperty approach. So the advantages of each of them follows the ones of AST v.s. CST. Pros of ClassHasInstanceExpression:
Pros of MetaProperty:
If we are going with the MetaProperty approach, the pros of ClassHasInstanceExpression can be obtained from extra |
ensure @babel/generator prints the code according to the AST: Co-authored-by: Huáng Jùnliàng <jlhwung@gmail.com>
…eat/classhasintance
@@ -229,8 +229,10 @@ export default (superClass: Class<Parser>): Class<Parser> => | |||
): T { | |||
const type = isStatement ? "ClassDeclaration" : "ClassExpression"; | |||
|
|||
this.next(); | |||
this.takeDecorators(node); | |||
if (this.eat(tt._class)) { |
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.
With this change we will incorrectly allow
class class A {}
because class
is eaten twice.
I suggest we remove this.takeDecorators
in parseClassOrClassHasInstanceExpression
and remove this.next()
above.
@@ -0,0 +1,975 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP |
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.
The snapshot should be removed.
|
||
/* 2 */ | ||
|
||
/* 3 */ |
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.
The output here is incorrect. It seems to me the comments are registered as innerComments
of the BodyStatement, it should be attached as the innerComments
of ClassHasInstanceExpression
/ MetaProperty
.
@@ -132,6 +132,7 @@ export default (_: typeof toParseErrorCredentials) => ({ | |||
IncompatibleRegExpUVFlags: _( | |||
"The 'u' and 'v' regular expression flags cannot be enabled at the same time.", | |||
), | |||
InvalidArguments: _("Invalid Arguments."), |
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.
The error message is a bit vague. We can provide more informative errors like we did for setters:
babel/packages/babel-parser/src/parse-error/standard-errors.js
Lines 48 to 51 in 2c7e9f7
BadSetterArity: _("A 'set' accesor must have exactly one formal parameter."), | |
BadSetterRestParameter: _( | |
"A 'set' accesor function argument must not be a rest parameter.", | |
), |
Co-authored-by: Huáng Jùnliàng <jlhwung@gmail.com>
Co-authored-by: Huáng Jùnliàng <jlhwung@gmail.com>
Co-authored-by: Huáng Jùnliàng <jlhwung@gmail.com>
…eat/classhasintance
Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/51691/ |
According to https://github.com/tc39/notes/blob/HEAD/meetings/2021-01/jan-27.md#class-brand-checks and tc39/proposal-class-brand-check#15, it's likely that the syntax will change because:
Given those likely changes, I think it would be better to wait for the proposal champion to present the updated proposal version to TC39 before merging this PR. |
This is valuable advice. I will discuss the plugin's plans with the authors of the proposal. |
Thank you for your PR! Since this proposal is still in phase 1 and no longer seems to be active, I will close this PR. |
Add TC39 proposal: proposal-class-brand-check
usage:
after transform :