Skip to content

test(transformer): add test for string enum alias member#20652

Merged
graphite-app[bot] merged 1 commit intomainfrom
test/enum-string-alias-member
Apr 13, 2026
Merged

test(transformer): add test for string enum alias member#20652
graphite-app[bot] merged 1 commit intomainfrom
test/enum-string-alias-member

Conversation

@Dunqing
Copy link
Copy Markdown
Member

@Dunqing Dunqing commented Mar 23, 2026

Summary

Test plan

  • cargo run -p oxc_transform_conformance -- --filter enum-string-alias-member passes

🤖 Generated with Claude Code

@github-actions github-actions Bot added A-transformer Area - Transformer / Transpiler C-test Category - Testing. Code is missing test cases, or a PR is adding them labels Mar 23, 2026
Copy link
Copy Markdown
Member Author

Dunqing commented Mar 23, 2026


How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • 0-merge - adds this PR to the back of the merge queue
  • hotfix - for urgent changes, fast-track this PR to the front of the merge queue

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@Dunqing Dunqing marked this pull request as ready for review March 23, 2026 13:13
@Dunqing Dunqing force-pushed the test/enum-string-alias-member branch from 9b82f47 to 687f71b Compare April 2, 2026 14:27
@github-actions github-actions Bot added A-linter Area - Linter A-parser Area - Parser A-semantic Area - Semantic A-cli Area - CLI A-minifier Area - Minifier A-ast Area - AST A-codegen Area - Code Generation A-cfg Area - Control Flow Graph A-isolated-declarations Isolated Declarations A-ast-tools Area - AST tools A-editor Area - Editor and Language Server A-formatter Area - Formatter A-linter-plugins Area - Linter JS plugins labels Apr 2, 2026
@Dunqing Dunqing force-pushed the feat/optimize-enums-option branch from 2ed8fb8 to 3874d8f Compare April 3, 2026 01:00
@Dunqing Dunqing force-pushed the test/enum-string-alias-member branch from 687f71b to 0bf9397 Compare April 3, 2026 01:00
@Dunqing Dunqing removed A-linter Area - Linter A-parser Area - Parser A-semantic Area - Semantic labels Apr 3, 2026
@Dunqing Dunqing removed A-formatter Area - Formatter A-linter-plugins Area - Linter JS plugins labels Apr 3, 2026
@Sysix Sysix removed their request for review April 3, 2026 10:30
@Dunqing Dunqing force-pushed the test/enum-string-alias-member branch from 0bf9397 to b491ac1 Compare April 7, 2026 06:57
@Dunqing Dunqing changed the base branch from feat/optimize-enums-option to graphite-base/20652 April 7, 2026 06:57
@github-actions github-actions Bot added the A-semantic Area - Semantic label Apr 7, 2026
@Dunqing Dunqing force-pushed the test/enum-string-alias-member branch from b491ac1 to 140947b Compare April 7, 2026 07:54
@Dunqing Dunqing force-pushed the graphite-base/20652 branch from 3874d8f to 54abab1 Compare April 7, 2026 07:54
@Dunqing Dunqing added the 0-merge Merge with Graphite Merge Queue label Apr 7, 2026
Copy link
Copy Markdown
Member Author

Dunqing commented Apr 7, 2026

Merge activity

@Dunqing Dunqing force-pushed the test/enum-string-alias-member branch from 140947b to d016ae2 Compare April 13, 2026 03:24
@Dunqing Dunqing force-pushed the graphite-base/20652 branch from 54abab1 to 420f2bf Compare April 13, 2026 03:24
@Dunqing Dunqing changed the base branch from graphite-base/20652 to feat/optimize-enums-option April 13, 2026 03:25
@graphite-app graphite-app Bot force-pushed the feat/optimize-enums-option branch 2 times, most recently from 98c89b5 to ff89f68 Compare April 13, 2026 03:34
@graphite-app graphite-app Bot force-pushed the test/enum-string-alias-member branch from d016ae2 to b87d3be Compare April 13, 2026 03:34
@Dunqing Dunqing force-pushed the test/enum-string-alias-member branch from b87d3be to d575d86 Compare April 13, 2026 07:22
@Dunqing Dunqing force-pushed the feat/optimize-enums-option branch from ff89f68 to 07d6574 Compare April 13, 2026 07:22
@Dunqing Dunqing force-pushed the test/enum-string-alias-member branch from d575d86 to 0197623 Compare April 13, 2026 08:44
@Dunqing Dunqing force-pushed the feat/optimize-enums-option branch from 07d6574 to 8496bbe Compare April 13, 2026 08:44
## Summary

- Add a conformance test for string enum alias members (e.g. `Default = Theme.Light`) covering both const and non-const enum cases
- Verifies no incorrect reverse mapping is generated for string alias members (relates to rolldown/rolldown#8866)

## Test plan

- `cargo run -p oxc_transform_conformance -- --filter enum-string-alias-member` passes

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@graphite-app graphite-app Bot force-pushed the feat/optimize-enums-option branch from 8496bbe to e7e1aea Compare April 13, 2026 08:49
@graphite-app graphite-app Bot force-pushed the test/enum-string-alias-member branch from 0197623 to 995e13e Compare April 13, 2026 08:50
Base automatically changed from feat/optimize-enums-option to main April 13, 2026 08:53
@graphite-app graphite-app Bot removed the 0-merge Merge with Graphite Merge Queue label Apr 13, 2026
@graphite-app graphite-app Bot merged commit 995e13e into main Apr 13, 2026
25 checks passed
@graphite-app graphite-app Bot deleted the test/enum-string-alias-member branch April 13, 2026 08:54
IWANABETHATGUY pushed a commit to rolldown/rolldown that referenced this pull request Apr 15, 2026
## Summary

Enable cross-module enum inlining by consuming pre-computed enum member
values from oxc_semantic.

**Depends on:** oxc-project/oxc#20652

closes #4342

### What changed

- **Extract enum values** from initial `Scoping` before the transformer
converts enums to IIFEs/placeholders
- **Store on `EcmaView`** as `enum_member_value_map` (name-keyed,
survives transformer rewrites)
- **Inline enum member accesses** in the scope hoisting finalizer:
  - `Direction.Up` → `0` (dot notation)
  - `Direction["Up"]` → `0` (bracket notation)
  - `ns.Direction.Up` → `0` (chained namespace access)
- **Tree-shake dead enum declarations** when all references are inlined
member accesses
- Supports both `const enum` and regular `enum` when all members have
statically known values
- Enables oxc's `optimize_const_enums` and `optimize_enums` transformer
options

### Architecture

The enum inlining pipeline follows Rolldown's existing module processing
stages:

```
┌─ Scan Stage (per module) ──────────────────────────────────────────┐
│                                                                     │
│  pre_process_ecma_ast.rs                                           │
│  ├─ Step 1: SemanticBuilder → Scoping                              │
│  ├─ Step 1.5: Extract enum_member_value_map from Scoping           │
│  │            (before transformer destroys enum declarations)       │
│  ├─ Step 3: Transformer (optimize_const_enums + optimize_enums)    │
│  │           const enums → removed, regular enums → @__PURE__ IIFE │
│  └─ Returns ParseToEcmaAstResult { enum_member_value_map, ... }    │
│                                                                     │
│  ecma_module_view_factory.rs                                        │
│  ├─ AstScanner: scans AST for imports/exports/statements           │
│  └─ enum_member_value_map stored directly on EcmaView              │
│     (bypasses AstScanner — no symbol-level processing needed)       │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

┌─ Link Stage ───────────────────────────────────────────────────────┐
│                                                                     │
│  include_statements.rs (tree-shaking)                               │
│  ├─ Computes has_enum_inlining once for the whole bundle           │
│  └─ For member expr refs (e.g. B.member):                          │
│     if member exists in enum_member_value_map → skip including     │
│     the enum declaration (it will be inlined, declaration is dead)  │
│                                                                     │
│  has_enum_inlining stored on LinkStageOutput for generate stage    │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

┌─ Generate Stage ───────────────────────────────────────────────────┐
│                                                                     │
│  ScopeHoistingFinalizer (impl_visit_mut.rs + mod.rs)               │
│  ├─ visit_expression: try_inline_enum_access() before other        │
│  │   member expr rewrites                                          │
│  ├─ After namespace rewrite (ns.E → E): retry enum inlining       │
│  └─ try_inline_enum_member_by_ref: canonical_ref → owner module   │
│     → enum_member_value_map → literal value                        │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘
```

### Comparison with other tools

| Feature | Rolldown (this PR) | esbuild | TypeScript (`tsc`) |
|---|---|---|---|
| Const enum inlining | Yes | Yes | Yes (same-file only with
`--isolatedModules`) |
| Regular enum inlining | Yes | Yes | No |
| Cross-module const enum | Yes | Yes | No (with `--isolatedModules`) |
| Optional chaining (`E?.X`) | No | No | No |
| Computed access (`E["X"]`) | Yes | Yes | Yes |
| Namespace chains (`ns.E.X`) | Yes | Yes | N/A |
| Tree-shake dead enum decls | Yes | Yes | No |
| Merged/sibling enums | Yes | Yes | Yes |

### Performance

- `has_enum_inlining` flag computed once during link stage, reused by
generate stage
- Fast-path skip in visitor hot loop for enum-free bundles

## Test plan

- [x] `ts_enum_cross_module_inlining_access` — direct + computed member
access inlined
- [x] `ts_enum_cross_module_inlining_edge_cases` — renamed re-exports,
namespace re-exports, mixed value types, const vs regular
- [x] `ts_enum_cross_module_inlining_definitions` — enum definitions
handled correctly
- [x] `ts_enum_cross_module_inlining_re_export` — chained
`ns.Enum.Member` inlined
- [x] `ts_enum_cross_module_tree_shaking` — dead enum declarations
removed
- [x] `ts_enum_same_module_inlining_access` — same-module accesses
inlined
- [x] `ts_const_enum_comments` — const enum member accesses inlined
- [x] `ts_sibling_enum` — merged enum declarations resolved correctly
- [x] `cross_module_constant_folding_*` — number, string, computed
property name folding
- [x] Full enum test suite: 15 passed, 0 failed

### Known limitations

- Optional chaining on enums (`E?.X`) not inlined (matches esbuild
behavior)
- Comment annotations (`/* Direction.Up */`) on inlined values not yet
implemented

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-semantic Area - Semantic A-transformer Area - Transformer / Transpiler C-test Category - Testing. Code is missing test cases, or a PR is adding them

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant