Skip to content

@babel/types builder improvements#14519

Merged
JLHwung merged 17 commits intobabel:mainfrom
JLHwung:babel-types-builder
May 9, 2022
Merged

@babel/types builder improvements#14519
JLHwung merged 17 commits intobabel:mainfrom
JLHwung:babel-types-builder

Conversation

@JLHwung
Copy link
Copy Markdown
Contributor

@JLHwung JLHwung commented May 3, 2022

Q                       A
Supersedes PR Closes #13369
Tests Added + Pass? No yet
Documentation PR Link
Any Dependency Changes?
License MIT

This PR is reviving #13369. Further improvements includes:

  • The default value of each AST node will be type checked
  • Smaller footprints

The test is currently failing. However when I run the failing test, the result diverge from the whole test, implying that it may due to 1) test correlations or 2) or engine optimizer bug. Currently

// Fails
yarn jest ./packages/babel-plugin-proposal-decorators
yarn jest ./packages/babel-plugin-proposal-decorators -t "2021 12"
yarn jest ./packages/babel-plugin-proposal-decorators -t "2021 12 runtime errors  to es2015"
// Pass
yarn jest ./packages/babel-plugin-proposal-decorators -t "2021 12 runtime errors  to es2015 > invalid class decorator return"

Update: the last test is passing because "2021 12 runtime errors to es2015 > invalid class decorator return" does not match any test title (according to jest-runner, which reports "1 skipped, 0 of 1 total"), but jest-light-runner reports "1 passed".

The test is failing because

path.scope.bindingIdentifierEquals(path.node.name, state.innerBinding)
does not guard against undefined state.innerBinding, which is the id of a ClassExpression. Surprisingly the check passes for null state.innerBinding because (undefined as Binding)?.identifier !== null. This is fixed in 055933c.

@babel-bot
Copy link
Copy Markdown
Collaborator

babel-bot commented May 3, 2022

Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/51890/

@JLHwung JLHwung force-pushed the babel-types-builder branch from 32b8d4a to e77587e Compare May 3, 2022 23:39
@JLHwung JLHwung marked this pull request as ready for review May 4, 2022 12:14
}

function defaultExpression(field) {
return Array.isArray(field.default) ? "[]" : JSON.stringify(field.default);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why do we need to special-case arrays?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That was the behaviour of builder.js:

arg = Array.isArray(field.default) ? [] : field.default;

I will check if we have weird field.default.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we had that check to avoid sharing the same [] reference every time, but since it's now a new [] value for every call it's always a different one.

Comment on lines +10 to +15
const node: t.ArrayExpression = {
type: "ArrayExpression",
elements,
};
validateNode(node);
return node;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

To generate slightly smaller code, we could modify validateNode like this:

function validateNode<N extends t.Node>(node: N): N {
  // todo: because keys not in BUILDER_KEYS are not validated - this actually allows invalid nodes in some cases
  const keys = BUILDER_KEYS[node.type];
  for (const key of keys) {
    validate(node, key, node[key]);
  }
  return node;
}

and then do

export function arrayExpression(
     elements: Array<null | t.Expression | t.SpreadElement> = [],
) {
  return validateNode<t.ArrayExpression>({
    type: "ArrayExpression",
    elements,
  });
}

@nicolo-ribaudo nicolo-ribaudo added the PR: Internal 🏠 A type of pull request used for our changelog categories label May 6, 2022
@JLHwung JLHwung force-pushed the babel-types-builder branch from 4b252b5 to 2600b5a Compare May 9, 2022 14:08
}function ${formatedBuilderNameLocal}(${defArgs.join(
", "
)}): t.${type} { return builder.apply("${type}", arguments); }\n`;
}function ${formatedBuilderNameLocal}(${defArgs.join(", ")}): t.${type} {`;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The return type annotation is preserved because we skip validateNode for nodes with empty builder keys.

}function ${formatedBuilderNameLocal}(${defArgs.join(", ")}): t.${type} {`;

const nodeObjectExpression = `{\n${objectFields
.map(([k, v]) => (k === v ? ` ${k},` : ` ${k}: ${v},`))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: since these just come from local param names, can't we make it always match?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Most of the argument name match the AST field name. The exceptions are non-valid binding identifier names, such as CallExpression's arguments and ClassMethod's static.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ahhh

@JLHwung JLHwung merged commit c6e68c7 into babel:main May 9, 2022
@JLHwung JLHwung deleted the babel-types-builder branch May 9, 2022 18:20
@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 Aug 9, 2022
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 9, 2022
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 PR: Internal 🏠 A type of pull request used for our changelog categories

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants