-
-
Notifications
You must be signed in to change notification settings - Fork 5.8k
Cleanup babel types #5971
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
Cleanup babel types #5971
Conversation
|
@jridgewell, thanks for your PR! By analyzing the history of the files in this pull request, we identified @ForbesLindesay, @existentialism and @xtuc to be potential reviewers. |
| ); | ||
| traverse(this.ast, visitor, this.scope); | ||
|
|
||
| t.validateDeep(this.ast); |
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.
curious how much slower it gets when doing this (I guess it's 1 one time check)?
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 could only do this when NODE_ENV === 'test'
| var f1 = implements => implements; | ||
| var f2 = implements => { return implements; }; | ||
| var f3 = (implements) => { return implements; }; | ||
| var f1 = i => i; |
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.
These changes seem incorrect. Isn't the whole point of this test file to check sloppy arguments in arrow functions?
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 like it, but it's impossible to tell where these identifiers were defined. The only other alternative it to forbid Identifiers inside VariableDeclarators from having these.
|
|
||
| this.debug(() => `Replace with ${node && node.type}`); | ||
|
|
||
| this.node = this.container[this.key] = node; |
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.
Shouldn't we first validate and then replace? Or what is the idea of this change?
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 node should already be valid, so we just need to check parent-child validations after the replacement.
| name: { | ||
| validate: assertNodeType("JSXIdentifier", "JSXMemberExpression"), | ||
| }, | ||
| // WTF is this on the OpeningElement and not the Element? |
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.
Seems so, as it is like that in every parser.
| fields: { | ||
| argument: { | ||
| validate: assertNodeType("LVal"), | ||
| validate: assertNodeType("Identifier"), |
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.
It can also be a member expression, if the destructuring is not part of a parameter/declaration:
var a = {};
[...a.b] = [1, 2, 3];
a.b; // 1, 2, 3There 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 also a pattern, if the rest element is not inside an object destructuring.
|
|
||
| defineType("ForOfStatement", { | ||
| visitor: ["left", "right", "body"], | ||
| visitor: ["left", "right", "body", "await"], |
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 await be in visitor or in builder?
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.
Builder. 😬
tmp Lock down type system Update tests Add implicit fields to nodes Add missing fields RestElements must be last element Do not mutate an inherited fields map Remove ObjectPatternProperty Fix a few types Deeply validate before printing Update docs
08d5aed to
361a64d
Compare
jridgewell
left a comment
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.
First pass after the typescript changes. I'll finish tomorrow.
| var f1 = implements => implements; | ||
| var f2 = implements => { return implements; }; | ||
| var f3 = (implements) => { return implements; }; | ||
| var f1 = i => i; |
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 like it, but it's impossible to tell where these identifiers were defined. The only other alternative it to forbid Identifiers inside VariableDeclarators from having these.
|
|
||
| this.debug(() => `Replace with ${node && node.type}`); | ||
|
|
||
| this.node = this.container[this.key] = node; |
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 node should already be valid, so we just need to check parent-child validations after the replacement.
|
|
||
| defineType("ForOfStatement", { | ||
| visitor: ["left", "right", "body"], | ||
| visitor: ["left", "right", "body", "await"], |
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.
Builder. 😬
jridgewell
left a comment
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.
Alright, this should be good for a final review.
| ); | ||
| traverse(this.ast, visitor, this.scope); | ||
|
|
||
| t.validateDeep(this.ast); |
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 could only do this when NODE_ENV === 'test'
nicolo-ribaudo
left a comment
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 also have few comments/questions not related to your changes:
-
LabeledStatement#body,IfStatement#consequent,IfStatement#alternateand others are defined asStatement, but they should disallow declarations (except for plain functions). What is the reason for declarations to have aStatementalias? - Can
AssignmentPatterns andArrayPatterns have decorators?
| flags: { | ||
| validate: assertValueType("string"), | ||
| default: "", | ||
| }, |
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.
Maybe we should check that there are only valid flags?
| ...patternLikeCommon, | ||
| argument: { | ||
| validate: assertNodeType("LVal"), | ||
| validate: assertNodeType("Identifier", "MemberExpression"), |
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 can also be a Pattern:
function a(...[x]) {}| validate: chain(assertNodeType("BlockStatement"), function(node) { | ||
| if (!node.handler && !node.finalizer) { | ||
| throw new TypeError( | ||
| "TryStatement expects either a handler or finalizer, or both", |
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.
Now you can remove
| // todo: at least handler or finalizer should be set to be valid |
| validate: chain( | ||
| assertValueType("array"), | ||
| assertEach(assertNodeType("LVal")), | ||
| assertEach(assertNodeType("Identifier", "Pattern", "RestElement")), |
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 use assertNodeType("PatternLike")
| throw new TypeError( | ||
| `Property ${key} of ${node.type} expected node to be of a type ${JSON.stringify( | ||
| types, | ||
| )} ` + `but instead got ${JSON.stringify(val && val.type)}`, |
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.
Nit: here it isn't needed to use two concatenated templates. (Also line 81)
| return false; | ||
| } else { | ||
| return esutils.keyword.isIdentifierNameES6(name); | ||
| if (reserved && name === "await") return false; |
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.
reserved && is not needed, since this is inside if (reserved) {
| " (default: `" + util.inspect(defaultValue) + "`" | ||
| ); | ||
| if (types.BUILDER_KEYS[key].indexOf(field) < 0) { | ||
| fieldDescription.push(", non-buildable"); |
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.
Maybe something like excluded from the factory function would be more clear?
This provides a much stricter node system. It also does a deep validation of the AST before printing (should we only do this in testing?).