mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
feat(transformer/typescript): debug_assert that enum_eval ran in semantic (#22252)
Closes #21667. Stacked on #22253 (which lands the prerequisite `with_enum_eval(true)` calls in `cargo allocs` and the four transformer benches that this assert would otherwise trip). ## Problem The TS enum lowering reads pre-computed member values from `Scoping`. Those values are only populated when `SemanticBuilder::with_enum_eval(true)` is set; without it, every `get_enum_member_value` call returns `None`, so string-valued members are treated as opaque expressions and the transform emits incorrect reverse mappings. Example from #21667: ```ts enum Theme { Light = "Light", Dark = "Dark", Default = Theme.Light, } ``` When the transformer runs on a `Scoping` built without `enum_eval`, it does not recognise `Theme.Light` as a string and produces: ```js Theme[Theme["Default"] = Theme.Light] = "Default"; ``` — i.e. a reverse-mapping assignment for a string member, which is wrong (and runtime-observable). ## Fix Add a `debug_assert!` at the entry of `transform_ts_enum` (after the `decl.declare` early return) verifying that the enum's body scope is registered in `Scoping`. The check uses `get_enum_body_scopes` as the signal: `add_enum_body_scope` has exactly one caller (`evaluate_enum_members`), which is gated entirely by `enum_eval`. No new state on `Scoping` / `EnumData`. The internal `Compiler` (`crates/oxc/src/compiler.rs`) and the playground (`napi/playground/src/lib.rs`) already enable `enum_eval`. The benches and `cargo allocs` are fixed in the parent PR. This guard catches the misuse for any other external caller of `Transformer::build_with_scoping`. ## Test plan - [x] `cargo test -p oxc_transformer` — new integration tests in `tests/integrations/enum_eval.rs` cover both the positive case and the `#[should_panic]` case (debug-only) - [x] `cargo run -p oxc_transform_conformance` — no snapshot changes (the conformance runner goes through `CompilerInterface`, which already enables `enum_eval`) - [x] `cargo clippy -p oxc_transformer --tests` — clean
This commit is contained in:
1 parent
31a5de7991
commit
66c9b01c83
6 files changed
+51
-8
No files matched your search
@@ -160,6 +160,17 @@ impl<'a> TypeScriptEnum {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Enum lowering relies on pre-computed member values stored in `Scoping`
|
||||
// by `evaluate_enum_members` (only run when the semantic builder is configured
|
||||
// with `enum_eval`). Without it, string-valued members are not recognized and
|
||||
// the transform emits incorrect reverse mappings (see oxc#21667).
|
||||
debug_assert!(
|
||||
ctx.scoping().get_enum_body_scopes(decl.id.symbol_id()).is_some(),
|
||||
"Transformer requires `Scoping` produced with `SemanticBuilder::with_enum_eval(true)` \
|
||||
to correctly transform `enum {}`.",
|
||||
decl.id.name,
|
||||
);
|
||||
|
||||
let ast = ctx.ast;
|
||||
|
||||
let is_export = export_span.is_some();
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
use std::path::Path;
|
||||
|
||||
use oxc_allocator::Allocator;
|
||||
use oxc_parser::Parser;
|
||||
use oxc_semantic::SemanticBuilder;
|
||||
use oxc_span::SourceType;
|
||||
use oxc_transformer::{TransformOptions, Transformer};
|
||||
|
||||
fn run(enum_eval: bool) {
|
||||
let source_text = "enum E { A = 1 }";
|
||||
let source_type = SourceType::ts();
|
||||
let allocator = Allocator::default();
|
||||
let ret = Parser::new(&allocator, source_text, source_type).parse();
|
||||
let mut program = ret.program;
|
||||
let scoping =
|
||||
SemanticBuilder::new().with_enum_eval(enum_eval).build(&program).semantic.into_scoping();
|
||||
let _ret = Transformer::new(&allocator, Path::new(""), &TransformOptions::default())
|
||||
.build_with_scoping(scoping, &mut program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transforms_enum_when_enum_eval_enabled() {
|
||||
run(true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "SemanticBuilder::with_enum_eval(true)")]
|
||||
#[cfg(debug_assertions)]
|
||||
fn panics_when_enum_eval_disabled() {
|
||||
run(false);
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
mod enum_eval;
|
||||
mod es_target;
|
||||
mod helper_call;
|
||||
mod targets;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
File | File size || Sys allocs | Sys reallocs || Arena allocs | Arena reallocs | Arena bytes
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------
|
||||
checker.ts | 2.92 MB || 286 | 37 || 152712 | 28244
|
||||
checker.ts | 2.92 MB || 286 | 37 || 152659 | 28244
|
||||
|
||||
cal.com.tsx | 1.06 MB || 20214 | 46 || 37153 | 4570
|
||||
|
||||
@@ -10,5 +10,5 @@ pdf.mjs | 567.30 kB || 4052 | 417 |
|
||||
|
||||
antd.js | 6.69 MB || 7702 | 1657 || 331684 | 69349
|
||||
|
||||
binder.ts | 193.08 kB || 66 | 23 || 7083 | 824
|
||||
binder.ts | 193.08 kB || 66 | 23 || 7075 | 824
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
File | File size || Sys allocs | Sys reallocs || Arena allocs | Arena reallocs | Arena bytes
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------
|
||||
checker.ts | 2.92 MB || 2281 | 18 || 0 | 0
|
||||
checker.ts | 2.92 MB || 2309 | 18 || 0 | 0
|
||||
|
||||
cal.com.tsx | 1.06 MB || 14966 | 22 || 0 | 0
|
||||
cal.com.tsx | 1.06 MB || 14978 | 22 || 0 | 0
|
||||
|
||||
RadixUIAdoptionSection.jsx | 2.52 kB || 10 | 3 || 0 | 0
|
||||
|
||||
@@ -10,5 +10,5 @@ pdf.mjs | 567.30 kB || 1401 | 208 |
|
||||
|
||||
antd.js | 6.69 MB || 2455 | 18 || 0 | 0
|
||||
|
||||
binder.ts | 193.08 kB || 190 | 11 || 0 | 0
|
||||
binder.ts | 193.08 kB || 196 | 11 || 0 | 0
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
File | File size || Sys allocs | Sys reallocs || Arena allocs | Arena reallocs | Arena bytes
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------
|
||||
checker.ts | 2.92 MB || 159 | 1 || 4765 | 64
|
||||
checker.ts | 2.92 MB || 20 | 1 || 4400 | 64
|
||||
|
||||
cal.com.tsx | 1.06 MB || 37 | 3 || 38190 | 3515
|
||||
cal.com.tsx | 1.06 MB || 26 | 3 || 38212 | 3515
|
||||
|
||||
RadixUIAdoptionSection.jsx | 2.52 kB || 22 | 3 || 259 | 24
|
||||
|
||||
@@ -10,5 +10,5 @@ pdf.mjs | 567.30 kB || 15 | 0 |
|
||||
|
||||
antd.js | 6.69 MB || 15 | 0 || 2 | 0
|
||||
|
||||
binder.ts | 193.08 kB || 30 | 1 || 367 | 6
|
||||
binder.ts | 193.08 kB || 18 | 1 || 379 | 6
|
||||
|
||||
Reference in new issue
Block a user