refactor(es/ast)!: split bodyless functions - #12119
Conversation
🦋 Changeset detectedLatest commit: 698a192 The changes in this PR will be included in the next version bump. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Merging this PR will degrade performance by 4.36%
Warning Please fix the performance issues or acknowledge them on CodSpeed. Performance Changes
Tip Investigate this regression by commenting Comparing Footnotes
|
5931283 to
b1547b7
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b1547b7892
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "Codex (@codex) review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".
b1547b7 to
6d3788b
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6d3788b379
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "Codex (@codex) review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".
6d3788b to
b21ffad
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b21ffad28d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "Codex (@codex) review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".
b21ffad to
767005a
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 767005a504
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "Codex (@codex) review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".
cd903b6 to
9b1b646
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9b1b646f3a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "Codex (@codex) review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".
9b1b646 to
f913be6
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f913be666d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "Codex (@codex) review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".
Represent functions with bodies separately from TypeScript declarations and methods that omit bodies. Also stop legacy lexer iteration at exhausted input so zero-length EOF errors cannot repeat indefinitely. Closes #12103.
f913be6 to
698a192
Compare
|
I don't really see the benefit of this change. |
I've updated the PR description to clarify the motivation and breaking changes. The main benefit is making the implementation-body invariant structural: This keeps declaration-only nodes out of runtime transforms and removes repeated |
|
Most of the passed that works after typescript doesn't need to deal with ts nodes so it would be a brainless unwrap while those few passes needed to deal with typescript would need duplicate method for simliar ast nodes. Also even under the intention of this PR, |
Summary
This PR makes the required-body invariant explicit in the SWC ECMAScript AST.
Functionnow only represents JavaScript function declarations, expressions, and methods with an implementation body. Bodyless TypeScript and Flow declarations, overload signatures, abstract methods, and ambient methods useTsFunction, wrapped byTsFnDeclfor declarations andTsMethodfor class members.The parser selects the node kind based on whether an implementation body was parsed. Code generation, traversal, semantic analysis, transforms, bindings, and ESTree compatibility have been updated accordingly.
Motivation
A function-like declaration without a body is not a JavaScript function implementation. It is a TypeScript or Flow declaration, overload signature, abstract method, or ambient method.
Previously,
Functioncombined runtime function implementations with declaration-only signatures throughbody: Option<FunctionBody>. This allowed combinations that are not semantically meaningful and required every consumer of an implementation-bearing function to handle the bodyless case.With this change, transforms and minifiers operating on
Functioncan access its body directly without repeatedSome/Nonechecks. Declaration-only signatures are represented structurally and are less likely to enter runtime processing accidentally.The split also makes class semantics structural:
ClassMethodandPrivateMethodrepresent implementations, whileTsMethodrepresents a bodyless signature. KeepingTsFunctionnested underTsMethodpreserves the function-scope boundary between decorators or computed keys and method parameters.Additional Fix
The legacy lexer now stops iteration when the remaining input is empty instead of relying on source-map position metadata. This prevents zero-length errors at EOF, such as an unterminated string error, from being yielded indefinitely.
BREAKING CHANGE:
Function.bodychanges fromOption<FunctionBody>toFunctionBody.TsFunction,TsFnDecl, andTsMethodare introduced for bodyless TypeScript and Flow function-like syntax.Decl::TsFnorDefaultDecl::TsFn.ClassMember::TsMethod.TsDeclareFunctionandTsMethodDefinition.Related issue (if exists):