mirror of
https://github.com/oxc-project/oxc.git
synced 2026-09-14 19:36:11 +08:00
4e9194fe57
Closes Group C of the "oxc compiles where the fork errors" gap — deleting a property of a frozen or global value.
## Root cause
`build_hir` lowered `delete` on a member expression to a `Primitive(undefined)` no-op behind a leftover `TODO(stage1a-arms)`. So `delete obj.prop` was **silently dropped** — the deletion never reached the output, and it never produced a mutation effect. The downstream machinery was already in place: mutation inference emits `Mutate { object }` for `PropertyDelete`/`ComputedDelete` (`infer_mutation_aliasing_effects.rs:1953`) and codegen emits `delete ...` for them (`codegen_reactive_function.rs:2034`). Only the lowering was missing.
## Fix
Lower `delete obj.prop` → `PropertyDelete` and `delete obj[key]` → `ComputedDelete`, reusing the existing `lower_member_expression` helper (matches TS `BuildHIR`). Non-member `delete` keeps the prior no-op.
## Result (9 snapshots, all improvements)
- **3 error fixtures now error + decline** with `This value cannot be modified`, matching the fork: `error.invalid-delete-property-of-frozen-value`, `error.invalid-delete-computed-property-of-frozen-value`, `error.mutate-property-from-global`.
- **6 fixtures that compile with a `delete`** now emit `delete ...` instead of the silently-dropped `undefined` (e.g. `delete-property` now matches the fork exactly; `round3_effect_read_vs_capture_v2` — previously a mis-compile — now emits `delete profile[key]`).
Verified: full `cargo test -p oxc_react_compiler` (snapshot + 15 unit tests) green, `cargo clippy --all-features -D warnings` and `cargo fmt --check` clean.
28 lines
530 B
Plaintext
28 lines
530 B
Plaintext
---
|
|
source: crates/oxc_react_compiler/tests/snapshot.rs
|
|
input_file: crates/oxc_react_compiler/fixtures/delete-computed-property.js
|
|
---
|
|
import { c as _c } from "react/compiler-runtime";
|
|
function Component(props) {
|
|
const $ = _c(3);
|
|
let x;
|
|
if ($[0] !== props.a || $[1] !== props.b) {
|
|
x = {
|
|
a: props.a,
|
|
b: props.b
|
|
};
|
|
delete x["b"];
|
|
$[0] = props.a;
|
|
$[1] = props.b;
|
|
$[2] = x;
|
|
} else {
|
|
x = $[2];
|
|
}
|
|
return x;
|
|
}
|
|
export const FIXTURE_ENTRYPOINT = {
|
|
fn: Component,
|
|
params: ["TodoAdd"],
|
|
isComponent: "TodoAdd"
|
|
};
|