Files
oxc-project__oxc/crates/oxc_react_compiler/tests/snapshots/unary-expr.snap
Boshen 4e9194fe57 fix(react_compiler): lower delete obj.prop to Property/ComputedDelete (#24123)
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.
2026-07-03 15:57:29 +00:00

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"
};