[compiler] Fixture tests for PropertyStore effects

Adds fixture tests to demonstrate an issue in changing PropertyStore to always have a Store effect on its object operand, regardless of the operand type. The issue is that if we're doing a PropertyStore on a nested value, that has be considered a transitive mutation of the parent object:

```
const x = {y: {z: {}}};
x.y.z.key = 'value'; // this has to be a mutation of `x`
```

Fix in the next PR.

ghstack-source-id: 4491c86970
Pull Request resolved: https://github.com/facebook/react/pull/33163
This commit is contained in:
Joe Savona
2025-06-09 11:10:15 -07:00
parent 17ffa32fe9
commit ac2c71e44d
2 changed files with 125 additions and 0 deletions
@@ -0,0 +1,102 @@
## Input
```javascript
function Component({a, b, c}) {
// This is an object version of array-access-assignment.js
// Meant to confirm that object expressions and PropertyStore/PropertyLoad with strings
// works equivalently to array expressions and property accesses with numeric indices
const x = {zero: a};
const y = {zero: null, one: b};
const z = {zero: {}, one: {}, two: {zero: c}};
x.zero = y.one;
z.zero.zero = x.zero;
return {zero: x, one: z};
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{a: 1, b: 20, c: 300}],
sequentialRenders: [
{a: 2, b: 20, c: 300},
{a: 3, b: 20, c: 300},
{a: 3, b: 21, c: 300},
{a: 3, b: 22, c: 300},
{a: 3, b: 22, c: 301},
],
};
```
## Code
```javascript
import { c as _c } from "react/compiler-runtime";
function Component(t0) {
const $ = _c(10);
const { a, b, c } = t0;
let t1;
if ($[0] !== a || $[1] !== b || $[2] !== c) {
const x = { zero: a };
let t2;
if ($[4] !== b) {
t2 = { zero: null, one: b };
$[4] = b;
$[5] = t2;
} else {
t2 = $[5];
}
const y = t2;
let t3;
let t4;
if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
t3 = {};
t4 = {};
$[6] = t3;
$[7] = t4;
} else {
t3 = $[6];
t4 = $[7];
}
let t5;
if ($[8] !== c) {
t5 = { zero: c };
$[8] = c;
$[9] = t5;
} else {
t5 = $[9];
}
const z = { zero: t3, one: t4, two: t5 };
x.zero = y.one;
z.zero.zero = x.zero;
t1 = { zero: x, one: z };
$[0] = a;
$[1] = b;
$[2] = c;
$[3] = t1;
} else {
t1 = $[3];
}
return t1;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{ a: 1, b: 20, c: 300 }],
sequentialRenders: [
{ a: 2, b: 20, c: 300 },
{ a: 3, b: 20, c: 300 },
{ a: 3, b: 21, c: 300 },
{ a: 3, b: 22, c: 300 },
{ a: 3, b: 22, c: 301 },
],
};
```
### Eval output
(kind: ok) {"zero":{"zero":20},"one":{"zero":{"zero":20},"one":{},"two":{"zero":300}}}
{"zero":{"zero":20},"one":{"zero":{"zero":20},"one":{},"two":{"zero":300}}}
{"zero":{"zero":21},"one":{"zero":{"zero":21},"one":{},"two":{"zero":300}}}
{"zero":{"zero":22},"one":{"zero":{"zero":22},"one":{},"two":{"zero":300}}}
{"zero":{"zero":22},"one":{"zero":{"zero":22},"one":{},"two":{"zero":301}}}
@@ -0,0 +1,23 @@
function Component({a, b, c}) {
// This is an object version of array-access-assignment.js
// Meant to confirm that object expressions and PropertyStore/PropertyLoad with strings
// works equivalently to array expressions and property accesses with numeric indices
const x = {zero: a};
const y = {zero: null, one: b};
const z = {zero: {}, one: {}, two: {zero: c}};
x.zero = y.one;
z.zero.zero = x.zero;
return {zero: x, one: z};
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{a: 1, b: 20, c: 300}],
sequentialRenders: [
{a: 2, b: 20, c: 300},
{a: 3, b: 20, c: 300},
{a: 3, b: 21, c: 300},
{a: 3, b: 22, c: 300},
{a: 3, b: 22, c: 301},
],
};