Skip to content

fix(es/typescript): Handle TypeScript expressions in enum transformation#11769

Open
magic-akari wants to merge 15 commits intoswc-project:mainfrom
magic-akari:fix/issue-11761
Open

fix(es/typescript): Handle TypeScript expressions in enum transformation#11769
magic-akari wants to merge 15 commits intoswc-project:mainfrom
magic-akari:fix/issue-11761

Conversation

@magic-akari
Copy link
Copy Markdown
Member

Description:

BREAKING CHANGE:

Related issue (if exists):

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 6, 2026

⚠️ No Changeset found

Latest commit: 1062344

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 6, 2026

Binary Sizes

File Size
swc.linux-x64-gnu.node 28M (29100488 bytes)

Commit: 2093266

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Apr 6, 2026

Merging this PR will not alter performance

✅ 219 untouched benchmarks


Comparing magic-akari:fix/issue-11761 (00d0558) with main (236eff0)1

Open in CodSpeed

Footnotes

  1. No successful run was found on main (fff1426) during the generation of this report, so 236eff0 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@magic-akari magic-akari marked this pull request as ready for review April 6, 2026 14:08
@magic-akari magic-akari requested a review from a team as a code owner April 6, 2026 14:08
Copilot AI review requested due to automatic review settings April 6, 2026 14:08
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c9ea557187

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes a crash when transforming TypeScript enums whose member initializers include TS-only expression wrappers (e.g. as any), by unwrapping/stripping those wrappers during enum value computation and enum emission.

Changes:

  • Unwrap TS expression wrappers (as, non-null, type assertions, satisfies, etc.) when computing enum member values.
  • Visit/transform opaque enum initializer expressions during enum emission so TS-only syntax is stripped before codegen.
  • Add regression tests for TS-wrapped and complex enum initializers; update existing fixture outputs to match new behavior.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
crates/swc_ecma_transforms_typescript/src/ts_enum.rs Unwraps TS expression wrappers when computing enum member values.
crates/swc_ecma_transforms_typescript/src/transform.rs Visits opaque enum initializer expressions and tracks opacity during enum emission.
crates/swc_ecma_transforms_typescript/tests/strip.rs Adds new enum-related regression tests.
crates/swc_ecma_transforms_typescript/tests/swc_snapshots/tests/strip.rs/* Adds snapshots for new regression tests.
crates/swc_ecma_transforms_typescript/tests/fixture/issue-3001/*/output.js Updates expected fixture output due to new enum-expression processing/inlining.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@magic-akari magic-akari marked this pull request as draft April 6, 2026 14:23
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@magic-akari magic-akari marked this pull request as ready for review April 6, 2026 16:57
Copilot AI review requested due to automatic review settings April 6, 2026 16:57
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 64335328f7

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@magic-akari magic-akari marked this pull request as draft April 6, 2026 17:30
Comment on lines +1261 to +1274
// Intentionally do not predeclare enum members in the resolver.
// Enum initializers may reference other members, including quoted names whose
// text is a valid identifier:
//
// ```TypeScript
// enum E {
// A = "A",
// "B" = "B",
// C = (() => { console.log(A, B); })(),
// }
// ```
//
// We keep those references unresolved here so the TypeScript enum transform
// can rewrite them using semantic.enum_record.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Another approach would be to mark all of them with contexts, like this:

enum E#2 {
    A#4 = "A",
    "B"#4 = "B",
    C = (() => { console#1.log(A#4, B#4); })(),
}

This way, during the subsequent enum transformation process, we could directly compare IDs to perform correct replacements.

However, SWC's current design doesn't allocate contexts for string enum members, so this approach doesn't work. We have to settle for the alternative: not marking any of them.

@magic-akari magic-akari marked this pull request as ready for review April 7, 2026 12:28
Copilot AI review requested due to automatic review settings April 7, 2026 12:28
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fd53909b1e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@magic-akari magic-akari marked this pull request as draft April 7, 2026 12:44
//
// We keep those references unresolved here so the TypeScript enum transform
// can rewrite them using semantic.enum_record.
child.current.mark = self.config.unresolved_mark;
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Please review this part carefully.
I am unsure if this implementation represents the correct direction for the fix.
@swc-project/core

@magic-akari magic-akari marked this pull request as ready for review April 7, 2026 14:28
Copilot AI review requested due to automatic review settings April 7, 2026 14:28
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 22 out of 22 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 930359506d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@magic-akari magic-akari marked this pull request as draft April 7, 2026 15:36
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3d75291b7c

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@kdy1 kdy1 added this to the Planned milestone Apr 7, 2026
@magic-akari magic-akari marked this pull request as ready for review April 7, 2026 18:05
Copilot AI review requested due to automatic review settings April 7, 2026 18:05
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 00d05585e9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +1086 to +1087
let TsEnumRecordValue::Opaque(mut e) = enum_computer.compute(e) else {
unreachable!();
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Avoid panicking when recomputed enum value becomes const

This unreachable!() can be hit for validly parsed enums where the semantic pass stored an initializer as Opaque, but the second pass recomputes it as a constant using the full enum record. For example, enum E { A = B, B = 1 } records A as opaque during semantic analysis (because B is not known yet), then enum_computer.compute returns Number(1) here, so the destructuring fails and the transform panics instead of emitting code. The same crash pattern applies to forward references across merged enum declarations.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 22 out of 22 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1055 to +1067
let member_names = self
.semantic
.enum_record
.keys()
.filter(|k| k.enum_id == id.to_id())
.map(|k| k.member_name.clone())
.collect();

let enum_computer = EnumValueComputer {
enum_id: &id.to_id(),
unresolved_ctxt: self.unresolved_ctxt,
record: &self.semantic.enum_record,
};
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

EnumValueComputer { enum_id: &id.to_id(), .. } takes a reference to a temporary Id produced by to_id(). This will not live long enough and is expected to fail to compile (temporary dropped while borrowed). Bind let enum_id = id.to_id(); once and pass enum_id: &enum_id (and reuse enum_id in the nearby .filter(|k| k.enum_id == ...) / TsEnumRecordKey construction to avoid repeated to_id() calls).

Copilot uses AI. Check for mistakes.
Comment on lines +1088 to +1095
};
e.visit_mut_with(&mut RefRewriter {
query: EnumMemberRefQuery {
enum_id: &id.to_id(),
member_names: &member_names,
unresolved_ctxt: self.unresolved_ctxt,
},
});
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

EnumMemberRefQuery { enum_id: &id.to_id(), .. } also borrows a temporary Id. After introducing a local enum_id: Id (e.g. let enum_id = id.to_id();), pass enum_id: &enum_id here as well to avoid borrowing a temporary and to ensure the reference outlives the rewriter.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Typescript enum value with as syntax cause swc crash

3 participants