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.
46 lines
828 B
Plaintext
46 lines
828 B
Plaintext
---
|
|
source: crates/oxc_react_compiler/tests/snapshot.rs
|
|
input_file: crates/oxc_react_compiler/fixtures/unary-expr.js
|
|
---
|
|
import { c as _c } from "react/compiler-runtime";
|
|
// @enablePreserveExistingMemoizationGuarantees:false
|
|
function component(a) {
|
|
const $ = _c(8);
|
|
const t = { t: a };
|
|
const z = +t.t;
|
|
const q = -t.t;
|
|
const p = void t.t;
|
|
const n = delete t.t;
|
|
const m = !t.t;
|
|
const e = ~t.t;
|
|
const f = typeof t.t;
|
|
let t0;
|
|
if ($[0] !== e || $[1] !== f || $[2] !== m || $[3] !== n || $[4] !== p || $[5] !== q || $[6] !== z) {
|
|
t0 = {
|
|
z,
|
|
p,
|
|
q,
|
|
n,
|
|
m,
|
|
e,
|
|
f
|
|
};
|
|
$[0] = e;
|
|
$[1] = f;
|
|
$[2] = m;
|
|
$[3] = n;
|
|
$[4] = p;
|
|
$[5] = q;
|
|
$[6] = z;
|
|
$[7] = t0;
|
|
} else {
|
|
t0 = $[7];
|
|
}
|
|
return t0;
|
|
}
|
|
export const FIXTURE_ENTRYPOINT = {
|
|
fn: component,
|
|
params: ["TodoAdd"],
|
|
isComponent: "TodoAdd"
|
|
};
|