@samitouri / QOS-React-1 / commits / 943e45e910

[compiler][test fixtures] Fork more fixtures for hir-rewrite

Followup from #30894 , not sure how these got missed. Note that this PR just copies the fixtures without adding `@enablePropagateDepsInHIR`. #31032 follows and actually enables the HIR-version of propagateScopeDeps to run. I split this out into two PRs to make snapshot differences easier to review, but also happy to merge Fixtures found from locally setting snap test runner to default to `enablePropagateDepsInHIR: 'enabled_baseline'` and forking fixtures files with different output. ghstack-source-id: 7d7cf41aa923d83ad49f89079171b0411923ce6b Pull Request resolved: https://github.com/facebook/react/pull/31030

Mofei Zhang committed Sep 30, 2024 at 12:24 UTC 943e45e910d1a125f2be431c2b66f22a035ea0c9
29 files changed +1504
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/conditional-break-labeled.expect.md new
+65
@@ -0,0 +1,65 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +/**
6 + * props.b *does* influence `a`
7 + */
8 +function Component(props) {
9 + const a = [];
10 + a.push(props.a);
11 + label: {
12 + if (props.b) {
13 + break label;
14 + }
15 + a.push(props.c);
16 + }
17 + a.push(props.d);
18 + return a;
19 +}
20 +
21 +export const FIXTURE_ENTRYPOINT = {
22 + fn: Component,
23 + params: ['TodoAdd'],
24 + isComponent: 'TodoAdd',
25 +};
26 +
27 +```
28 +
29 +## Code
30 +
31 +```javascript
32 +import { c as _c } from "react/compiler-runtime"; /**
33 + * props.b *does* influence `a`
34 + */
35 +function Component(props) {
36 + const $ = _c(2);
37 + let a;
38 + if ($[0] !== props) {
39 + a = [];
40 + a.push(props.a);
41 + bb0: {
42 + if (props.b) {
43 + break bb0;
44 + }
45 +
46 + a.push(props.c);
47 + }
48 +
49 + a.push(props.d);
50 + $[0] = props;
51 + $[1] = a;
52 + } else {
53 + a = $[1];
54 + }
55 + return a;
56 +}
57 +
58 +export const FIXTURE_ENTRYPOINT = {
59 + fn: Component,
60 + params: ["TodoAdd"],
61 + isComponent: "TodoAdd",
62 +};
63 +
64 +```
65 +
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/conditional-break-labeled.js new
+21
@@ -0,0 +1,21 @@
1 +/**
2 + * props.b *does* influence `a`
3 + */
4 +function Component(props) {
5 + const a = [];
6 + a.push(props.a);
7 + label: {
8 + if (props.b) {
9 + break label;
10 + }
11 + a.push(props.c);
12 + }
13 + a.push(props.d);
14 + return a;
15 +}
16 +
17 +export const FIXTURE_ENTRYPOINT = {
18 + fn: Component,
19 + params: ['TodoAdd'],
20 + isComponent: 'TodoAdd',
21 +};
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/conditional-early-return.expect.md new
+197
@@ -0,0 +1,197 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +/**
6 + * props.b does *not* influence `a`
7 + */
8 +function ComponentA(props) {
9 + const a_DEBUG = [];
10 + a_DEBUG.push(props.a);
11 + if (props.b) {
12 + return null;
13 + }
14 + a_DEBUG.push(props.d);
15 + return a_DEBUG;
16 +}
17 +
18 +/**
19 + * props.b *does* influence `a`
20 + */
21 +function ComponentB(props) {
22 + const a = [];
23 + a.push(props.a);
24 + if (props.b) {
25 + a.push(props.c);
26 + }
27 + a.push(props.d);
28 + return a;
29 +}
30 +
31 +/**
32 + * props.b *does* influence `a`, but only in a way that is never observable
33 + */
34 +function ComponentC(props) {
35 + const a = [];
36 + a.push(props.a);
37 + if (props.b) {
38 + a.push(props.c);
39 + return null;
40 + }
41 + a.push(props.d);
42 + return a;
43 +}
44 +
45 +/**
46 + * props.b *does* influence `a`
47 + */
48 +function ComponentD(props) {
49 + const a = [];
50 + a.push(props.a);
51 + if (props.b) {
52 + a.push(props.c);
53 + return a;
54 + }
55 + a.push(props.d);
56 + return a;
57 +}
58 +
59 +export const FIXTURE_ENTRYPOINT = {
60 + fn: ComponentA,
61 + params: [{a: 1, b: false, d: 3}],
62 +};
63 +
64 +```
65 +
66 +## Code
67 +
68 +```javascript
69 +import { c as _c } from "react/compiler-runtime"; /**
70 + * props.b does *not* influence `a`
71 + */
72 +function ComponentA(props) {
73 + const $ = _c(3);
74 + let a_DEBUG;
75 + let t0;
76 + if ($[0] !== props) {
77 + t0 = Symbol.for("react.early_return_sentinel");
78 + bb0: {
79 + a_DEBUG = [];
80 + a_DEBUG.push(props.a);
81 + if (props.b) {
82 + t0 = null;
83 + break bb0;
84 + }
85 +
86 + a_DEBUG.push(props.d);
87 + }
88 + $[0] = props;
89 + $[1] = a_DEBUG;
90 + $[2] = t0;
91 + } else {
92 + a_DEBUG = $[1];
93 + t0 = $[2];
94 + }
95 + if (t0 !== Symbol.for("react.early_return_sentinel")) {
96 + return t0;
97 + }
98 + return a_DEBUG;
99 +}
100 +
101 +/**
102 + * props.b *does* influence `a`
103 + */
104 +function ComponentB(props) {
105 + const $ = _c(2);
106 + let a;
107 + if ($[0] !== props) {
108 + a = [];
109 + a.push(props.a);
110 + if (props.b) {
111 + a.push(props.c);
112 + }
113 +
114 + a.push(props.d);
115 + $[0] = props;
116 + $[1] = a;
117 + } else {
118 + a = $[1];
119 + }
120 + return a;
121 +}
122 +
123 +/**
124 + * props.b *does* influence `a`, but only in a way that is never observable
125 + */
126 +function ComponentC(props) {
127 + const $ = _c(3);
128 + let a;
129 + let t0;
130 + if ($[0] !== props) {
131 + t0 = Symbol.for("react.early_return_sentinel");
132 + bb0: {
133 + a = [];
134 + a.push(props.a);
135 + if (props.b) {
136 + a.push(props.c);
137 + t0 = null;
138 + break bb0;
139 + }
140 +
141 + a.push(props.d);
142 + }
143 + $[0] = props;
144 + $[1] = a;
145 + $[2] = t0;
146 + } else {
147 + a = $[1];
148 + t0 = $[2];
149 + }
150 + if (t0 !== Symbol.for("react.early_return_sentinel")) {
151 + return t0;
152 + }
153 + return a;
154 +}
155 +
156 +/**
157 + * props.b *does* influence `a`
158 + */
159 +function ComponentD(props) {
160 + const $ = _c(3);
161 + let a;
162 + let t0;
163 + if ($[0] !== props) {
164 + t0 = Symbol.for("react.early_return_sentinel");
165 + bb0: {
166 + a = [];
167 + a.push(props.a);
168 + if (props.b) {
169 + a.push(props.c);
170 + t0 = a;
171 + break bb0;
172 + }
173 +
174 + a.push(props.d);
175 + }
176 + $[0] = props;
177 + $[1] = a;
178 + $[2] = t0;
179 + } else {
180 + a = $[1];
181 + t0 = $[2];
182 + }
183 + if (t0 !== Symbol.for("react.early_return_sentinel")) {
184 + return t0;
185 + }
186 + return a;
187 +}
188 +
189 +export const FIXTURE_ENTRYPOINT = {
190 + fn: ComponentA,
191 + params: [{ a: 1, b: false, d: 3 }],
192 +};
193 +
194 +```
195 +
196 +### Eval output
197 +(kind: ok) [1,3]
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/conditional-early-return.js new
+58
@@ -0,0 +1,58 @@
1 +/**
2 + * props.b does *not* influence `a`
3 + */
4 +function ComponentA(props) {
5 + const a_DEBUG = [];
6 + a_DEBUG.push(props.a);
7 + if (props.b) {
8 + return null;
9 + }
10 + a_DEBUG.push(props.d);
11 + return a_DEBUG;
12 +}
13 +
14 +/**
15 + * props.b *does* influence `a`
16 + */
17 +function ComponentB(props) {
18 + const a = [];
19 + a.push(props.a);
20 + if (props.b) {
21 + a.push(props.c);
22 + }
23 + a.push(props.d);
24 + return a;
25 +}
26 +
27 +/**
28 + * props.b *does* influence `a`, but only in a way that is never observable
29 + */
30 +function ComponentC(props) {
31 + const a = [];
32 + a.push(props.a);
33 + if (props.b) {
34 + a.push(props.c);
35 + return null;
36 + }
37 + a.push(props.d);
38 + return a;
39 +}
40 +
41 +/**
42 + * props.b *does* influence `a`
43 + */
44 +function ComponentD(props) {
45 + const a = [];
46 + a.push(props.a);
47 + if (props.b) {
48 + a.push(props.c);
49 + return a;
50 + }
51 + a.push(props.d);
52 + return a;
53 +}
54 +
55 +export const FIXTURE_ENTRYPOINT = {
56 + fn: ComponentA,
57 + params: [{a: 1, b: false, d: 3}],
58 +};
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/conditional-on-mutable.expect.md new
+88
@@ -0,0 +1,88 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function ComponentA(props) {
6 + const a = [];
7 + const b = [];
8 + if (b) {
9 + a.push(props.p0);
10 + }
11 + if (props.p1) {
12 + b.push(props.p2);
13 + }
14 + return <Foo a={a} b={b} />;
15 +}
16 +
17 +function ComponentB(props) {
18 + const a = [];
19 + const b = [];
20 + if (mayMutate(b)) {
21 + a.push(props.p0);
22 + }
23 + if (props.p1) {
24 + b.push(props.p2);
25 + }
26 + return <Foo a={a} b={b} />;
27 +}
28 +
29 +function Foo() {}
30 +function mayMutate() {}
31 +
32 +```
33 +
34 +## Code
35 +
36 +```javascript
37 +import { c as _c } from "react/compiler-runtime";
38 +function ComponentA(props) {
39 + const $ = _c(2);
40 + let t0;
41 + if ($[0] !== props) {
42 + const a = [];
43 + const b = [];
44 + if (b) {
45 + a.push(props.p0);
46 + }
47 + if (props.p1) {
48 + b.push(props.p2);
49 + }
50 +
51 + t0 = <Foo a={a} b={b} />;
52 + $[0] = props;
53 + $[1] = t0;
54 + } else {
55 + t0 = $[1];
56 + }
57 + return t0;
58 +}
59 +
60 +function ComponentB(props) {
61 + const $ = _c(2);
62 + let t0;
63 + if ($[0] !== props) {
64 + const a = [];
65 + const b = [];
66 + if (mayMutate(b)) {
67 + a.push(props.p0);
68 + }
69 + if (props.p1) {
70 + b.push(props.p2);
71 + }
72 +
73 + t0 = <Foo a={a} b={b} />;
74 + $[0] = props;
75 + $[1] = t0;
76 + } else {
77 + t0 = $[1];
78 + }
79 + return t0;
80 +}
81 +
82 +function Foo() {}
83 +function mayMutate() {}
84 +
85 +```
86 +
87 +### Eval output
88 +(kind: exception) Fixture not implemented
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/conditional-on-mutable.js new
+26
@@ -0,0 +1,26 @@
1 +function ComponentA(props) {
2 + const a = [];
3 + const b = [];
4 + if (b) {
5 + a.push(props.p0);
6 + }
7 + if (props.p1) {
8 + b.push(props.p2);
9 + }
10 + return <Foo a={a} b={b} />;
11 +}
12 +
13 +function ComponentB(props) {
14 + const a = [];
15 + const b = [];
16 + if (mayMutate(b)) {
17 + a.push(props.p0);
18 + }
19 + if (props.p1) {
20 + b.push(props.p2);
21 + }
22 + return <Foo a={a} b={b} />;
23 +}
24 +
25 +function Foo() {}
26 +function mayMutate() {}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/early-return-nested-early-return-within-reactive-scope.expect.md new
+89
@@ -0,0 +1,89 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function Component(props) {
6 + let x = [];
7 + if (props.cond) {
8 + x.push(props.a);
9 + if (props.b) {
10 + const y = [props.b];
11 + x.push(y);
12 + // oops no memo!
13 + return x;
14 + }
15 + // oops no memo!
16 + return x;
17 + } else {
18 + return foo();
19 + }
20 +}
21 +
22 +export const FIXTURE_ENTRYPOINT = {
23 + fn: Component,
24 + params: [{cond: true, a: 42, b: 3.14}],
25 +};
26 +
27 +```
28 +
29 +## Code
30 +
31 +```javascript
32 +import { c as _c } from "react/compiler-runtime";
33 +function Component(props) {
34 + const $ = _c(5);
35 + let t0;
36 + if ($[0] !== props) {
37 + t0 = Symbol.for("react.early_return_sentinel");
38 + bb0: {
39 + const x = [];
40 + if (props.cond) {
41 + x.push(props.a);
42 + if (props.b) {
43 + let t1;
44 + if ($[2] !== props.b) {
45 + t1 = [props.b];
46 + $[2] = props.b;
47 + $[3] = t1;
48 + } else {
49 + t1 = $[3];
50 + }
51 + const y = t1;
52 + x.push(y);
53 + t0 = x;
54 + break bb0;
55 + }
56 +
57 + t0 = x;
58 + break bb0;
59 + } else {
60 + let t1;
61 + if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
62 + t1 = foo();
63 + $[4] = t1;
64 + } else {
65 + t1 = $[4];
66 + }
67 + t0 = t1;
68 + break bb0;
69 + }
70 + }
71 + $[0] = props;
72 + $[1] = t0;
73 + } else {
74 + t0 = $[1];
75 + }
76 + if (t0 !== Symbol.for("react.early_return_sentinel")) {
77 + return t0;
78 + }
79 +}
80 +
81 +export const FIXTURE_ENTRYPOINT = {
82 + fn: Component,
83 + params: [{ cond: true, a: 42, b: 3.14 }],
84 +};
85 +
86 +```
87 +
88 +### Eval output
89 +(kind: ok) [42,[3.14]]
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/early-return-nested-early-return-within-reactive-scope.js new
+21
@@ -0,0 +1,21 @@
1 +function Component(props) {
2 + let x = [];
3 + if (props.cond) {
4 + x.push(props.a);
5 + if (props.b) {
6 + const y = [props.b];
7 + x.push(y);
8 + // oops no memo!
9 + return x;
10 + }
11 + // oops no memo!
12 + return x;
13 + } else {
14 + return foo();
15 + }
16 +}
17 +
18 +export const FIXTURE_ENTRYPOINT = {
19 + fn: Component,
20 + params: [{cond: true, a: 42, b: 3.14}],
21 +};
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/early-return-within-reactive-scope.expect.md new
+112
@@ -0,0 +1,112 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +import {makeArray} from 'shared-runtime';
6 +
7 +function Component(props) {
8 + let x = [];
9 + if (props.cond) {
10 + x.push(props.a);
11 + // oops no memo!
12 + return x;
13 + } else {
14 + return makeArray(props.b);
15 + }
16 +}
17 +
18 +export const FIXTURE_ENTRYPOINT = {
19 + fn: Component,
20 + params: [],
21 + sequentialRenders: [
22 + // pattern 1
23 + {cond: true, a: 42},
24 + {cond: true, a: 42},
25 + // pattern 2
26 + {cond: false, b: 3.14},
27 + {cond: false, b: 3.14},
28 + // pattern 1
29 + {cond: true, a: 42},
30 + // pattern 2
31 + {cond: false, b: 3.14},
32 + // pattern 1
33 + {cond: true, a: 42},
34 + // pattern 2
35 + {cond: false, b: 3.14},
36 + ],
37 +};
38 +
39 +```
40 +
41 +## Code
42 +
43 +```javascript
44 +import { c as _c } from "react/compiler-runtime";
45 +import { makeArray } from "shared-runtime";
46 +
47 +function Component(props) {
48 + const $ = _c(4);
49 + let t0;
50 + if ($[0] !== props) {
51 + t0 = Symbol.for("react.early_return_sentinel");
52 + bb0: {
53 + const x = [];
54 + if (props.cond) {
55 + x.push(props.a);
56 + t0 = x;
57 + break bb0;
58 + } else {
59 + let t1;
60 + if ($[2] !== props.b) {
61 + t1 = makeArray(props.b);
62 + $[2] = props.b;
63 + $[3] = t1;
64 + } else {
65 + t1 = $[3];
66 + }
67 + t0 = t1;
68 + break bb0;
69 + }
70 + }
71 + $[0] = props;
72 + $[1] = t0;
73 + } else {
74 + t0 = $[1];
75 + }
76 + if (t0 !== Symbol.for("react.early_return_sentinel")) {
77 + return t0;
78 + }
79 +}
80 +
81 +export const FIXTURE_ENTRYPOINT = {
82 + fn: Component,
83 + params: [],
84 + sequentialRenders: [
85 + // pattern 1
86 + { cond: true, a: 42 },
87 + { cond: true, a: 42 },
88 + // pattern 2
89 + { cond: false, b: 3.14 },
90 + { cond: false, b: 3.14 },
91 + // pattern 1
92 + { cond: true, a: 42 },
93 + // pattern 2
94 + { cond: false, b: 3.14 },
95 + // pattern 1
96 + { cond: true, a: 42 },
97 + // pattern 2
98 + { cond: false, b: 3.14 },
99 + ],
100 +};
101 +
102 +```
103 +
104 +### Eval output
105 +(kind: ok) [42]
106 +[42]
107 +[3.14]
108 +[3.14]
109 +[42]
110 +[3.14]
111 +[42]
112 +[3.14]
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/early-return-within-reactive-scope.js new
+33
@@ -0,0 +1,33 @@
1 +import {makeArray} from 'shared-runtime';
2 +
3 +function Component(props) {
4 + let x = [];
5 + if (props.cond) {
6 + x.push(props.a);
7 + // oops no memo!
8 + return x;
9 + } else {
10 + return makeArray(props.b);
11 + }
12 +}
13 +
14 +export const FIXTURE_ENTRYPOINT = {
15 + fn: Component,
16 + params: [],
17 + sequentialRenders: [
18 + // pattern 1
19 + {cond: true, a: 42},
20 + {cond: true, a: 42},
21 + // pattern 2
22 + {cond: false, b: 3.14},
23 + {cond: false, b: 3.14},
24 + // pattern 1
25 + {cond: true, a: 42},
26 + // pattern 2
27 + {cond: false, b: 3.14},
28 + // pattern 1
29 + {cond: true, a: 42},
30 + // pattern 2
31 + {cond: false, b: 3.14},
32 + ],
33 +};
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/error.todo-optional-call-chain-in-optional.expect.md new
+34
@@ -0,0 +1,34 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function useFoo(props: {value: {x: string; y: string} | null}) {
6 + const value = props.value;
7 + return createArray(value?.x, value?.y)?.join(', ');
8 +}
9 +
10 +function createArray<T>(...args: Array<T>): Array<T> {
11 + return args;
12 +}
13 +
14 +export const FIXTURE_ENTRYPONT = {
15 + fn: useFoo,
16 + props: [{value: null}],
17 +};
18 +
19 +```
20 +
21 +
22 +## Error
23 +
24 +```
25 + 1 | function useFoo(props: {value: {x: string; y: string} | null}) {
26 + 2 | const value = props.value;
27 +> 3 | return createArray(value?.x, value?.y)?.join(', ');
28 + | ^^^^^^^^ Todo: Unexpected terminal kind `optional` for optional test block (3:3)
29 + 4 | }
30 + 5 |
31 + 6 | function createArray<T>(...args: Array<T>): Array<T> {
32 +```
33 +
34 +
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/error.todo-optional-call-chain-in-optional.ts new
+13
@@ -0,0 +1,13 @@
1 +function useFoo(props: {value: {x: string; y: string} | null}) {
2 + const value = props.value;
3 + return createArray(value?.x, value?.y)?.join(', ');
4 +}
5 +
6 +function createArray<T>(...args: Array<T>): Array<T> {
7 + return args;
8 +}
9 +
10 +export const FIXTURE_ENTRYPONT = {
11 + fn: useFoo,
12 + props: [{value: null}],
13 +};
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/iife-return-modified-later-phi.expect.md new
+57
@@ -0,0 +1,57 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function Component(props) {
6 + const items = (() => {
7 + if (props.cond) {
8 + return [];
9 + } else {
10 + return null;
11 + }
12 + })();
13 + items?.push(props.a);
14 + return items;
15 +}
16 +
17 +export const FIXTURE_ENTRYPOINT = {
18 + fn: Component,
19 + params: [{a: {}}],
20 +};
21 +
22 +```
23 +
24 +## Code
25 +
26 +```javascript
27 +import { c as _c } from "react/compiler-runtime";
28 +function Component(props) {
29 + const $ = _c(2);
30 + let items;
31 + if ($[0] !== props) {
32 + let t0;
33 + if (props.cond) {
34 + t0 = [];
35 + } else {
36 + t0 = null;
37 + }
38 + items = t0;
39 +
40 + items?.push(props.a);
41 + $[0] = props;
42 + $[1] = items;
43 + } else {
44 + items = $[1];
45 + }
46 + return items;
47 +}
48 +
49 +export const FIXTURE_ENTRYPOINT = {
50 + fn: Component,
51 + params: [{ a: {} }],
52 +};
53 +
54 +```
55 +
56 +### Eval output
57 +(kind: ok) null
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/iife-return-modified-later-phi.js new
+16
@@ -0,0 +1,16 @@
1 +function Component(props) {
2 + const items = (() => {
3 + if (props.cond) {
4 + return [];
5 + } else {
6 + return null;
7 + }
8 + })();
9 + items?.push(props.a);
10 + return items;
11 +}
12 +
13 +export const FIXTURE_ENTRYPOINT = {
14 + fn: Component,
15 + params: [{a: {}}],
16 +};
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/object-mutated-in-consequent-alternate-both-return.expect.md new
+66
@@ -0,0 +1,66 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +import {makeObject_Primitives} from 'shared-runtime';
6 +
7 +function Component(props) {
8 + const object = makeObject_Primitives();
9 + if (props.cond) {
10 + object.value = 1;
11 + return object;
12 + } else {
13 + object.value = props.value;
14 + return object;
15 + }
16 +}
17 +
18 +export const FIXTURE_ENTRYPOINT = {
19 + fn: Component,
20 + params: [{cond: false, value: [0, 1, 2]}],
21 +};
22 +
23 +```
24 +
25 +## Code
26 +
27 +```javascript
28 +import { c as _c } from "react/compiler-runtime";
29 +import { makeObject_Primitives } from "shared-runtime";
30 +
31 +function Component(props) {
32 + const $ = _c(2);
33 + let t0;
34 + if ($[0] !== props) {
35 + t0 = Symbol.for("react.early_return_sentinel");
36 + bb0: {
37 + const object = makeObject_Primitives();
38 + if (props.cond) {
39 + object.value = 1;
40 + t0 = object;
41 + break bb0;
42 + } else {
43 + object.value = props.value;
44 + t0 = object;
45 + break bb0;
46 + }
47 + }
48 + $[0] = props;
49 + $[1] = t0;
50 + } else {
51 + t0 = $[1];
52 + }
53 + if (t0 !== Symbol.for("react.early_return_sentinel")) {
54 + return t0;
55 + }
56 +}
57 +
58 +export const FIXTURE_ENTRYPOINT = {
59 + fn: Component,
60 + params: [{ cond: false, value: [0, 1, 2] }],
61 +};
62 +
63 +```
64 +
65 +### Eval output
66 +(kind: ok) {"a":0,"b":"value1","c":true,"value":[0,1,2]}
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/object-mutated-in-consequent-alternate-both-return.js new
+17
@@ -0,0 +1,17 @@
1 +import {makeObject_Primitives} from 'shared-runtime';
2 +
3 +function Component(props) {
4 + const object = makeObject_Primitives();
5 + if (props.cond) {
6 + object.value = 1;
7 + return object;
8 + } else {
9 + object.value = props.value;
10 + return object;
11 + }
12 +}
13 +
14 +export const FIXTURE_ENTRYPOINT = {
15 + fn: Component,
16 + params: [{cond: false, value: [0, 1, 2]}],
17 +};
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/partial-early-return-within-reactive-scope.expect.md new
+80
@@ -0,0 +1,80 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function Component(props) {
6 + let x = [];
7 + let y = null;
8 + if (props.cond) {
9 + x.push(props.a);
10 + // oops no memo!
11 + return x;
12 + } else {
13 + y = foo();
14 + if (props.b) {
15 + return;
16 + }
17 + }
18 + return y;
19 +}
20 +
21 +export const FIXTURE_ENTRYPOINT = {
22 + fn: Component,
23 + params: [{cond: true, a: 42}],
24 +};
25 +
26 +```
27 +
28 +## Code
29 +
30 +```javascript
31 +import { c as _c } from "react/compiler-runtime";
32 +function Component(props) {
33 + const $ = _c(4);
34 + let y;
35 + let t0;
36 + if ($[0] !== props) {
37 + t0 = Symbol.for("react.early_return_sentinel");
38 + bb0: {
39 + const x = [];
40 + if (props.cond) {
41 + x.push(props.a);
42 + t0 = x;
43 + break bb0;
44 + } else {
45 + let t1;
46 + if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
47 + t1 = foo();
48 + $[3] = t1;
49 + } else {
50 + t1 = $[3];
51 + }
52 + y = t1;
53 + if (props.b) {
54 + t0 = undefined;
55 + break bb0;
56 + }
57 + }
58 + }
59 + $[0] = props;
60 + $[1] = y;
61 + $[2] = t0;
62 + } else {
63 + y = $[1];
64 + t0 = $[2];
65 + }
66 + if (t0 !== Symbol.for("react.early_return_sentinel")) {
67 + return t0;
68 + }
69 + return y;
70 +}
71 +
72 +export const FIXTURE_ENTRYPOINT = {
73 + fn: Component,
74 + params: [{ cond: true, a: 42 }],
75 +};
76 +
77 +```
78 +
79 +### Eval output
80 +(kind: ok) [42]
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/partial-early-return-within-reactive-scope.js new
+20
@@ -0,0 +1,20 @@
1 +function Component(props) {
2 + let x = [];
3 + let y = null;
4 + if (props.cond) {
5 + x.push(props.a);
6 + // oops no memo!
7 + return x;
8 + } else {
9 + y = foo();
10 + if (props.b) {
11 + return;
12 + }
13 + }
14 + return y;
15 +}
16 +
17 +export const FIXTURE_ENTRYPOINT = {
18 + fn: Component,
19 + params: [{cond: true, a: 42}],
20 +};
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/phi-type-inference-array-push-consecutive-phis.expect.md new
+110
@@ -0,0 +1,110 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +import {makeArray} from 'shared-runtime';
6 +
7 +function Component(props) {
8 + const x = {};
9 + let y;
10 + if (props.cond) {
11 + if (props.cond2) {
12 + y = [props.value];
13 + } else {
14 + y = [props.value2];
15 + }
16 + } else {
17 + y = [];
18 + }
19 + // This should be inferred as `<store> y` s.t. `x` can still
20 + // be independently memoized. *But* this also must properly
21 + // extend the mutable range of the array literals in the
22 + // if/else branches
23 + y.push(x);
24 +
25 + return [x, y];
26 +}
27 +
28 +export const FIXTURE_ENTRYPOINT = {
29 + fn: Component,
30 + params: [{cond: true, cond2: true, value: 42}],
31 + sequentialRenders: [
32 + {cond: true, cond2: true, value: 3.14},
33 + {cond: true, cond2: true, value: 42},
34 + {cond: true, cond2: true, value: 3.14},
35 + {cond: true, cond2: false, value2: 3.14},
36 + {cond: true, cond2: false, value2: 42},
37 + {cond: true, cond2: false, value2: 3.14},
38 + {cond: false},
39 + {cond: false},
40 + ],
41 +};
42 +
43 +```
44 +
45 +## Code
46 +
47 +```javascript
48 +import { c as _c } from "react/compiler-runtime";
49 +import { makeArray } from "shared-runtime";
50 +
51 +function Component(props) {
52 + const $ = _c(3);
53 + let t0;
54 + if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
55 + t0 = {};
56 + $[0] = t0;
57 + } else {
58 + t0 = $[0];
59 + }
60 + const x = t0;
61 + let t1;
62 + if ($[1] !== props) {
63 + let y;
64 + if (props.cond) {
65 + if (props.cond2) {
66 + y = [props.value];
67 + } else {
68 + y = [props.value2];
69 + }
70 + } else {
71 + y = [];
72 + }
73 +
74 + y.push(x);
75 +
76 + t1 = [x, y];
77 + $[1] = props;
78 + $[2] = t1;
79 + } else {
80 + t1 = $[2];
81 + }
82 + return t1;
83 +}
84 +
85 +export const FIXTURE_ENTRYPOINT = {
86 + fn: Component,
87 + params: [{ cond: true, cond2: true, value: 42 }],
88 + sequentialRenders: [
89 + { cond: true, cond2: true, value: 3.14 },
90 + { cond: true, cond2: true, value: 42 },
91 + { cond: true, cond2: true, value: 3.14 },
92 + { cond: true, cond2: false, value2: 3.14 },
93 + { cond: true, cond2: false, value2: 42 },
94 + { cond: true, cond2: false, value2: 3.14 },
95 + { cond: false },
96 + { cond: false },
97 + ],
98 +};
99 +
100 +```
101 +
102 +### Eval output
103 +(kind: ok) [{},[3.14,"[[ cyclic ref *1 ]]"]]
104 +[{},[42,"[[ cyclic ref *1 ]]"]]
105 +[{},[3.14,"[[ cyclic ref *1 ]]"]]
106 +[{},[3.14,"[[ cyclic ref *1 ]]"]]
107 +[{},[42,"[[ cyclic ref *1 ]]"]]
108 +[{},[3.14,"[[ cyclic ref *1 ]]"]]
109 +[{},["[[ cyclic ref *1 ]]"]]
110 +[{},["[[ cyclic ref *1 ]]"]]
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/phi-type-inference-array-push-consecutive-phis.js new
+37
@@ -0,0 +1,37 @@
1 +import {makeArray} from 'shared-runtime';
2 +
3 +function Component(props) {
4 + const x = {};
5 + let y;
6 + if (props.cond) {
7 + if (props.cond2) {
8 + y = [props.value];
9 + } else {
10 + y = [props.value2];
11 + }
12 + } else {
13 + y = [];
14 + }
15 + // This should be inferred as `<store> y` s.t. `x` can still
16 + // be independently memoized. *But* this also must properly
17 + // extend the mutable range of the array literals in the
18 + // if/else branches
19 + y.push(x);
20 +
21 + return [x, y];
22 +}
23 +
24 +export const FIXTURE_ENTRYPOINT = {
25 + fn: Component,
26 + params: [{cond: true, cond2: true, value: 42}],
27 + sequentialRenders: [
28 + {cond: true, cond2: true, value: 3.14},
29 + {cond: true, cond2: true, value: 42},
30 + {cond: true, cond2: true, value: 3.14},
31 + {cond: true, cond2: false, value2: 3.14},
32 + {cond: true, cond2: false, value2: 42},
33 + {cond: true, cond2: false, value2: 3.14},
34 + {cond: false},
35 + {cond: false},
36 + ],
37 +};
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/phi-type-inference-array-push.expect.md new
+83
@@ -0,0 +1,83 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function Component(props) {
6 + const x = {};
7 + let y;
8 + if (props.cond) {
9 + y = [props.value];
10 + } else {
11 + y = [];
12 + }
13 + // This should be inferred as `<store> y` s.t. `x` can still
14 + // be independently memoized. *But* this also must properly
15 + // extend the mutable range of the array literals in the
16 + // if/else branches
17 + y.push(x);
18 +
19 + return [x, y];
20 +}
21 +
22 +export const FIXTURE_ENTRYPOINT = {
23 + fn: Component,
24 + params: [{cond: true, value: 42}],
25 + sequentialRenders: [
26 + {cond: true, value: 3.14},
27 + {cond: false, value: 3.14},
28 + {cond: true, value: 42},
29 + ],
30 +};
31 +
32 +```
33 +
34 +## Code
35 +
36 +```javascript
37 +import { c as _c } from "react/compiler-runtime";
38 +function Component(props) {
39 + const $ = _c(3);
40 + let t0;
41 + if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
42 + t0 = {};
43 + $[0] = t0;
44 + } else {
45 + t0 = $[0];
46 + }
47 + const x = t0;
48 + let t1;
49 + if ($[1] !== props) {
50 + let y;
51 + if (props.cond) {
52 + y = [props.value];
53 + } else {
54 + y = [];
55 + }
56 +
57 + y.push(x);
58 +
59 + t1 = [x, y];
60 + $[1] = props;
61 + $[2] = t1;
62 + } else {
63 + t1 = $[2];
64 + }
65 + return t1;
66 +}
67 +
68 +export const FIXTURE_ENTRYPOINT = {
69 + fn: Component,
70 + params: [{ cond: true, value: 42 }],
71 + sequentialRenders: [
72 + { cond: true, value: 3.14 },
73 + { cond: false, value: 3.14 },
74 + { cond: true, value: 42 },
75 + ],
76 +};
77 +
78 +```
79 +
80 +### Eval output
81 +(kind: ok) [{},[3.14,"[[ cyclic ref *1 ]]"]]
82 +[{},["[[ cyclic ref *1 ]]"]]
83 +[{},[42,"[[ cyclic ref *1 ]]"]]
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/phi-type-inference-array-push.js new
+26
@@ -0,0 +1,26 @@
1 +function Component(props) {
2 + const x = {};
3 + let y;
4 + if (props.cond) {
5 + y = [props.value];
6 + } else {
7 + y = [];
8 + }
9 + // This should be inferred as `<store> y` s.t. `x` can still
10 + // be independently memoized. *But* this also must properly
11 + // extend the mutable range of the array literals in the
12 + // if/else branches
13 + y.push(x);
14 +
15 + return [x, y];
16 +}
17 +
18 +export const FIXTURE_ENTRYPOINT = {
19 + fn: Component,
20 + params: [{cond: true, value: 42}],
21 + sequentialRenders: [
22 + {cond: true, value: 3.14},
23 + {cond: false, value: 3.14},
24 + {cond: true, value: 42},
25 + ],
26 +};
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/phi-type-inference-property-store.expect.md new
+72
@@ -0,0 +1,72 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +// @debug
6 +function Component(props) {
7 + const x = {};
8 + let y;
9 + if (props.cond) {
10 + y = {};
11 + } else {
12 + y = {a: props.a};
13 + }
14 + // This should be inferred as `<store> y` s.t. `x` can still
15 + // be independently memoized. *But* this also must properly
16 + // extend the mutable range of the object literals in the
17 + // if/else branches
18 + y.x = x;
19 +
20 + return [x, y];
21 +}
22 +
23 +export const FIXTURE_ENTRYPOINT = {
24 + fn: Component,
25 + params: [{cond: false, a: 'a!'}],
26 +};
27 +
28 +```
29 +
30 +## Code
31 +
32 +```javascript
33 +import { c as _c } from "react/compiler-runtime"; // @debug
34 +function Component(props) {
35 + const $ = _c(3);
36 + let t0;
37 + if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
38 + t0 = {};
39 + $[0] = t0;
40 + } else {
41 + t0 = $[0];
42 + }
43 + const x = t0;
44 + let t1;
45 + if ($[1] !== props) {
46 + let y;
47 + if (props.cond) {
48 + y = {};
49 + } else {
50 + y = { a: props.a };
51 + }
52 +
53 + y.x = x;
54 +
55 + t1 = [x, y];
56 + $[1] = props;
57 + $[2] = t1;
58 + } else {
59 + t1 = $[2];
60 + }
61 + return t1;
62 +}
63 +
64 +export const FIXTURE_ENTRYPOINT = {
65 + fn: Component,
66 + params: [{ cond: false, a: "a!" }],
67 +};
68 +
69 +```
70 +
71 +### Eval output
72 +(kind: ok) [{},{"a":"a!","x":"[[ cyclic ref *1 ]]"}]
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/phi-type-inference-property-store.js new
+22
@@ -0,0 +1,22 @@
1 +// @debug
2 +function Component(props) {
3 + const x = {};
4 + let y;
5 + if (props.cond) {
6 + y = {};
7 + } else {
8 + y = {a: props.a};
9 + }
10 + // This should be inferred as `<store> y` s.t. `x` can still
11 + // be independently memoized. *But* this also must properly
12 + // extend the mutable range of the object literals in the
13 + // if/else branches
14 + y.x = x;
15 +
16 + return [x, y];
17 +}
18 +
19 +export const FIXTURE_ENTRYPOINT = {
20 + fn: Component,
21 + params: [{cond: false, a: 'a!'}],
22 +};
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reactive-dependencies-non-optional-properties-inside-optional-chain.expect.md new
+31
@@ -0,0 +1,31 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function Component(props) {
6 + return props.post.feedback.comments?.edges?.map(render);
7 +}
8 +
9 +```
10 +
11 +## Code
12 +
13 +```javascript
14 +import { c as _c } from "react/compiler-runtime";
15 +function Component(props) {
16 + const $ = _c(2);
17 + let t0;
18 + if ($[0] !== props.post.feedback.comments) {
19 + t0 = props.post.feedback.comments?.edges?.map(render);
20 + $[0] = props.post.feedback.comments;
21 + $[1] = t0;
22 + } else {
23 + t0 = $[1];
24 + }
25 + return t0;
26 +}
27 +
28 +```
29 +
30 +### Eval output
31 +(kind: exception) Fixture not implemented
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reactive-dependencies-non-optional-properties-inside-optional-chain.js new
+3
@@ -0,0 +1,3 @@
1 +function Component(props) {
2 + return props.post.feedback.comments?.edges?.map(render);
3 +}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/ssa-renaming-unconditional-with-mutation.expect.md new
+79
@@ -0,0 +1,79 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +import {mutate} from 'shared-runtime';
6 +
7 +function useFoo(props) {
8 + let x = [];
9 + x.push(props.bar);
10 + if (props.cond) {
11 + x = {};
12 + x = [];
13 + x.push(props.foo);
14 + } else {
15 + x = [];
16 + x = [];
17 + x.push(props.bar);
18 + }
19 + mutate(x);
20 + return x;
21 +}
22 +
23 +export const FIXTURE_ENTRYPOINT = {
24 + fn: useFoo,
25 + params: [{bar: 'bar', foo: 'foo', cond: true}],
26 + sequentialRenders: [
27 + {bar: 'bar', foo: 'foo', cond: true},
28 + {bar: 'bar', foo: 'foo', cond: true},
29 + {bar: 'bar', foo: 'foo', cond: false},
30 + ],
31 +};
32 +
33 +```
34 +
35 +## Code
36 +
37 +```javascript
38 +import { c as _c } from "react/compiler-runtime";
39 +import { mutate } from "shared-runtime";
40 +
41 +function useFoo(props) {
42 + const $ = _c(2);
43 + let x;
44 + if ($[0] !== props) {
45 + x = [];
46 + x.push(props.bar);
47 + if (props.cond) {
48 + x = [];
49 + x.push(props.foo);
50 + } else {
51 + x = [];
52 + x.push(props.bar);
53 + }
54 +
55 + mutate(x);
56 + $[0] = props;
57 + $[1] = x;
58 + } else {
59 + x = $[1];
60 + }
61 + return x;
62 +}
63 +
64 +export const FIXTURE_ENTRYPOINT = {
65 + fn: useFoo,
66 + params: [{ bar: "bar", foo: "foo", cond: true }],
67 + sequentialRenders: [
68 + { bar: "bar", foo: "foo", cond: true },
69 + { bar: "bar", foo: "foo", cond: true },
70 + { bar: "bar", foo: "foo", cond: false },
71 + ],
72 +};
73 +
74 +```
75 +
76 +### Eval output
77 +(kind: ok) ["foo","joe"]
78 +["foo","joe"]
79 +["bar","joe"]
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/ssa-renaming-unconditional-with-mutation.js new
+27
@@ -0,0 +1,27 @@
1 +import {mutate} from 'shared-runtime';
2 +
3 +function useFoo(props) {
4 + let x = [];
5 + x.push(props.bar);
6 + if (props.cond) {
7 + x = {};
8 + x = [];
9 + x.push(props.foo);
10 + } else {
11 + x = [];
12 + x = [];
13 + x.push(props.bar);
14 + }
15 + mutate(x);
16 + return x;
17 +}
18 +
19 +export const FIXTURE_ENTRYPOINT = {
20 + fn: useFoo,
21 + params: [{bar: 'bar', foo: 'foo', cond: true}],
22 + sequentialRenders: [
23 + {bar: 'bar', foo: 'foo', cond: true},
24 + {bar: 'bar', foo: 'foo', cond: true},
25 + {bar: 'bar', foo: 'foo', cond: false},
26 + ],
27 +};
compiler/packages/snap/src/SproutTodoFilter.ts
+1
@@ -50,6 +50,7 @@ const skipFilter = new Set([
50 'component',
51 'cond-deps-conditional-member-expr',
52 'conditional-break-labeled',
53 + 'propagate-scope-deps-hir-fork/conditional-break-labeled',
54 'conditional-set-state-in-render',
55 'constant-computed',
56 'constant-propagation-phi',