[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',