Skip to content

Conversation

@jridgewell
Copy link
Member

@jridgewell jridgewell commented Jul 19, 2017

Q A
Patch: Bug Fix? No
Major: Breaking Change? Yes
Minor: New Feature? No
Deprecations? Bad node types
Spec Compliancy? Yes?
Tests Added/Pass? No
Fixed Tickets Fixes #4059
License MIT
Doc PR
Dependency Changes

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?).

@mention-bot
Copy link

@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.

@existentialism existentialism added pkg: types PR: Breaking Change 💥 A type of pull request used for our changelog categories for next major release labels Jul 19, 2017
@existentialism existentialism added this to the Babel 7 milestone Jul 25, 2017
@hzoo hzoo mentioned this pull request Aug 1, 2017
);
traverse(this.ast, visitor, this.scope);

t.validateDeep(this.ast);
Copy link
Member

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)?

Copy link
Member Author

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;

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?

Copy link
Member Author

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;
Copy link
Member

@danez danez Aug 4, 2017

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?

Copy link
Member Author

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?
Copy link
Member

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"),
Copy link
Member

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, 3

Copy link
Member

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"],
Copy link
Member

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?

Copy link
Member Author

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
@jridgewell jridgewell force-pushed the cleanup-babel-types branch from 08d5aed to 361a64d Compare August 16, 2017 04:23
Copy link
Member Author

@jridgewell jridgewell left a 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;
Copy link
Member Author

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;
Copy link
Member Author

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"],
Copy link
Member Author

Choose a reason for hiding this comment

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

Builder. 😬

Copy link
Member Author

@jridgewell jridgewell left a 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);
Copy link
Member Author

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'

Copy link
Member

@nicolo-ribaudo nicolo-ribaudo left a 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#alternate and others are defined as Statement, but they should disallow declarations (except for plain functions). What is the reason for declarations to have a Statement alias?
  • Can AssignmentPatterns and ArrayPatterns have decorators?

flags: {
validate: assertValueType("string"),
default: "",
},
Copy link
Member

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"),
Copy link
Member

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",
Copy link
Member

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")),
Copy link
Member

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)}`,
Copy link
Member

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;
Copy link
Member

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");
Copy link
Member

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?

@danez danez closed this Aug 31, 2017
@danez danez reopened this Aug 31, 2017
@danez danez changed the base branch from 7.0 to master August 31, 2017 17:02
@hzoo hzoo added this to the Babel 7.next milestone Sep 13, 2017
@hzoo hzoo removed this from the Babel 7 Beta milestone Sep 13, 2017
@nicolo-ribaudo nicolo-ribaudo mentioned this pull request Dec 2, 2019
11 tasks
@github-actions github-actions bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Apr 12, 2020
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 12, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

outdated A closed issue/PR that is archived due to age. Recommended to make a new issue pkg: types PR: Breaking Change 💥 A type of pull request used for our changelog categories for next major release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AST seems to allow MemberExpression in function parameter list (T7068)

7 participants