@samitouri / QOS-React-2 / commits / ddf8bc3fba

[compiler] Improve merging of scopes that invalidate together (#34049)

We try to merge consecutive reactive scopes that will always invalidate together, but there's one common case that isn't handled. ```js const y = [[x]]; ``` Here we'll create two consecutive scopes for the inner and outer array expressions. Because the input to the second scope is a temporary, they'll merge into one scope. But if we name the inner array, the merging stops: ```js const array = [x]; const y = [array]; ``` This is because the merging logic checks if all the dependencies of the second scope are outputs of the first scope, but doesn't account for renaming due to LoadLocal/StoreLocal. The fix is to track these temporaries. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/34049). * __->__ #34049 * #34047 * #34044

Joseph Savona committed Aug 1, 2025 at 13:00 UTC ddf8bc3fbac7aefbf557e2e4a3e14d8de1b80872
48 files changed +401 -733
compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/MergeReactiveScopesThatInvalidateTogether.ts
+26 -4
@@ -119,6 +119,7 @@ class FindLastUsageVisitor extends ReactiveFunctionVisitor<void> {
119
120 class Transform extends ReactiveFunctionTransform<ReactiveScopeDependencies | null> {
121 lastUsage: Map<DeclarationId, InstructionId>;
122 + temporaries: Map<DeclarationId, DeclarationId> = new Map();
123
124 constructor(lastUsage: Map<DeclarationId, InstructionId>) {
125 super();
@@ -215,6 +216,12 @@ class Transform extends ReactiveFunctionTransform<ReactiveScopeDependencies | nu
216 current.lvalues.add(
217 instr.instruction.lvalue.identifier.declarationId,
218 );
219 + if (instr.instruction.value.kind === 'LoadLocal') {
220 + this.temporaries.set(
221 + instr.instruction.lvalue.identifier.declarationId,
222 + instr.instruction.value.place.identifier.declarationId,
223 + );
224 + }
225 }
226 break;
227 }
@@ -236,6 +243,13 @@ class Transform extends ReactiveFunctionTransform<ReactiveScopeDependencies | nu
243 )) {
244 current.lvalues.add(lvalue.identifier.declarationId);
245 }
246 + this.temporaries.set(
247 + instr.instruction.value.lvalue.place.identifier
248 + .declarationId,
249 + this.temporaries.get(
250 + instr.instruction.value.value.identifier.declarationId,
251 + ) ?? instr.instruction.value.value.identifier.declarationId,
252 + );
253 } else {
254 log(
255 `Reset scope @${current.block.scope.id} from StoreLocal in [${instr.instruction.id}]`,
@@ -260,7 +274,7 @@ class Transform extends ReactiveFunctionTransform<ReactiveScopeDependencies | nu
274 case 'scope': {
275 if (
276 current !== null &&
263 - canMergeScopes(current.block, instr) &&
277 + canMergeScopes(current.block, instr, this.temporaries) &&
278 areLValuesLastUsedByScope(
279 instr.scope,
280 current.lvalues,
@@ -426,6 +440,7 @@ function areLValuesLastUsedByScope(
440 function canMergeScopes(
441 current: ReactiveScopeBlock,
442 next: ReactiveScopeBlock,
443 + temporaries: Map<DeclarationId, DeclarationId>,
444 ): boolean {
445 // Don't merge scopes with reassignments
446 if (
@@ -465,11 +480,14 @@ function canMergeScopes(
480 (next.scope.dependencies.size !== 0 &&
481 [...next.scope.dependencies].every(
482 dep =>
483 + dep.path.length === 0 &&
484 isAlwaysInvalidatingType(dep.identifier.type) &&
485 Iterable_some(
486 current.scope.declarations.values(),
487 decl =>
472 - decl.identifier.declarationId === dep.identifier.declarationId,
488 + decl.identifier.declarationId === dep.identifier.declarationId ||
489 + decl.identifier.declarationId ===
490 + temporaries.get(dep.identifier.declarationId),
491 ),
492 ))
493 ) {
@@ -477,8 +495,12 @@ function canMergeScopes(
495 return true;
496 }
497 log(` cannot merge scopes:`);
480 - log(` ${printReactiveScopeSummary(current.scope)}`);
481 - log(` ${printReactiveScopeSummary(next.scope)}`);
498 + log(
499 + ` ${printReactiveScopeSummary(current.scope)} ${[...current.scope.declarations.values()].map(decl => decl.identifier.declarationId)}`,
500 + );
501 + log(
502 + ` ${printReactiveScopeSummary(next.scope)} ${[...next.scope.dependencies].map(dep => `${dep.identifier.declarationId} ${temporaries.get(dep.identifier.declarationId) ?? dep.identifier.declarationId}`)}`,
503 + );
504 return false;
505 }
506
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-at-closure.expect.md
+5 -12
@@ -19,7 +19,7 @@ function Component(props) {
19 ```javascript
20 import { c as _c } from "react/compiler-runtime";
21 function Component(props) {
22 - const $ = _c(7);
22 + const $ = _c(5);
23 let t0;
24 if ($[0] !== props.x) {
25 t0 = foo(props.x);
@@ -31,26 +31,19 @@ function Component(props) {
31 const x = t0;
32 let t1;
33 if ($[2] !== props || $[3] !== x) {
34 - t1 = function () {
34 + const fn = function () {
35 const arr = [...bar(props)];
36 return arr.at(x);
37 };
38 +
39 + t1 = fn();
40 $[2] = props;
41 $[3] = x;
42 $[4] = t1;
43 } else {
44 t1 = $[4];
45 }
44 - const fn = t1;
45 - let t2;
46 - if ($[5] !== fn) {
47 - t2 = fn();
48 - $[5] = fn;
49 - $[6] = t2;
50 - } else {
51 - t2 = $[6];
52 - }
53 - const fnResult = t2;
46 + const fnResult = t1;
47 return fnResult;
48 }
49
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-map-captures-receiver-noAlias.expect.md
+5 -21
@@ -23,34 +23,18 @@ export const FIXTURE_ENTRYPOINT = {
23 ```javascript
24 import { c as _c } from "react/compiler-runtime";
25 function Component(props) {
26 - const $ = _c(6);
26 + const $ = _c(2);
27 let t0;
28 if ($[0] !== props.a) {
29 - t0 = { a: props.a };
29 + const item = { a: props.a };
30 + const items = [item];
31 + t0 = items.map(_temp);
32 $[0] = props.a;
33 $[1] = t0;
34 } else {
35 t0 = $[1];
36 }
35 - const item = t0;
36 - let t1;
37 - if ($[2] !== item) {
38 - t1 = [item];
39 - $[2] = item;
40 - $[3] = t1;
41 - } else {
42 - t1 = $[3];
43 - }
44 - const items = t1;
45 - let t2;
46 - if ($[4] !== items) {
47 - t2 = items.map(_temp);
48 - $[4] = items;
49 - $[5] = t2;
50 - } else {
51 - t2 = $[5];
52 - }
53 - const mapped = t2;
37 + const mapped = t0;
38 return mapped;
39 }
40 function _temp(item_0) {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-map-noAlias-escaping-function.expect.md
+4 -12
@@ -21,26 +21,18 @@ export const FIXTURE_ENTRYPOINT = {
21 ```javascript
22 import { c as _c } from "react/compiler-runtime";
23 function Component(props) {
24 - const $ = _c(4);
24 + const $ = _c(2);
25 const f = _temp;
26 let t0;
27 if ($[0] !== props.items) {
28 - t0 = [...props.items].map(f);
28 + const x = [...props.items].map(f);
29 + t0 = [x, f];
30 $[0] = props.items;
31 $[1] = t0;
32 } else {
33 t0 = $[1];
34 }
34 - const x = t0;
35 - let t1;
36 - if ($[2] !== x) {
37 - t1 = [x, f];
38 - $[2] = x;
39 - $[3] = t1;
40 - } else {
41 - t1 = $[3];
42 - }
43 - return t1;
35 + return t0;
36 }
37 function _temp(item) {
38 return item;
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-arrow-function-1.expect.md
+6 -14
@@ -23,27 +23,19 @@ export const FIXTURE_ENTRYPOINT = {
23 ```javascript
24 import { c as _c } from "react/compiler-runtime";
25 function component(a) {
26 - const $ = _c(4);
26 + const $ = _c(2);
27 let t0;
28 if ($[0] !== a) {
29 - t0 = { a };
29 + const z = { a };
30 + t0 = () => {
31 + console.log(z);
32 + };
33 $[0] = a;
34 $[1] = t0;
35 } else {
36 t0 = $[1];
37 }
35 - const z = t0;
36 - let t1;
37 - if ($[2] !== z) {
38 - t1 = () => {
39 - console.log(z);
40 - };
41 - $[2] = z;
42 - $[3] = t1;
43 - } else {
44 - t1 = $[3];
45 - }
46 - const x = t1;
38 + const x = t0;
39 return x;
40 }
41
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-function-1.expect.md
+6 -14
@@ -23,27 +23,19 @@ export const FIXTURE_ENTRYPOINT = {
23 ```javascript
24 import { c as _c } from "react/compiler-runtime";
25 function component(a) {
26 - const $ = _c(4);
26 + const $ = _c(2);
27 let t0;
28 if ($[0] !== a) {
29 - t0 = { a };
29 + const z = { a };
30 + t0 = function () {
31 + console.log(z);
32 + };
33 $[0] = a;
34 $[1] = t0;
35 } else {
36 t0 = $[1];
37 }
35 - const z = t0;
36 - let t1;
37 - if ($[2] !== z) {
38 - t1 = function () {
39 - console.log(z);
40 - };
41 - $[2] = z;
42 - $[3] = t1;
43 - } else {
44 - t1 = $[3];
45 - }
46 - const x = t1;
38 + const x = t0;
39 return x;
40 }
41
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-function-runs-inference.expect.md
+5 -21
@@ -22,35 +22,19 @@ export const FIXTURE_ENTRYPOINT = {
22 import { c as _c } from "react/compiler-runtime";
23 import { Stringify } from "shared-runtime";
24 function Component(t0) {
25 - const $ = _c(6);
25 + const $ = _c(2);
26 const { a } = t0;
27 let t1;
28 if ($[0] !== a) {
29 - t1 = { a };
29 + const z = { a };
30 + const p = () => <Stringify>{z}</Stringify>;
31 + t1 = p();
32 $[0] = a;
33 $[1] = t1;
34 } else {
35 t1 = $[1];
36 }
35 - const z = t1;
36 - let t2;
37 - if ($[2] !== z) {
38 - t2 = () => <Stringify>{z}</Stringify>;
39 - $[2] = z;
40 - $[3] = t2;
41 - } else {
42 - t2 = $[3];
43 - }
44 - const p = t2;
45 - let t3;
46 - if ($[4] !== p) {
47 - t3 = p();
48 - $[4] = p;
49 - $[5] = t3;
50 - } else {
51 - t3 = $[5];
52 - }
53 - return t3;
37 + return t1;
38 }
39
40 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-variable-in-nested-block.expect.md
+6 -14
@@ -25,27 +25,19 @@ export const FIXTURE_ENTRYPOINT = {
25 ```javascript
26 import { c as _c } from "react/compiler-runtime";
27 function component(a) {
28 - const $ = _c(4);
28 + const $ = _c(2);
29 let t0;
30 if ($[0] !== a) {
31 - t0 = { a };
31 + const z = { a };
32 + t0 = function () {
33 + console.log(z);
34 + };
35 $[0] = a;
36 $[1] = t0;
37 } else {
38 t0 = $[1];
39 }
37 - const z = t0;
38 - let t1;
39 - if ($[2] !== z) {
40 - t1 = function () {
41 - console.log(z);
42 - };
43 - $[2] = z;
44 - $[3] = t1;
45 - } else {
46 - t1 = $[3];
47 - }
48 - const x = t1;
40 + const x = t0;
41 return x;
42 }
43
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-variable-in-nested-function.expect.md
+7 -15
@@ -25,29 +25,21 @@ export const FIXTURE_ENTRYPOINT = {
25 ```javascript
26 import { c as _c } from "react/compiler-runtime";
27 function component(a) {
28 - const $ = _c(4);
28 + const $ = _c(2);
29 let t0;
30 if ($[0] !== a) {
31 - t0 = { a };
32 - $[0] = a;
33 - $[1] = t0;
34 - } else {
35 - t0 = $[1];
36 - }
37 - const z = t0;
38 - let t1;
39 - if ($[2] !== z) {
40 - t1 = function () {
31 + const z = { a };
32 + t0 = function () {
33 (function () {
34 console.log(z);
35 })();
36 };
45 - $[2] = z;
46 - $[3] = t1;
37 + $[0] = a;
38 + $[1] = t0;
39 } else {
48 - t1 = $[3];
40 + t0 = $[1];
41 }
50 - const x = t1;
42 + const x = t0;
43 return x;
44 }
45
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/escape-analysis-non-escaping-interleaved-allocating-nested-dependency.expect.md
+10 -17
@@ -40,36 +40,29 @@ export const FIXTURE_ENTRYPOINT = {
40 ```javascript
41 import { c as _c } from "react/compiler-runtime";
42 function Component(props) {
43 - const $ = _c(7);
43 + const $ = _c(5);
44 let t0;
45 if ($[0] !== props.a) {
46 - t0 = [props.a];
46 + const a = [props.a];
47 +
48 + t0 = [a];
49 $[0] = props.a;
50 $[1] = t0;
51 } else {
52 t0 = $[1];
53 }
52 - const a = t0;
53 - let t1;
54 - if ($[2] !== a) {
55 - t1 = [a];
56 - $[2] = a;
57 - $[3] = t1;
58 - } else {
59 - t1 = $[3];
60 - }
61 - const b = t1;
54 + const b = t0;
55 let c;
63 - if ($[4] !== b || $[5] !== props.b) {
56 + if ($[2] !== b || $[3] !== props.b) {
57 c = [];
58 const d = {};
59 d.b = b;
60 c.push(props.b);
68 - $[4] = b;
69 - $[5] = props.b;
70 - $[6] = c;
61 + $[2] = b;
62 + $[3] = props.b;
63 + $[4] = c;
64 } else {
72 - c = $[6];
65 + c = $[4];
66 }
67 return c;
68 }
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbt-param-with-newline.expect.md
+5 -12
@@ -32,10 +32,10 @@ import { c as _c } from "react/compiler-runtime";
32 import fbt from "fbt";
33
34 function Component(props) {
35 - const $ = _c(4);
35 + const $ = _c(2);
36 let t0;
37 if ($[0] !== props.name) {
38 - t0 = fbt._(
38 + const element = fbt._(
39 "Hello {a really long description that got split into multiple lines}",
40 [
41 fbt._param(
@@ -46,21 +46,14 @@ function Component(props) {
46 ],
47 { hk: "1euPUp" },
48 );
49 +
50 + t0 = element.toString();
51 $[0] = props.name;
52 $[1] = t0;
53 } else {
54 t0 = $[1];
55 }
54 - const element = t0;
55 - let t1;
56 - if ($[2] !== element) {
57 - t1 = element.toString();
58 - $[2] = element;
59 - $[3] = t1;
60 - } else {
61 - t1 = $[3];
62 - }
63 - return t1;
56 + return t0;
57 }
58
59 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbt-param-with-quotes.expect.md
+15 -14
@@ -27,27 +27,28 @@ import { c as _c } from "react/compiler-runtime";
27 import fbt from "fbt";
28
29 function Component(props) {
30 - const $ = _c(4);
30 + const $ = _c(2);
31 let t0;
32 if ($[0] !== props.name) {
33 - t0 = fbt._('Hello {"user" name}', [fbt._param('"user" name', props.name)], {
34 - hk: "S0vMe",
35 - });
33 + const element = fbt._(
34 + 'Hello {"user" name}',
35 + [
36 + fbt._param(
37 + '"user" name',
38 +
39 + props.name,
40 + ),
41 + ],
42 + { hk: "S0vMe" },
43 + );
44 +
45 + t0 = element.toString();
46 $[0] = props.name;
47 $[1] = t0;
48 } else {
49 t0 = $[1];
50 }
41 - const element = t0;
42 - let t1;
43 - if ($[2] !== element) {
44 - t1 = element.toString();
45 - $[2] = element;
46 - $[3] = t1;
47 - } else {
48 - t1 = $[3];
49 - }
50 - return t1;
51 + return t0;
52 }
53
54 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbt-param-with-unicode.expect.md
+12 -13
@@ -27,29 +27,28 @@ import { c as _c } from "react/compiler-runtime";
27 import fbt from "fbt";
28
29 function Component(props) {
30 - const $ = _c(4);
30 + const $ = _c(2);
31 let t0;
32 if ($[0] !== props.name) {
33 - t0 = fbt._(
33 + const element = fbt._(
34 "Hello {user name ☺}",
35 - [fbt._param("user name \u263A", props.name)],
35 + [
36 + fbt._param(
37 + "user name \u263A",
38 +
39 + props.name,
40 + ),
41 + ],
42 { hk: "1En1lp" },
43 );
44 +
45 + t0 = element.toString();
46 $[0] = props.name;
47 $[1] = t0;
48 } else {
49 t0 = $[1];
50 }
43 - const element = t0;
44 - let t1;
45 - if ($[2] !== element) {
46 - t1 = element.toString();
47 - $[2] = element;
48 - $[3] = t1;
49 - } else {
50 - t1 = $[3];
51 - }
52 - return t1;
51 + return t0;
52 }
53
54 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbt-to-string.expect.md
+15 -14
@@ -27,27 +27,28 @@ import { c as _c } from "react/compiler-runtime";
27 import fbt from "fbt";
28
29 function Component(props) {
30 - const $ = _c(4);
30 + const $ = _c(2);
31 let t0;
32 if ($[0] !== props.name) {
33 - t0 = fbt._("Hello {user name}", [fbt._param("user name", props.name)], {
34 - hk: "2zEDKF",
35 - });
33 + const element = fbt._(
34 + "Hello {user name}",
35 + [
36 + fbt._param(
37 + "user name",
38 +
39 + props.name,
40 + ),
41 + ],
42 + { hk: "2zEDKF" },
43 + );
44 +
45 + t0 = element.toString();
46 $[0] = props.name;
47 $[1] = t0;
48 } else {
49 t0 = $[1];
50 }
41 - const element = t0;
42 - let t1;
43 - if ($[2] !== element) {
44 - t1 = element.toString();
45 - $[2] = element;
46 - $[3] = t1;
47 - } else {
48 - t1 = $[3];
49 - }
50 - return t1;
51 + return t0;
52 }
53
54 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/function-expression-maybe-mutates-hook-return-value.expect.md
+5 -12
@@ -22,28 +22,21 @@ function Component(props) {
22 ```javascript
23 import { c as _c } from "react/compiler-runtime";
24 function Component(props) {
25 - const $ = _c(4);
25 + const $ = _c(2);
26 const id = useSelectedEntitytId();
27 let t0;
28 if ($[0] !== id) {
29 - t0 = () => {
29 + const onLoad = () => {
30 log(id);
31 };
32 +
33 + t0 = <Foo onLoad={onLoad} />;
34 $[0] = id;
35 $[1] = t0;
36 } else {
37 t0 = $[1];
38 }
37 - const onLoad = t0;
38 - let t1;
39 - if ($[2] !== onLoad) {
40 - t1 = <Foo onLoad={onLoad} />;
41 - $[2] = onLoad;
42 - $[3] = t1;
43 - } else {
44 - t1 = $[3];
45 - }
46 - return t1;
39 + return t0;
40 }
41
42 ```
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/function-expression-prototype-call.expect.md
+5 -12
@@ -21,27 +21,20 @@ export const FIXTURE_ENTRYPOINT = {
21 ```javascript
22 import { c as _c } from "react/compiler-runtime";
23 function Component(props) {
24 - const $ = _c(4);
24 + const $ = _c(2);
25 let t0;
26 if ($[0] !== props) {
27 - t0 = function () {
27 + const f = function () {
28 return <div>{props.name}</div>;
29 };
30 +
31 + t0 = f.call();
32 $[0] = props;
33 $[1] = t0;
34 } else {
35 t0 = $[1];
36 }
35 - const f = t0;
36 - let t1;
37 - if ($[2] !== f) {
38 - t1 = f.call();
39 - $[2] = f;
40 - $[3] = t1;
41 - } else {
42 - t1 = $[3];
43 - }
44 - return t1;
37 + return t0;
38 }
39
40 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-functionexpr-conditional-dep.expect.md
+5 -12
@@ -55,33 +55,26 @@ import { Stringify } from "shared-runtime";
55 * (kind: exception) Cannot read properties of null (reading 'prop')
56 */
57 function Component(t0) {
58 - const $ = _c(5);
58 + const $ = _c(3);
59 const { obj, isObjNull } = t0;
60 let t1;
61 if ($[0] !== isObjNull || $[1] !== obj) {
62 - t1 = () => {
62 + const callback = () => {
63 if (!isObjNull) {
64 return obj.prop;
65 } else {
66 return null;
67 }
68 };
69 +
70 + t1 = <Stringify shouldInvokeFns={true} callback={callback} />;
71 $[0] = isObjNull;
72 $[1] = obj;
73 $[2] = t1;
74 } else {
75 t1 = $[2];
76 }
75 - const callback = t1;
76 - let t2;
77 - if ($[3] !== callback) {
78 - t2 = <Stringify shouldInvokeFns={true} callback={callback} />;
79 - $[3] = callback;
80 - $[4] = t2;
81 - } else {
82 - t2 = $[4];
83 - }
84 - return t2;
77 + return t1;
78 }
79
80 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-setstate-captured-indirectly-jsx.expect.md
+11 -18
@@ -27,7 +27,7 @@ function useFoo() {
27 ```javascript
28 import { c as _c } from "react/compiler-runtime"; // @validatePreserveExistingMemoizationGuarantees
29 function useFoo() {
30 - const $ = _c(9);
30 + const $ = _c(7);
31 const onClick = (response) => {
32 setState(DISABLED_FORM);
33 };
@@ -48,31 +48,24 @@ function useFoo() {
48 const handleLogout = t1;
49 let t2;
50 if ($[2] !== handleLogout) {
51 - t2 = () => <ColumnItem onPress={() => handleLogout()} />;
51 + const getComponent = () => <ColumnItem onPress={() => handleLogout()} />;
52 +
53 + t2 = getComponent();
54 $[2] = handleLogout;
55 $[3] = t2;
56 } else {
57 t2 = $[3];
58 }
57 - const getComponent = t2;
59 let t3;
59 - if ($[4] !== getComponent) {
60 - t3 = getComponent();
61 - $[4] = getComponent;
62 - $[5] = t3;
63 - } else {
64 - t3 = $[5];
65 - }
66 - let t4;
67 - if ($[6] !== onClick || $[7] !== t3) {
68 - t4 = [t3, onClick];
69 - $[6] = onClick;
70 - $[7] = t3;
71 - $[8] = t4;
60 + if ($[4] !== onClick || $[5] !== t2) {
61 + t3 = [t2, onClick];
62 + $[4] = onClick;
63 + $[5] = t2;
64 + $[6] = t3;
65 } else {
73 - t4 = $[8];
66 + t3 = $[6];
67 }
75 - return t4;
68 + return t3;
69 }
70
71 ```
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-function/nullable-objects/array-map-named-chained-callbacks.expect.md
+30 -46
@@ -42,74 +42,58 @@ import { c as _c } from "react/compiler-runtime"; /**
42 * conservative and assume that all named lambdas are conditionally called.
43 */
44 function useFoo(t0) {
45 - const $ = _c(17);
45 + const $ = _c(13);
46 const { arr1, arr2 } = t0;
47 let t1;
48 if ($[0] !== arr1[0]) {
49 - t1 = () => arr1[0].value;
49 + const getVal1 = () => arr1[0].value;
50 + t1 = (e) => getVal1() + e.value;
51 $[0] = arr1[0];
52 $[1] = t1;
53 } else {
54 t1 = $[1];
55 }
55 - const getVal1 = t1;
56 + const cb1 = t1;
57 let t2;
57 - if ($[2] !== getVal1) {
58 - t2 = (e) => getVal1() + e.value;
59 - $[2] = getVal1;
60 - $[3] = t2;
58 + if ($[2] !== arr1 || $[3] !== cb1) {
59 + t2 = arr1.map(cb1);
60 + $[2] = arr1;
61 + $[3] = cb1;
62 + $[4] = t2;
63 } else {
62 - t2 = $[3];
64 + t2 = $[4];
65 }
64 - const cb1 = t2;
66 + const x = t2;
67 let t3;
66 - if ($[4] !== arr1 || $[5] !== cb1) {
67 - t3 = arr1.map(cb1);
68 - $[4] = arr1;
69 - $[5] = cb1;
68 + if ($[5] !== arr2) {
69 + const getVal2 = () => arr2[0].value;
70 + t3 = (e_0) => getVal2() + e_0.value;
71 + $[5] = arr2;
72 $[6] = t3;
73 } else {
74 t3 = $[6];
75 }
74 - const x = t3;
76 + const cb2 = t3;
77 let t4;
76 - if ($[7] !== arr2) {
77 - t4 = () => arr2[0].value;
78 - $[7] = arr2;
79 - $[8] = t4;
78 + if ($[7] !== arr1 || $[8] !== cb2) {
79 + t4 = arr1.map(cb2);
80 + $[7] = arr1;
81 + $[8] = cb2;
82 + $[9] = t4;
83 } else {
81 - t4 = $[8];
84 + t4 = $[9];
85 }
83 - const getVal2 = t4;
86 + const y = t4;
87 let t5;
85 - if ($[9] !== getVal2) {
86 - t5 = (e_0) => getVal2() + e_0.value;
87 - $[9] = getVal2;
88 - $[10] = t5;
88 + if ($[10] !== x || $[11] !== y) {
89 + t5 = [x, y];
90 + $[10] = x;
91 + $[11] = y;
92 + $[12] = t5;
93 } else {
90 - t5 = $[10];
94 + t5 = $[12];
95 }
92 - const cb2 = t5;
93 - let t6;
94 - if ($[11] !== arr1 || $[12] !== cb2) {
95 - t6 = arr1.map(cb2);
96 - $[11] = arr1;
97 - $[12] = cb2;
98 - $[13] = t6;
99 - } else {
100 - t6 = $[13];
101 - }
102 - const y = t6;
103 - let t7;
104 - if ($[14] !== x || $[15] !== y) {
105 - t7 = [x, y];
106 - $[14] = x;
107 - $[15] = y;
108 - $[16] = t7;
109 - } else {
110 - t7 = $[16];
111 - }
112 - return t7;
96 + return t5;
97 }
98
99 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-function/nullable-objects/assume-invoked/conditional-call-chain.expect.md
+5 -12
@@ -42,7 +42,7 @@ import { useRef } from "react";
42 import { Stringify } from "shared-runtime";
43
44 function Component(t0) {
45 - const $ = _c(9);
45 + const $ = _c(7);
46 const { a, b } = t0;
47 let t1;
48 if ($[0] !== a.value) {
@@ -70,29 +70,22 @@ function Component(t0) {
70 const hasLogged = useRef(false);
71 let t3;
72 if ($[4] !== logA || $[5] !== logB) {
73 - t3 = () => {
73 + const log = () => {
74 if (!hasLogged.current) {
75 logA();
76 logB();
77 hasLogged.current = true;
78 }
79 };
80 +
81 + t3 = <Stringify log={log} shouldInvokeFns={true} />;
82 $[4] = logA;
83 $[5] = logB;
84 $[6] = t3;
85 } else {
86 t3 = $[6];
87 }
86 - const log = t3;
87 - let t4;
88 - if ($[7] !== log) {
89 - t4 = <Stringify log={log} shouldInvokeFns={true} />;
90 - $[7] = log;
91 - $[8] = t4;
92 - } else {
93 - t4 = $[8];
94 - }
95 - return t4;
88 + return t3;
89 }
90
91 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-lowercase-localvar-memberexpr-in-lambda.expect.md
+4 -12
@@ -24,28 +24,20 @@ import { c as _c } from "react/compiler-runtime";
24 import * as SharedRuntime from "shared-runtime";
25 import { invoke } from "shared-runtime";
26 function useComponentFactory(t0) {
27 - const $ = _c(4);
27 + const $ = _c(2);
28 const { name } = t0;
29 let t1;
30 if ($[0] !== name) {
31 - t1 = () => (
31 + const cb = () => (
32 <SharedRuntime.Stringify>hello world {name}</SharedRuntime.Stringify>
33 );
34 + t1 = invoke(cb);
35 $[0] = name;
36 $[1] = t1;
37 } else {
38 t1 = $[1];
39 }
39 - const cb = t1;
40 - let t2;
41 - if ($[2] !== cb) {
42 - t2 = invoke(cb);
43 - $[2] = cb;
44 - $[3] = t2;
45 - } else {
46 - t2 = $[3];
47 - }
48 - return t2;
40 + return t1;
41 }
42
43 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/array-map-captures-receiver-noAlias.expect.md
+5 -21
@@ -25,34 +25,18 @@ export const FIXTURE_ENTRYPOINT = {
25 ```javascript
26 import { c as _c } from "react/compiler-runtime"; // @enableNewMutationAliasingModel
27 function Component(props) {
28 - const $ = _c(6);
28 + const $ = _c(2);
29 let t0;
30 if ($[0] !== props.a) {
31 - t0 = { a: props.a };
31 + const item = { a: props.a };
32 + const items = [item];
33 + t0 = items.map(_temp);
34 $[0] = props.a;
35 $[1] = t0;
36 } else {
37 t0 = $[1];
38 }
37 - const item = t0;
38 - let t1;
39 - if ($[2] !== item) {
40 - t1 = [item];
41 - $[2] = item;
42 - $[3] = t1;
43 - } else {
44 - t1 = $[3];
45 - }
46 - const items = t1;
47 - let t2;
48 - if ($[4] !== items) {
49 - t2 = items.map(_temp);
50 - $[4] = items;
51 - $[5] = t2;
52 - } else {
53 - t2 = $[5];
54 - }
55 - const mapped = t2;
39 + const mapped = t0;
40 return mapped;
41 }
42 function _temp(item_0) {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/prop-capturing-function-1.expect.md
+6 -14
@@ -23,28 +23,20 @@ export const FIXTURE_ENTRYPOINT = {
23 ```javascript
24 import { c as _c } from "react/compiler-runtime";
25 function component(a, b) {
26 - const $ = _c(5);
26 + const $ = _c(3);
27 let t0;
28 if ($[0] !== a || $[1] !== b) {
29 - t0 = { a, b };
29 + const z = { a, b };
30 + t0 = function () {
31 + console.log(z);
32 + };
33 $[0] = a;
34 $[1] = b;
35 $[2] = t0;
36 } else {
37 t0 = $[2];
38 }
36 - const z = t0;
37 - let t1;
38 - if ($[3] !== z) {
39 - t1 = function () {
40 - console.log(z);
41 - };
42 - $[3] = z;
43 - $[4] = t1;
44 - } else {
45 - t1 = $[4];
46 - }
47 - const x = t1;
39 + const x = t0;
40 return x;
41 }
42
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-function-uncond-access-local-var.expect.md
+4 -12
@@ -29,7 +29,7 @@ import { c as _c } from "react/compiler-runtime"; // @enablePropagateDepsInHIR
29 import { mutate, shallowCopy, Stringify } from "shared-runtime";
30
31 function useFoo(t0) {
32 - const $ = _c(6);
32 + const $ = _c(4);
33 const { a } = t0;
34 let local;
35 if ($[0] !== a) {
@@ -42,22 +42,14 @@ function useFoo(t0) {
42 }
43 let t1;
44 if ($[2] !== local.b.c) {
45 - t1 = () => local.b.c;
45 + const fn = () => local.b.c;
46 + t1 = <Stringify fn={fn} shouldInvokeFns={true} />;
47 $[2] = local.b.c;
48 $[3] = t1;
49 } else {
50 t1 = $[3];
51 }
51 - const fn = t1;
52 - let t2;
53 - if ($[4] !== fn) {
54 - t2 = <Stringify fn={fn} shouldInvokeFns={true} />;
55 - $[4] = fn;
56 - $[5] = t2;
57 - } else {
58 - t2 = $[5];
59 - }
60 - return t2;
52 + return t1;
53 }
54
55 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-nested-function-uncond-access-local-var.expect.md
+4 -12
@@ -29,7 +29,7 @@ import { c as _c } from "react/compiler-runtime"; // @enablePropagateDepsInHIR
29 import { shallowCopy, Stringify, mutate } from "shared-runtime";
30
31 function useFoo(t0) {
32 - const $ = _c(6);
32 + const $ = _c(4);
33 const { a } = t0;
34 let local;
35 if ($[0] !== a) {
@@ -42,22 +42,14 @@ function useFoo(t0) {
42 }
43 let t1;
44 if ($[2] !== local) {
45 - t1 = () => [() => local.b.c];
45 + const fn = () => [() => local.b.c];
46 + t1 = <Stringify fn={fn} shouldInvokeFns={true} />;
47 $[2] = local;
48 $[3] = t1;
49 } else {
50 t1 = $[3];
51 }
51 - const fn = t1;
52 - let t2;
53 - if ($[4] !== fn) {
54 - t2 = <Stringify fn={fn} shouldInvokeFns={true} />;
55 - $[4] = fn;
56 - $[5] = t2;
57 - } else {
58 - t2 = $[5];
59 - }
60 - return t2;
52 + return t1;
53 }
54
55 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-nested-function-uncond-access.expect.md
+5 -12
@@ -31,26 +31,19 @@ import { c as _c } from "react/compiler-runtime"; // @enablePropagateDepsInHIR
31 import { Stringify } from "shared-runtime";
32
33 function useFoo(t0) {
34 - const $ = _c(4);
34 + const $ = _c(2);
35 const { a } = t0;
36 let t1;
37 if ($[0] !== a.b.c) {
38 - t1 = () => () => ({ value: a.b.c });
38 + const fn = () => () => ({ value: a.b.c });
39 +
40 + t1 = <Stringify fn={fn} shouldInvokeFns={true} />;
41 $[0] = a.b.c;
42 $[1] = t1;
43 } else {
44 t1 = $[1];
45 }
44 - const fn = t1;
45 - let t2;
46 - if ($[2] !== fn) {
47 - t2 = <Stringify fn={fn} shouldInvokeFns={true} />;
48 - $[2] = fn;
49 - $[3] = t2;
50 - } else {
51 - t2 = $[3];
52 - }
53 - return t2;
46 + return t1;
47 }
48
49 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-object-method-uncond-access.expect.md
+5 -12
@@ -31,30 +31,23 @@ import { c as _c } from "react/compiler-runtime"; // @enablePropagateDepsInHIR
31 import { identity, Stringify } from "shared-runtime";
32
33 function useFoo(t0) {
34 - const $ = _c(4);
34 + const $ = _c(2);
35 const { a } = t0;
36 let t1;
37 if ($[0] !== a) {
38 - t1 = {
38 + const x = {
39 fn() {
40 return identity(a.b.c);
41 },
42 };
43 +
44 + t1 = <Stringify x={x} shouldInvokeFns={true} />;
45 $[0] = a;
46 $[1] = t1;
47 } else {
48 t1 = $[1];
49 }
48 - const x = t1;
49 - let t2;
50 - if ($[2] !== x) {
51 - t2 = <Stringify x={x} shouldInvokeFns={true} />;
52 - $[2] = x;
53 - $[3] = t2;
54 - } else {
55 - t2 = $[3];
56 - }
57 - return t2;
50 + return t1;
51 }
52
53 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/prune-scopes-whose-deps-invalidate-jsx.expect.md
+5 -12
@@ -29,7 +29,7 @@ import { c as _c } from "react/compiler-runtime";
29 import { useHook } from "shared-runtime";
30
31 function Component(props) {
32 - const $ = _c(6);
32 + const $ = _c(4);
33 const o = {};
34 let t0;
35 if ($[0] !== props.value) {
@@ -44,22 +44,15 @@ function Component(props) {
44 o.value = props.value;
45 let t1;
46 if ($[2] !== x) {
47 - t1 = <div>{x}</div>;
47 + const y = <div>{x}</div>;
48 +
49 + t1 = <div>{y}</div>;
50 $[2] = x;
51 $[3] = t1;
52 } else {
53 t1 = $[3];
54 }
53 - const y = t1;
54 - let t2;
55 - if ($[4] !== y) {
56 - t2 = <div>{y}</div>;
57 - $[4] = y;
58 - $[5] = t2;
59 - } else {
60 - t2 = $[5];
61 - }
62 - return t2;
55 + return t1;
56 }
57
58 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/prune-scopes-whose-deps-may-invalidate-array.expect.md
+5 -12
@@ -31,7 +31,7 @@ import { c as _c } from "react/compiler-runtime";
31 import { useHook, identity } from "shared-runtime";
32
33 function Component(props) {
34 - const $ = _c(4);
34 + const $ = _c(2);
35 let x = 42;
36 if (props.cond) {
37 x = [];
@@ -41,22 +41,15 @@ function Component(props) {
41 identity(x);
42 let t0;
43 if ($[0] !== x) {
44 - t0 = [x];
44 + const y = [x];
45 +
46 + t0 = [y];
47 $[0] = x;
48 $[1] = t0;
49 } else {
50 t0 = $[1];
51 }
50 - const y = t0;
51 - let t1;
52 - if ($[2] !== y) {
53 - t1 = [y];
54 - $[2] = y;
55 - $[3] = t1;
56 - } else {
57 - t1 = $[3];
58 - }
59 - return t1;
52 + return t0;
53 }
54
55 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-ref-param.expect.md
+4 -12
@@ -66,25 +66,17 @@ function Parent(t0) {
66 }
67
68 function ChildImpl(_props, ref) {
69 - const $ = _c(4);
69 + const $ = _c(2);
70 let t0;
71 if ($[0] !== ref) {
72 - t0 = () => ref.current;
72 + const cb = () => ref.current;
73 + t0 = <Stringify cb={cb} shouldInvokeFns={true} />;
74 $[0] = ref;
75 $[1] = t0;
76 } else {
77 t0 = $[1];
78 }
78 - const cb = t0;
79 - let t1;
80 - if ($[2] !== cb) {
81 - t1 = <Stringify cb={cb} shouldInvokeFns={true} />;
82 - $[2] = cb;
83 - $[3] = t1;
84 - } else {
85 - t1 = $[3];
86 - }
87 - return t1;
79 + return t0;
80 }
81
82 const Child = forwardRef(ChildImpl);
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-ref.expect.md
+4 -12
@@ -41,29 +41,21 @@ import { Stringify } from "shared-runtime";
41 * `pruneNonReactiveDependencies`
42 */
43 function Component(t0) {
44 - const $ = _c(4);
44 + const $ = _c(2);
45 const { cond } = t0;
46 const ref1 = useRef(1);
47 const ref2 = useRef(2);
48 const ref = cond ? ref1 : ref2;
49 let t1;
50 if ($[0] !== ref) {
51 - t1 = () => ref.current;
51 + const cb = () => ref.current;
52 + t1 = <Stringify cb={cb} shouldInvokeFns={true} />;
53 $[0] = ref;
54 $[1] = t1;
55 } else {
56 t1 = $[1];
57 }
57 - const cb = t1;
58 - let t2;
59 - if ($[2] !== cb) {
60 - t2 = <Stringify cb={cb} shouldInvokeFns={true} />;
61 - $[2] = cb;
62 - $[3] = t2;
63 - } else {
64 - t2 = $[3];
65 - }
66 - return t2;
58 + return t1;
59 }
60
61 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactivity-analysis-interleaved-reactivity.expect.md
+8 -19
@@ -35,34 +35,23 @@ export const FIXTURE_ENTRYPOINT = {
35 ```javascript
36 import { c as _c } from "react/compiler-runtime";
37 function Component(props) {
38 - const $ = _c(6);
39 - let a;
38 + const $ = _c(2);
39 let t0;
40 if ($[0] !== props.b) {
42 - a = {};
41 + const a = {};
42 const b = [];
43 b.push(props.b);
44 a.a = null;
45
47 - t0 = [a];
46 + const c = [a];
47 +
48 + t0 = [c, a];
49 $[0] = props.b;
49 - $[1] = a;
50 - $[2] = t0;
51 - } else {
52 - a = $[1];
53 - t0 = $[2];
54 - }
55 - const c = t0;
56 - let t1;
57 - if ($[3] !== a || $[4] !== c) {
58 - t1 = [c, a];
59 - $[3] = a;
60 - $[4] = c;
61 - $[5] = t1;
50 + $[1] = t0;
51 } else {
63 - t1 = $[5];
52 + t0 = $[1];
53 }
65 - return t1;
54 + return t0;
55 }
56
57 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactivity-via-aliased-mutation-array.expect.md
+13 -7
@@ -32,18 +32,24 @@ export const FIXTURE_ENTRYPOINT = {
32 ```javascript
33 import { c as _c } from "react/compiler-runtime";
34 function Component(props) {
35 - const $ = _c(2);
36 - let t0;
35 + const $ = _c(4);
36 + let x;
37 if ($[0] !== props.input) {
38 - const x = [];
38 + x = [];
39 const y = x;
40 y.push(props.input);
41 -
42 - t0 = [x[0]];
41 $[0] = props.input;
44 - $[1] = t0;
42 + $[1] = x;
43 + } else {
44 + x = $[1];
45 + }
46 + let t0;
47 + if ($[2] !== x[0]) {
48 + t0 = [x[0]];
49 + $[2] = x[0];
50 + $[3] = t0;
51 } else {
46 - t0 = $[1];
52 + t0 = $[3];
53 }
54 return t0;
55 }
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactivity-via-aliased-mutation-lambda.expect.md
+13 -7
@@ -35,22 +35,28 @@ export const FIXTURE_ENTRYPOINT = {
35 ```javascript
36 import { c as _c } from "react/compiler-runtime";
37 function Component(props) {
38 - const $ = _c(2);
39 - let t0;
38 + const $ = _c(4);
39 + let x;
40 if ($[0] !== props.input) {
41 - const x = [];
41 + x = [];
42 const f = (arg) => {
43 const y = x;
44 y.push(arg);
45 };
46
47 f(props.input);
48 -
49 - t0 = [x[0]];
48 $[0] = props.input;
51 - $[1] = t0;
49 + $[1] = x;
50 + } else {
51 + x = $[1];
52 + }
53 + let t0;
54 + if ($[2] !== x[0]) {
55 + t0 = [x[0]];
56 + $[2] = x[0];
57 + $[3] = t0;
58 } else {
53 - t0 = $[1];
59 + t0 = $[3];
60 }
61 return t0;
62 }
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-aliased-not-added-to-dep-2.expect.md
+5 -12
@@ -18,28 +18,21 @@ function Foo({a}) {
18 ```javascript
19 import { c as _c } from "react/compiler-runtime"; // @validateRefAccessDuringRender:false
20 function Foo(t0) {
21 - const $ = _c(4);
21 + const $ = _c(2);
22 const { a } = t0;
23 const ref = useRef();
24 const val = ref.current;
25 let t1;
26 if ($[0] !== a) {
27 - t1 = { a, val };
27 + const x = { a, val };
28 +
29 + t1 = <VideoList videos={x} />;
30 $[0] = a;
31 $[1] = t1;
32 } else {
33 t1 = $[1];
34 }
33 - const x = t1;
34 - let t2;
35 - if ($[2] !== x) {
36 - t2 = <VideoList videos={x} />;
37 - $[2] = x;
38 - $[3] = t2;
39 - } else {
40 - t2 = $[3];
41 - }
42 - return t2;
35 + return t1;
36 }
37
38 ```
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ref-current-not-added-to-dep-2.expect.md
+5 -12
@@ -17,27 +17,20 @@ function Foo({a}) {
17 ```javascript
18 import { c as _c } from "react/compiler-runtime"; // @validateRefAccessDuringRender:false
19 function Foo(t0) {
20 - const $ = _c(4);
20 + const $ = _c(2);
21 const { a } = t0;
22 const ref = useRef();
23 let t1;
24 if ($[0] !== a) {
25 - t1 = { a, val: ref.current };
25 + const x = { a, val: ref.current };
26 +
27 + t1 = <VideoList videos={x} />;
28 $[0] = a;
29 $[1] = t1;
30 } else {
31 t1 = $[1];
32 }
31 - const x = t1;
32 - let t2;
33 - if ($[2] !== x) {
34 - t2 = <VideoList videos={x} />;
35 - $[2] = x;
36 - $[3] = t2;
37 - } else {
38 - t2 = $[3];
39 - }
40 - return t2;
33 + return t1;
34 }
35
36 ```
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rename-source-variables-nested-function.expect.md
+5 -13
@@ -41,11 +41,11 @@ const $ = "module_$";
41 const t0 = "module_t0";
42 const c_0 = "module_c_0";
43 function useFoo(props) {
44 - const $0 = _c(4);
44 + const $0 = _c(2);
45 const c_00 = $0[0] !== props.value;
46 let t1;
47 if (c_00) {
48 - t1 = () => {
48 + const a = () => {
49 const b = () => {
50 const c = () => {
51 console.log($);
@@ -57,22 +57,14 @@ function useFoo(props) {
57 };
58 return b;
59 };
60 +
61 + t1 = a()()();
62 $0[0] = props.value;
63 $0[1] = t1;
64 } else {
65 t1 = $0[1];
66 }
65 - const a = t1;
66 - const c_2 = $0[2] !== a;
67 - let t2;
68 - if (c_2) {
69 - t2 = a()()();
70 - $0[2] = a;
71 - $0[3] = t2;
72 - } else {
73 - t2 = $0[3];
74 - }
75 - return t2;
67 + return t1;
68 }
69
70 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-missing-memoization-lack-of-phi-types-explicit-types.expect.md
+17 -33
@@ -35,60 +35,44 @@ import { useMemo } from "react";
35 import { useFragment } from "shared-runtime";
36
37 function Component() {
38 - const $ = _c(11);
38 + const $ = _c(7);
39 const data = useFragment();
40 let t0;
41 if ($[0] !== data.nodes) {
42 - t0 = data.nodes ?? [];
42 + const nodes = data.nodes ?? [];
43 + const flatMap = nodes.flatMap(_temp);
44 + t0 = flatMap.filter(_temp2);
45 $[0] = data.nodes;
46 $[1] = t0;
47 } else {
48 t0 = $[1];
49 }
48 - const nodes = t0;
50 + const filtered = t0;
51 let t1;
50 - if ($[2] !== nodes) {
51 - t1 = nodes.flatMap(_temp);
52 - $[2] = nodes;
52 + if ($[2] !== filtered) {
53 + t1 = filtered.map();
54 + $[2] = filtered;
55 $[3] = t1;
56 } else {
57 t1 = $[3];
58 }
57 - const flatMap = t1;
58 - let t2;
59 - if ($[4] !== flatMap) {
60 - t2 = flatMap.filter(_temp2);
61 - $[4] = flatMap;
62 - $[5] = t2;
63 - } else {
64 - t2 = $[5];
65 - }
66 - const filtered = t2;
67 - let t3;
68 - if ($[6] !== filtered) {
69 - t3 = filtered.map();
70 - $[6] = filtered;
71 - $[7] = t3;
72 - } else {
73 - t3 = $[7];
74 - }
75 - const map = t3;
59 + const map = t1;
60 const index = filtered.findIndex(_temp3);
77 - let t4;
78 - if ($[8] !== index || $[9] !== map) {
79 - t4 = (
61 + let t2;
62 + if ($[4] !== index || $[5] !== map) {
63 + t2 = (
64 <div>
65 {map}
66 {index}
67 </div>
68 );
85 - $[8] = index;
86 - $[9] = map;
87 - $[10] = t4;
69 + $[4] = index;
70 + $[5] = map;
71 + $[6] = t2;
72 } else {
89 - t4 = $[10];
73 + t2 = $[6];
74 }
91 - return t4;
75 + return t2;
76 }
77 function _temp3(x) {
78 return x === null;
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-missing-memoization-lack-of-phi-types.expect.md
+17 -33
@@ -32,60 +32,44 @@ import { useMemo } from "react";
32 import { useFragment } from "shared-runtime";
33
34 function Component() {
35 - const $ = _c(11);
35 + const $ = _c(7);
36 const data = useFragment();
37 let t0;
38 if ($[0] !== data.nodes) {
39 - t0 = data.nodes ?? [];
39 + const nodes = data.nodes ?? [];
40 + const flatMap = nodes.flatMap(_temp);
41 + t0 = flatMap.filter(_temp2);
42 $[0] = data.nodes;
43 $[1] = t0;
44 } else {
45 t0 = $[1];
46 }
45 - const nodes = t0;
47 + const filtered = t0;
48 let t1;
47 - if ($[2] !== nodes) {
48 - t1 = nodes.flatMap(_temp);
49 - $[2] = nodes;
49 + if ($[2] !== filtered) {
50 + t1 = filtered.map();
51 + $[2] = filtered;
52 $[3] = t1;
53 } else {
54 t1 = $[3];
55 }
54 - const flatMap = t1;
55 - let t2;
56 - if ($[4] !== flatMap) {
57 - t2 = flatMap.filter(_temp2);
58 - $[4] = flatMap;
59 - $[5] = t2;
60 - } else {
61 - t2 = $[5];
62 - }
63 - const filtered = t2;
64 - let t3;
65 - if ($[6] !== filtered) {
66 - t3 = filtered.map();
67 - $[6] = filtered;
68 - $[7] = t3;
69 - } else {
70 - t3 = $[7];
71 - }
72 - const map = t3;
56 + const map = t1;
57 const index = filtered.findIndex(_temp3);
74 - let t4;
75 - if ($[8] !== index || $[9] !== map) {
76 - t4 = (
58 + let t2;
59 + if ($[4] !== index || $[5] !== map) {
60 + t2 = (
61 <div>
62 {map}
63 {index}
64 </div>
65 );
82 - $[8] = index;
83 - $[9] = map;
84 - $[10] = t4;
66 + $[4] = index;
67 + $[5] = map;
68 + $[6] = t2;
69 } else {
86 - t4 = $[10];
70 + t2 = $[6];
71 }
88 - return t4;
72 + return t2;
73 }
74 function _temp3(x) {
75 return x === null;
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-mutate-result-of-function-call-with-frozen-argument-in-function-expression.expect.md
+9 -16
@@ -30,40 +30,33 @@ import { c as _c } from "react/compiler-runtime";
30 import { identity, makeObject_Primitives, Stringify } from "shared-runtime";
31
32 function Example(props) {
33 - const $ = _c(7);
33 + const $ = _c(5);
34 const object = props.object;
35 let t0;
36 if ($[0] !== object || $[1] !== props.value) {
37 - t0 = () => {
37 + const f = () => {
38 const obj = identity(object);
39 obj.property = props.value;
40 return obj;
41 };
42 +
43 + t0 = f();
44 $[0] = object;
45 $[1] = props.value;
46 $[2] = t0;
47 } else {
48 t0 = $[2];
49 }
48 - const f = t0;
50 + const obj_0 = t0;
51 let t1;
50 - if ($[3] !== f) {
51 - t1 = f();
52 - $[3] = f;
52 + if ($[3] !== obj_0) {
53 + t1 = <Stringify obj={obj_0} />;
54 + $[3] = obj_0;
55 $[4] = t1;
56 } else {
57 t1 = $[4];
58 }
57 - const obj_0 = t1;
58 - let t2;
59 - if ($[5] !== obj_0) {
60 - t2 = <Stringify obj={obj_0} />;
61 - $[5] = obj_0;
62 - $[6] = t2;
63 - } else {
64 - t2 = $[6];
65 - }
66 - return t2;
59 + return t1;
60 }
61
62 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-mutate-result-of-method-call-on-frozen-value-in-function-expression.expect.md
+9 -16
@@ -30,40 +30,33 @@ import { c as _c } from "react/compiler-runtime";
30 import { makeObject_Primitives, Stringify } from "shared-runtime";
31
32 function Example(props) {
33 - const $ = _c(7);
33 + const $ = _c(5);
34 const object = props.object;
35 let t0;
36 if ($[0] !== object || $[1] !== props.value) {
37 - t0 = () => {
37 + const f = () => {
38 const obj = object.makeObject();
39 obj.property = props.value;
40 return obj;
41 };
42 +
43 + t0 = f();
44 $[0] = object;
45 $[1] = props.value;
46 $[2] = t0;
47 } else {
48 t0 = $[2];
49 }
48 - const f = t0;
50 + const obj_0 = t0;
51 let t1;
50 - if ($[3] !== f) {
51 - t1 = f();
52 - $[3] = f;
52 + if ($[3] !== obj_0) {
53 + t1 = <Stringify obj={obj_0} />;
54 + $[3] = obj_0;
55 $[4] = t1;
56 } else {
57 t1 = $[4];
58 }
57 - const obj_0 = t1;
58 - let t2;
59 - if ($[5] !== obj_0) {
60 - t2 = <Stringify obj={obj_0} />;
61 - $[5] = obj_0;
62 - $[6] = t2;
63 - } else {
64 - t2 = $[6];
65 - }
66 - return t2;
59 + return t1;
60 }
61
62 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-renaming-conflicting-decls.expect.md
+30 -37
@@ -45,7 +45,7 @@ import { Stringify, identity, makeArray, toJSON } from "shared-runtime";
45 import { useMemo } from "react";
46
47 function Component(props) {
48 - const $ = _c(12);
48 + const $ = _c(10);
49 let t0;
50 let t1;
51 if ($[0] !== props) {
@@ -71,57 +71,50 @@ function Component(props) {
71 }
72 let t2;
73 if ($[3] !== t0) {
74 - t2 = { url: t0 };
75 - $[3] = t0;
76 - $[4] = t2;
77 - } else {
78 - t2 = $[4];
79 - }
80 - const linkProps = t2;
81 - let t3;
82 - if ($[5] !== linkProps) {
74 + const linkProps = { url: t0 };
75 +
76 const x = {};
77 + let t3;
78 let t4;
79 let t5;
80 let t6;
81 let t7;
88 - let t8;
89 - if ($[7] === Symbol.for("react.memo_cache_sentinel")) {
90 - t4 = [1];
91 - t5 = [2];
92 - t6 = [3];
93 - t7 = [4];
94 - t8 = [5];
95 - $[7] = t4;
96 - $[8] = t5;
97 - $[9] = t6;
98 - $[10] = t7;
99 - $[11] = t8;
82 + if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
83 + t3 = [1];
84 + t4 = [2];
85 + t5 = [3];
86 + t6 = [4];
87 + t7 = [5];
88 + $[5] = t3;
89 + $[6] = t4;
90 + $[7] = t5;
91 + $[8] = t6;
92 + $[9] = t7;
93 } else {
101 - t4 = $[7];
102 - t5 = $[8];
103 - t6 = $[9];
104 - t7 = $[10];
105 - t8 = $[11];
94 + t3 = $[5];
95 + t4 = $[6];
96 + t5 = $[7];
97 + t6 = $[8];
98 + t7 = $[9];
99 }
107 - t3 = (
100 + t2 = (
101 <Stringify
102 link={linkProps}
110 - val1={t4}
111 - val2={t5}
112 - val3={t6}
113 - val4={t7}
114 - val5={t8}
103 + val1={t3}
104 + val2={t4}
105 + val3={t5}
106 + val4={t6}
107 + val5={t7}
108 >
109 {makeArray(x, 2)}
110 </Stringify>
111 );
119 - $[5] = linkProps;
120 - $[6] = t3;
112 + $[3] = t0;
113 + $[4] = t2;
114 } else {
122 - t3 = $[6];
115 + t2 = $[4];
116 }
124 - return t3;
117 + return t2;
118 }
119
120 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-undefined-expression-of-jsxexpressioncontainer.expect.md
+5 -12
@@ -48,28 +48,21 @@ import { c as _c } from "react/compiler-runtime";
48 import { StaticText1, Stringify, Text } from "shared-runtime";
49
50 function Component(props) {
51 - const $ = _c(4);
51 + const $ = _c(2);
52 const { buttons } = props;
53 let t0;
54 if ($[0] !== buttons) {
55 const [, ...nonPrimaryButtons] = buttons;
56
57 - t0 = nonPrimaryButtons.map(_temp);
57 + const renderedNonPrimaryButtons = nonPrimaryButtons.map(_temp);
58 +
59 + t0 = <StaticText1>{renderedNonPrimaryButtons}</StaticText1>;
60 $[0] = buttons;
61 $[1] = t0;
62 } else {
63 t0 = $[1];
64 }
63 - const renderedNonPrimaryButtons = t0;
64 - let t1;
65 - if ($[2] !== renderedNonPrimaryButtons) {
66 - t1 = <StaticText1>{renderedNonPrimaryButtons}</StaticText1>;
67 - $[2] = renderedNonPrimaryButtons;
68 - $[3] = t1;
69 - } else {
70 - t1 = $[3];
71 - }
72 - return t1;
65 + return t0;
66 }
67 function _temp(buttonProps, i) {
68 return (
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/try-catch-within-function-expression-returns-caught-value.expect.md
+5 -12
@@ -29,10 +29,10 @@ import { c as _c } from "react/compiler-runtime";
29 import { throwInput } from "shared-runtime";
30
31 function Component(props) {
32 - const $ = _c(4);
32 + const $ = _c(2);
33 let t0;
34 if ($[0] !== props) {
35 - t0 = () => {
35 + const callback = () => {
36 try {
37 throwInput([props.value]);
38 } catch (t1) {
@@ -40,21 +40,14 @@ function Component(props) {
40 return e;
41 }
42 };
43 +
44 + t0 = callback();
45 $[0] = props;
46 $[1] = t0;
47 } else {
48 t0 = $[1];
49 }
48 - const callback = t0;
49 - let t1;
50 - if ($[2] !== callback) {
51 - t1 = callback();
52 - $[2] = callback;
53 - $[3] = t1;
54 - } else {
55 - t1 = $[3];
56 - }
57 - return t1;
50 + return t0;
51 }
52
53 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/type-annotations/type-annotation-var-array.expect.md
+4 -12
@@ -25,25 +25,17 @@ export const FIXTURE_ENTRYPOINT = {
25 ```javascript
26 import { c as _c } from "react/compiler-runtime"; // @enableUseTypeAnnotations
27 function Component(props) {
28 - const $ = _c(4);
28 + const $ = _c(2);
29 let t0;
30 if ($[0] !== props.id) {
31 - t0 = makeArray(props.id);
31 + const x = makeArray(props.id);
32 + t0 = x.at(0);
33 $[0] = props.id;
34 $[1] = t0;
35 } else {
36 t0 = $[1];
37 }
37 - const x = t0;
38 - let t1;
39 - if ($[2] !== x) {
40 - t1 = x.at(0);
41 - $[2] = x;
42 - $[3] = t1;
43 - } else {
44 - t1 = $[3];
45 - }
46 - const y = t1;
38 + const y = t0;
39 return y;
40 }
41
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/type-annotations/type-annotation-var-array_.flow.expect.md
+4 -12
@@ -29,25 +29,17 @@ import { c as _c } from "react/compiler-runtime";
29 import { identity } from "shared-runtime";
30
31 function Component(props) {
32 - const $ = _c(4);
32 + const $ = _c(2);
33 let t0;
34 if ($[0] !== props.id) {
35 - t0 = makeArray(props.id);
35 + const x = makeArray(props.id);
36 + t0 = x.at(0);
37 $[0] = props.id;
38 $[1] = t0;
39 } else {
40 t0 = $[1];
41 }
41 - const x = t0;
42 - let t1;
43 - if ($[2] !== x) {
44 - t1 = x.at(0);
45 - $[2] = x;
46 - $[3] = t1;
47 - } else {
48 - t1 = $[3];
49 - }
50 - const y = t1;
42 + const y = t0;
43 return y;
44 }
45
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-memo-simple.expect.md
+4 -12
@@ -22,25 +22,17 @@ export const FIXTURE_ENTRYPOINT = {
22 import { c as _c } from "react/compiler-runtime";
23 function Component(props) {
24 "use memo";
25 - const $ = _c(4);
25 + const $ = _c(2);
26 let t0;
27 if ($[0] !== props.foo) {
28 - t0 = [props.foo];
28 + const x = [props.foo];
29 + t0 = <div x={x}>"foo"</div>;
30 $[0] = props.foo;
31 $[1] = t0;
32 } else {
33 t0 = $[1];
34 }
34 - const x = t0;
35 - let t1;
36 - if ($[2] !== x) {
37 - t1 = <div x={x}>"foo"</div>;
38 - $[2] = x;
39 - $[3] = t1;
40 - } else {
41 - t1 = $[3];
42 - }
43 - return t1;
35 + return t0;
36 }
37
38 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useContext-read-context-in-callback-if-condition.expect.md
+9 -16
@@ -39,41 +39,34 @@ import { Stringify } from "shared-runtime";
39 const FooContext = createContext({ current: true });
40
41 function Component(props) {
42 - const $ = _c(6);
42 + const $ = _c(4);
43 const foo = useContext(FooContext);
44 let t0;
45 if ($[0] !== foo.current) {
46 - t0 = () => {
46 + const getValue = () => {
47 if (foo.current) {
48 return {};
49 } else {
50 return null;
51 }
52 };
53 +
54 + t0 = getValue();
55 $[0] = foo.current;
56 $[1] = t0;
57 } else {
58 t0 = $[1];
59 }
58 - const getValue = t0;
60 + const value = t0;
61 let t1;
60 - if ($[2] !== getValue) {
61 - t1 = getValue();
62 - $[2] = getValue;
62 + if ($[2] !== value) {
63 + t1 = <Stringify value={value} />;
64 + $[2] = value;
65 $[3] = t1;
66 } else {
67 t1 = $[3];
68 }
67 - const value = t1;
68 - let t2;
69 - if ($[4] !== value) {
70 - t2 = <Stringify value={value} />;
71 - $[4] = value;
72 - $[5] = t2;
73 - } else {
74 - t2 = $[5];
75 - }
76 - return t2;
69 + return t1;
70 }
71
72 export const FIXTURE_ENTRYPOINT = {