From 296e7030a72031e51eff4c5c82b3b78205bf00c6 Mon Sep 17 00:00:00 2001 From: Joe Savona Date: Fri, 17 May 2024 17:01:28 -0700 Subject: [PATCH] compiler: Improve merging of memo scopes that invalidate together Improves merging of consecutive scopes so that we now merge two scopes if the dependencies of the second scope are a subset of the previous scope's output *and* that dependency has a type that will always produce a new value (array, object, jsx, function) if it is re-evaluated. To make this easier, we extend the set of builtin types to include ones for function expressions and JSX and to infer these types in InferTypes. This allows using the already inferred types in MergeReactiveScopesThatInvalidateTogether. ghstack-source-id: 720b9288bb501006329ead733cacbc67df487e16 Pull Request resolved: https://github.com/facebook/react/pull/29156 --- .../src/HIR/ObjectShape.ts | 2 + ...rgeReactiveScopesThatInvalidateTogether.ts | 26 ++++++++++ .../src/TypeInference/InferTypes.ts | 10 +++- .../fixtures/compiler/component.expect.md | 23 +++------ ...-callback-invoked-during-render-.expect.md | 2 +- ...n-callback-invoked-during-render.expect.md | 2 +- .../existing-variables-with-c-name.expect.md | 15 ++---- ...onmutating-loop-local-collection.expect.md | 49 +++++-------------- .../compiler/hot-module-reloading.expect.md | 17 ++----- ...-promoted-to-outer-scope-dynamic.expect.md | 37 ++++---------- .../fixtures/compiler/jsx-spread.expect.md | 15 ++---- .../jsx-string-attribute-non-ascii.expect.md | 23 +++------ ...-tag-evaluation-order-non-global.expect.md | 24 +++------ ...merge-consecutive-scopes-objects.expect.md | 25 ++++------ .../merge-consecutive-scopes.expect.md | 27 +++------- .../compiler/merge-scopes-repro.expect.md | 37 +++----------- .../object-shorthand-method-1.expect.md | 27 ++++------ .../object-shorthand-method-2.expect.md | 38 ++++++-------- ...invoked-callback-escaping-return.expect.md | 23 +++------ ...ion-part-of-already-closed-scope.expect.md | 26 +++------- ...ble-code-early-return-in-useMemo.expect.md | 15 ++---- ...assignment-to-scope-declarations.expect.md | 28 +++-------- ...ixed-local-and-scope-declaration.expect.md | 28 +++-------- .../use-operator-call-expression.expect.md | 15 ++---- .../use-operator-conditional.expect.md | 34 ++++--------- .../use-operator-method-call.expect.md | 15 ++---- 26 files changed, 187 insertions(+), 396 deletions(-) diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/ObjectShape.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/ObjectShape.ts index 33a0351ba1fa2..995b3caa2890a 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/ObjectShape.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/ObjectShape.ts @@ -188,6 +188,8 @@ export type ObjectShape = { */ export type ShapeRegistry = Map; export const BuiltInArrayId = "BuiltInArray"; +export const BuiltInFunctionId = "BuiltInFunction"; +export const BuiltInJsxId = "BuiltInJsx"; export const BuiltInObjectId = "BuiltInObject"; export const BuiltInUseStateId = "BuiltInUseState"; export const BuiltInSetStateId = "BuiltInSetState"; diff --git a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/MergeReactiveScopesThatInvalidateTogether.ts b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/MergeReactiveScopesThatInvalidateTogether.ts index 495d4945df345..bd533a13f4d8f 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/MergeReactiveScopesThatInvalidateTogether.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/MergeReactiveScopesThatInvalidateTogether.ts @@ -19,8 +19,15 @@ import { ReactiveScopeDependencies, ReactiveScopeDependency, ReactiveStatement, + Type, makeInstructionId, } from "../HIR"; +import { + BuiltInArrayId, + BuiltInFunctionId, + BuiltInJsxId, + BuiltInObjectId, +} from "../HIR/ObjectShape"; import { eachInstructionLValue } from "../HIR/visitors"; import { assertExhaustive } from "../Utils/utils"; import { printReactiveScopeSummary } from "./PrintReactiveFunction"; @@ -430,6 +437,11 @@ function canMergeScopes( })) ), next.scope.dependencies + ) || + [...next.scope.dependencies].some( + (dep) => + current.scope.declarations.has(dep.identifier.id) && + isAlwaysInvalidatingType(dep.identifier.type) ) ) { log(` outputs of prev are input to current`); @@ -441,6 +453,20 @@ function canMergeScopes( return false; } +function isAlwaysInvalidatingType(type: Type): boolean { + if (type.kind === "Object") { + switch (type.shapeId) { + case BuiltInArrayId: + case BuiltInObjectId: + case BuiltInFunctionId: + case BuiltInJsxId: { + return true; + } + } + } + return false; +} + function areEqualDependencies( a: Set, b: Set diff --git a/compiler/packages/babel-plugin-react-compiler/src/TypeInference/InferTypes.ts b/compiler/packages/babel-plugin-react-compiler/src/TypeInference/InferTypes.ts index 9ac8f403924d7..9b4425f097a24 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/TypeInference/InferTypes.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/TypeInference/InferTypes.ts @@ -20,6 +20,8 @@ import { } from "../HIR/HIR"; import { BuiltInArrayId, + BuiltInFunctionId, + BuiltInJsxId, BuiltInObjectId, BuiltInUseRefId, } from "../HIR/ObjectShape"; @@ -313,6 +315,7 @@ function* generateInstructionTypes( case "FunctionExpression": { yield* generate(value.loweredFunc.func); + yield equation(left, { kind: "Object", shapeId: BuiltInFunctionId }); break; } @@ -327,10 +330,13 @@ function* generateInstructionTypes( break; } + case "JsxExpression": + case "JsxFragment": { + yield equation(left, { kind: "Object", shapeId: BuiltInJsxId }); + break; + } case "DeclareLocal": case "NewExpression": - case "JsxExpression": - case "JsxFragment": case "RegExpLiteral": case "PropertyStore": case "ComputedStore": diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/component.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/component.expect.md index cd775f78aca2d..f6090f96019f5 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/component.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/component.expect.md @@ -42,7 +42,7 @@ export const FIXTURE_ENTRYPOINT = { ```javascript import { c as _c } from "react/compiler-runtime"; function Component(props) { - const $ = _c(8); + const $ = _c(5); const items = props.items; const maxItems = props.maxItems; let renderedItems; @@ -72,27 +72,18 @@ function Component(props) { const count = renderedItems.length; let t0; if ($[3] !== count) { - t0 =

{count} Items

; - $[3] = count; - $[4] = t0; - } else { - t0 = $[4]; - } - let t1; - if ($[5] !== t0 || $[6] !== renderedItems) { - t1 = ( + t0 = (
- {t0} +

{count} Items

{renderedItems}
); - $[5] = t0; - $[6] = renderedItems; - $[7] = t1; + $[3] = count; + $[4] = t0; } else { - t1 = $[7]; + t0 = $[4]; } - return t1; + return t0; } export const FIXTURE_ENTRYPOINT = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-aliased-ref-in-callback-invoked-during-render-.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-aliased-ref-in-callback-invoked-during-render-.expect.md index 38e5f636f087c..9560bd708f63e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-aliased-ref-in-callback-invoked-during-render-.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-aliased-ref-in-callback-invoked-during-render-.expect.md @@ -22,7 +22,7 @@ function Component(props) { 7 | return ; 8 | }; > 9 | return {props.items.map((item) => renderItem(item))}; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef). Cannot access ref value at mutate? $64[13:15] (9:9) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef). Cannot access ref value at mutate? $64[13:15]:TObject (9:9) 10 | } 11 | ``` diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-ref-in-callback-invoked-during-render.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-ref-in-callback-invoked-during-render.expect.md index 5f7a6e061809d..0118d7d1e1bce 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-ref-in-callback-invoked-during-render.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-ref-in-callback-invoked-during-render.expect.md @@ -21,7 +21,7 @@ function Component(props) { 6 | return ; 7 | }; > 8 | return {props.items.map((item) => renderItem(item))}; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef). Cannot access ref value at mutate? $60[14:16] (8:8) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef). Cannot access ref value at mutate? $60[14:16]:TObject (8:8) 9 | } 10 | ``` diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/existing-variables-with-c-name.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/existing-variables-with-c-name.expect.md index 0b90b6c6256f5..8d62542e76c9e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/existing-variables-with-c-name.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/existing-variables-with-c-name.expect.md @@ -33,7 +33,7 @@ import { useMemo, useState } from "react"; import { ValidateMemoization } from "shared-runtime"; function Component(props) { - const $ = _c2(7); + const $ = _c2(4); const [state] = useState(0); const c = state; @@ -54,22 +54,13 @@ function Component(props) { const array = t0; let t2; if ($[2] !== state) { - t2 = [state]; + t2 = ; $[2] = state; $[3] = t2; } else { t2 = $[3]; } - let t3; - if ($[4] !== t2 || $[5] !== array) { - t3 = ; - $[4] = t2; - $[5] = array; - $[6] = t3; - } else { - t3 = $[6]; - } - return t3; + return t2; } export const FIXTURE_ENTRYPOINT = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/for-of-nonmutating-loop-local-collection.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/for-of-nonmutating-loop-local-collection.expect.md index 1c223a50f4a44..b1ad40145a33e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/for-of-nonmutating-loop-local-collection.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/for-of-nonmutating-loop-local-collection.expect.md @@ -44,7 +44,7 @@ import { useMemo } from "react"; import { ValidateMemoization } from "shared-runtime"; function Component(t0) { - const $ = _c(19); + const $ = _c(10); const { a, b } = t0; let t1; let t2; @@ -75,54 +75,27 @@ function Component(t0) { const y = t3; let t4; if ($[5] !== a) { - t4 = [a]; + t4 = ; $[5] = a; $[6] = t4; } else { t4 = $[6]; } let t5; - if ($[7] !== t4 || $[8] !== x) { - t5 = ; - $[7] = t4; - $[8] = x; - $[9] = t5; - } else { - t5 = $[9]; - } - let t6; - if ($[10] !== x || $[11] !== b) { - t6 = [x, b]; - $[10] = x; - $[11] = b; - $[12] = t6; - } else { - t6 = $[12]; - } - let t7; - if ($[13] !== t6 || $[14] !== y) { - t7 = ; - $[13] = t6; - $[14] = y; - $[15] = t7; - } else { - t7 = $[15]; - } - let t8; - if ($[16] !== t5 || $[17] !== t7) { - t8 = ( + if ($[7] !== x || $[8] !== b) { + t5 = ( <> - {t5} - {t7} + {t4} + ); - $[16] = t5; - $[17] = t7; - $[18] = t8; + $[7] = x; + $[8] = b; + $[9] = t5; } else { - t8 = $[18]; + t5 = $[9]; } - return t8; + return t5; } export const FIXTURE_ENTRYPOINT = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hot-module-reloading.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hot-module-reloading.expect.md index ec16ce0bcdb7b..2067b075eee38 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hot-module-reloading.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hot-module-reloading.expect.md @@ -28,11 +28,11 @@ import { useMemo, useState } from "react"; import { ValidateMemoization } from "shared-runtime"; function Component(props) { - const $ = _c(8); + const $ = _c(5); if ( $[0] !== "bb6936608c0afe8e313aa547ca09fbc8451f24664284368812127c7e9bc2bca9" ) { - for (let $i = 0; $i < 8; $i += 1) { + for (let $i = 0; $i < 5; $i += 1) { $[$i] = Symbol.for("react.memo_cache_sentinel"); } $[0] = "bb6936608c0afe8e313aa547ca09fbc8451f24664284368812127c7e9bc2bca9"; @@ -52,22 +52,13 @@ function Component(props) { const doubled = t0; let t3; if ($[3] !== state) { - t3 = [state]; + t3 = ; $[3] = state; $[4] = t3; } else { t3 = $[4]; } - let t4; - if ($[5] !== t3 || $[6] !== doubled) { - t4 = ; - $[5] = t3; - $[6] = doubled; - $[7] = t4; - } else { - t4 = $[7]; - } - return t4; + return t3; } export const FIXTURE_ENTRYPOINT = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-memo-value-not-promoted-to-outer-scope-dynamic.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-memo-value-not-promoted-to-outer-scope-dynamic.expect.md index becc4066e7d76..fbf3405fbaa3a 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-memo-value-not-promoted-to-outer-scope-dynamic.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-memo-value-not-promoted-to-outer-scope-dynamic.expect.md @@ -24,7 +24,7 @@ function Component(props) { ```javascript import { c as _c } from "react/compiler-runtime"; function Component(props) { - const $ = _c(15); + const $ = _c(8); const item = useFragment(FRAGMENT, props.item); useFreeze(item); let t0; @@ -56,37 +56,20 @@ function Component(props) { } let t2; if ($[6] !== t0) { - t2 = {t0}; + t2 = ( + + + {t1} + {t0} + + + ); $[6] = t0; $[7] = t2; } else { t2 = $[7]; } - let t3; - if ($[8] !== T0 || $[9] !== t1 || $[10] !== t2) { - t3 = ( - - {t1} - {t2} - - ); - $[8] = T0; - $[9] = t1; - $[10] = t2; - $[11] = t3; - } else { - t3 = $[11]; - } - let t4; - if ($[12] !== T1 || $[13] !== t3) { - t4 = {t3}; - $[12] = T1; - $[13] = t3; - $[14] = t4; - } else { - t4 = $[14]; - } - return t4; + return t2; } ``` diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-spread.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-spread.expect.md index e4ffb3f6f6593..318a8f557e8e2 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-spread.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-spread.expect.md @@ -15,27 +15,18 @@ function Component(props) { ```javascript import { c as _c } from "react/compiler-runtime"; function Component(props) { - const $ = _c(5); + const $ = _c(2); const t0 = props.cond ? props.foo : props.bar; let t1; if ($[0] !== t0) { - t1 = { bar: t0 }; + t1 = ; $[0] = t0; $[1] = t1; } else { t1 = $[1]; } - let t2; - if ($[2] !== props || $[3] !== t1) { - t2 = ; - $[2] = props; - $[3] = t1; - $[4] = t2; - } else { - t2 = $[4]; - } - return t2; + return t1; } ``` diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-string-attribute-non-ascii.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-string-attribute-non-ascii.expect.md index 1cb36945e9fd4..f98c8cd415d44 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-string-attribute-non-ascii.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-string-attribute-non-ascii.expect.md @@ -51,7 +51,7 @@ function Component() { } function Post(t0) { - const $ = _c(7); + const $ = _c(4); const { author, text } = t0; let t1; if ($[0] !== author) { @@ -63,27 +63,18 @@ function Post(t0) { } let t2; if ($[2] !== text) { - t2 = {text}; - $[2] = text; - $[3] = t2; - } else { - t2 = $[3]; - } - let t3; - if ($[4] !== t1 || $[5] !== t2) { - t3 = ( + t2 = (
{t1} - {t2} + {text}
); - $[4] = t1; - $[5] = t2; - $[6] = t3; + $[2] = text; + $[3] = t2; } else { - t3 = $[6]; + t2 = $[3]; } - return t3; + return t2; } export const FIXTURE_ENTRYPOINT = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-tag-evaluation-order-non-global.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-tag-evaluation-order-non-global.expect.md index 5844f5f611680..2c4c58b39cfca 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-tag-evaluation-order-non-global.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-tag-evaluation-order-non-global.expect.md @@ -52,7 +52,7 @@ function MaybeMutable() { function maybeMutate(x) {} function Component(props) { - const $ = _c(11); + const $ = _c(7); let Tag; let T0; let t0; @@ -74,28 +74,18 @@ function Component(props) { } let t1; if ($[5] !== Tag) { - t1 = ; - $[5] = Tag; - $[6] = t1; - } else { - t1 = $[6]; - } - let t2; - if ($[7] !== T0 || $[8] !== t0 || $[9] !== t1) { - t2 = ( + t1 = ( {t0} - {t1} + ); - $[7] = T0; - $[8] = t0; - $[9] = t1; - $[10] = t2; + $[5] = Tag; + $[6] = t1; } else { - t2 = $[10]; + t1 = $[6]; } - return t2; + return t1; } export const FIXTURE_ENTRYPOINT = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/merge-consecutive-scopes-objects.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/merge-consecutive-scopes-objects.expect.md index 392dcf4c8458b..c4358b440cd08 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/merge-consecutive-scopes-objects.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/merge-consecutive-scopes-objects.expect.md @@ -44,7 +44,7 @@ import { Stringify } from "shared-runtime"; // prevent scome scopes from merging, which concealed a bug with the merging logic. // By avoiding JSX we eliminate extraneous instructions and more accurately test the merging. function Component(props) { - const $ = _c(11); + const $ = _c(8); const [state, setState] = useState(0); let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { @@ -78,25 +78,20 @@ function Component(props) { } let t4; if ($[6] !== t2) { - t4 = { - component: "button", - props: { "data-testid": "button", onClick: t2, children: t3 }, - }; + t4 = [ + t0, + t1, + { + component: "button", + props: { "data-testid": "button", onClick: t2, children: t3 }, + }, + ]; $[6] = t2; $[7] = t4; } else { t4 = $[7]; } - let t5; - if ($[8] !== t1 || $[9] !== t4) { - t5 = [t0, t1, t4]; - $[8] = t1; - $[9] = t4; - $[10] = t5; - } else { - t5 = $[10]; - } - return t5; + return t4; } export const FIXTURE_ENTRYPOINT = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/merge-consecutive-scopes.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/merge-consecutive-scopes.expect.md index c893ac645734b..71b5253af8f94 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/merge-consecutive-scopes.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/merge-consecutive-scopes.expect.md @@ -33,7 +33,7 @@ import { useState } from "react"; import { Stringify } from "shared-runtime"; function Component() { - const $ = _c(8); + const $ = _c(5); const [state, setState] = useState(0); let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { @@ -53,31 +53,20 @@ function Component() { let t2; if ($[3] !== state) { t2 = ( - - ); - $[3] = state; - $[4] = t2; - } else { - t2 = $[4]; - } - let t3; - if ($[5] !== t1 || $[6] !== t2) { - t3 = (
{t0} {t1} - {t2} +
); - $[5] = t1; - $[6] = t2; - $[7] = t3; + $[3] = state; + $[4] = t2; } else { - t3 = $[7]; + t2 = $[4]; } - return t3; + return t2; } export const FIXTURE_ENTRYPOINT = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/merge-scopes-repro.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/merge-scopes-repro.expect.md index a1d5a24b46d70..31dad46561ca4 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/merge-scopes-repro.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/merge-scopes-repro.expect.md @@ -19,43 +19,22 @@ function Component() { ```javascript import { c as _c } from "react/compiler-runtime"; function Component() { - const $ = _c(8); + const $ = _c(2); const [count, setCount] = useState(0); let t0; - let t1; if ($[0] !== count) { - t0 = ; - t1 = () => setCount(count + 1); - $[0] = count; - $[1] = t0; - $[2] = t1; - } else { - t0 = $[1]; - t1 = $[2]; - } - let t2; - if ($[3] !== t1) { - t2 = ; - $[3] = t1; - $[4] = t2; - } else { - t2 = $[4]; - } - let t3; - if ($[5] !== t0 || $[6] !== t2) { - t3 = ( + t0 = (
- {t0} - {t2} + +
); - $[5] = t0; - $[6] = t2; - $[7] = t3; + $[0] = count; + $[1] = t0; } else { - t3 = $[7]; + t0 = $[1]; } - return t3; + return t0; } ``` diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-shorthand-method-1.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-shorthand-method-1.expect.md index 213f7a01f3f59..c777a9c884dbc 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-shorthand-method-1.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-shorthand-method-1.expect.md @@ -27,33 +27,24 @@ export const FIXTURE_ENTRYPOINT = { import { c as _c } from "react/compiler-runtime"; import { createHookWrapper } from "shared-runtime"; function useHook(t0) { - const $ = _c(5); + const $ = _c(2); const { a, b } = t0; let t1; if ($[0] !== a) { - t1 = function () { - return [a]; - }; - $[0] = a; - $[1] = t1; - } else { - t1 = $[1]; - } - let t2; - if ($[2] !== b || $[3] !== t1) { - t2 = { - x: t1, + t1 = { + x: function () { + return [a]; + }, y() { return [b]; }, }; - $[2] = b; - $[3] = t1; - $[4] = t2; + $[0] = a; + $[1] = t1; } else { - t2 = $[4]; + t1 = $[1]; } - return t2; + return t1; } export const FIXTURE_ENTRYPOINT = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-shorthand-method-2.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-shorthand-method-2.expect.md index 271f0269de5bf..305e98a4e2035 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-shorthand-method-2.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-shorthand-method-2.expect.md @@ -28,41 +28,31 @@ import { c as _c } from "react/compiler-runtime"; import { createHookWrapper } from "shared-runtime"; function useHook(t0) { - const $ = _c(8); + const $ = _c(4); const { a, b, c } = t0; let t1; if ($[0] !== a) { - t1 = [a]; - $[0] = a; - $[1] = t1; - } else { - t1 = $[1]; - } - let t2; - if ($[2] !== b || $[3] !== c || $[4] !== t1) { - let t3; - if ($[6] !== c) { - t3 = { c }; - $[6] = c; - $[7] = t3; + let t2; + if ($[2] !== c) { + t2 = { c }; + $[2] = c; + $[3] = t2; } else { - t3 = $[7]; + t2 = $[3]; } - t2 = { - x: t1, + t1 = { + x: [a], y() { return [b]; }, - z: t3, + z: t2, }; - $[2] = b; - $[3] = c; - $[4] = t1; - $[5] = t2; + $[0] = a; + $[1] = t1; } else { - t2 = $[5]; + t1 = $[1]; } - return t2; + return t1; } export const FIXTURE_ENTRYPOINT = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-nonescaping-invoked-callback-escaping-return.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-nonescaping-invoked-callback-escaping-return.expect.md index 1291ccdfa9453..b5bcb6c8a3400 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-nonescaping-invoked-callback-escaping-return.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-nonescaping-invoked-callback-escaping-return.expect.md @@ -40,7 +40,7 @@ import { c as _c } from "react/compiler-runtime"; // @validatePreserveExistingMe import { useCallback } from "react"; function Component(t0) { - const $ = _c(11); + const $ = _c(8); const { entity, children } = t0; let t1; if ($[0] !== entity) { @@ -70,27 +70,18 @@ function Component(t0) { } let t4; if ($[6] !== children) { - t4 =
{children}
; - $[6] = children; - $[7] = t4; - } else { - t4 = $[7]; - } - let t5; - if ($[8] !== t3 || $[9] !== t4) { - t5 = ( + t4 = (
{t3} - {t4} +
{children}
); - $[8] = t3; - $[9] = t4; - $[10] = t5; + $[6] = children; + $[7] = t4; } else { - t5 = $[10]; + t4 = $[7]; } - return t5; + return t4; } export const FIXTURE_ENTRYPOINT = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-instruction-part-of-already-closed-scope.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-instruction-part-of-already-closed-scope.expect.md index f1fc418d92c33..486e9f6a4d16a 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-instruction-part-of-already-closed-scope.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-instruction-part-of-already-closed-scope.expect.md @@ -35,7 +35,7 @@ import { c as _c } from "react/compiler-runtime"; // @enableAssumeHooksFollowRul import { Stringify, identity, useHook } from "shared-runtime"; function Component(t0) { - const $ = _c(17); + const $ = _c(13); const { index } = t0; const data = useHook(); let T0; @@ -79,30 +79,20 @@ function Component(t0) { } let t4; if ($[10] !== T0 || $[11] !== t1) { - t4 = ; - $[10] = T0; - $[11] = t1; - $[12] = t4; - } else { - t4 = $[12]; - } - let t5; - if ($[13] !== t2 || $[14] !== t3 || $[15] !== t4) { - t5 = ( + t4 = (
{t2} {t3} - {t4} +
); - $[13] = t2; - $[14] = t3; - $[15] = t4; - $[16] = t5; + $[10] = T0; + $[11] = t1; + $[12] = t4; } else { - t5 = $[16]; + t4 = $[12]; } - return t5; + return t4; } export const FIXTURE_ENTRYPOINT = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-unreachable-code-early-return-in-useMemo.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-unreachable-code-early-return-in-useMemo.expect.md index 732f11d31155d..3b4581b68ed7e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-unreachable-code-early-return-in-useMemo.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-unreachable-code-early-return-in-useMemo.expect.md @@ -45,7 +45,7 @@ import { useMemo, useState } from "react"; import { ValidateMemoization, identity } from "shared-runtime"; function Component(t0) { - const $ = _c(7); + const $ = _c(4); const { value } = t0; let t1; bb0: { @@ -70,22 +70,13 @@ function Component(t0) { const result = t1; let t2; if ($[2] !== value) { - t2 = [value]; + t2 = ; $[2] = value; $[3] = t2; } else { t2 = $[3]; } - let t3; - if ($[4] !== t2 || $[5] !== result) { - t3 = ; - $[4] = t2; - $[5] = result; - $[6] = t3; - } else { - t3 = $[6]; - } - return t3; + return t2; } export const FIXTURE_ENTRYPOINT = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/sequential-destructuring-assignment-to-scope-declarations.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/sequential-destructuring-assignment-to-scope-declarations.expect.md index 6dcf610625390..07bc991ca86b4 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/sequential-destructuring-assignment-to-scope-declarations.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/sequential-destructuring-assignment-to-scope-declarations.expect.md @@ -42,7 +42,7 @@ import { c as _c } from "react/compiler-runtime"; import { identity } from "shared-runtime"; function Component(statusName) { - const $ = _c(12); + const $ = _c(6); let text; let t0; let t1; @@ -64,31 +64,17 @@ function Component(statusName) { } let t2; if ($[4] !== text) { - t2 = [text]; + t2 = ( +
+ {[text]} +
+ ); $[4] = text; $[5] = t2; } else { t2 = $[5]; } - let t3; - if ($[6] !== t0 || $[7] !== t2) { - t3 = {t2}; - $[6] = t0; - $[7] = t2; - $[8] = t3; - } else { - t3 = $[8]; - } - let t4; - if ($[9] !== t1 || $[10] !== t3) { - t4 =
{t3}
; - $[9] = t1; - $[10] = t3; - $[11] = t4; - } else { - t4 = $[11]; - } - return t4; + return t2; } function foo(name) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/sequential-destructuring-both-mixed-local-and-scope-declaration.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/sequential-destructuring-both-mixed-local-and-scope-declaration.expect.md index e99b39b6be7a9..980493e2a764a 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/sequential-destructuring-both-mixed-local-and-scope-declaration.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/sequential-destructuring-both-mixed-local-and-scope-declaration.expect.md @@ -45,7 +45,7 @@ import { c as _c } from "react/compiler-runtime"; import { identity } from "shared-runtime"; function Component(statusName) { - const $ = _c(12); + const $ = _c(6); let t0; let text; let font; @@ -69,31 +69,17 @@ function Component(statusName) { const bg = t0; let t1; if ($[4] !== text) { - t1 = [text]; + t1 = ( +
+ {[text]} +
+ ); $[4] = text; $[5] = t1; } else { t1 = $[5]; } - let t2; - if ($[6] !== font || $[7] !== t1) { - t2 = {t1}; - $[6] = font; - $[7] = t1; - $[8] = t2; - } else { - t2 = $[8]; - } - let t3; - if ($[9] !== bg || $[10] !== t2) { - t3 =
{t2}
; - $[9] = bg; - $[10] = t2; - $[11] = t3; - } else { - t3 = $[11]; - } - return t3; + return t1; } function foo(name) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-operator-call-expression.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-operator-call-expression.expect.md index 81d1797f7c113..2a60ddd5258c2 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-operator-call-expression.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-operator-call-expression.expect.md @@ -67,7 +67,7 @@ function Component(props) { } function Inner(props) { - const $ = _c(7); + const $ = _c(4); const input = use(FooContext); let t0; let t1; @@ -82,22 +82,13 @@ function Inner(props) { const output = t0; let t2; if ($[2] !== input) { - t2 = [input]; + t2 = ; $[2] = input; $[3] = t2; } else { t2 = $[3]; } - let t3; - if ($[4] !== t2 || $[5] !== output) { - t3 = ; - $[4] = t2; - $[5] = output; - $[6] = t3; - } else { - t3 = $[6]; - } - return t3; + return t2; } export const FIXTURE_ENTRYPOINT = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-operator-conditional.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-operator-conditional.expect.md index 77e19468df820..e056ac15c3f0f 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-operator-conditional.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-operator-conditional.expect.md @@ -56,29 +56,24 @@ import { use, useMemo } from "react"; const FooContext = React.createContext(null); function Component(props) { - const $ = _c(5); + const $ = _c(2); let t0; if ($[0] !== props.cond) { - t0 = ; + t0 = ( + + + + ); $[0] = props.cond; $[1] = t0; } else { t0 = $[1]; } - let t1; - if ($[2] !== props.value || $[3] !== t0) { - t1 = {t0}; - $[2] = props.value; - $[3] = t0; - $[4] = t1; - } else { - t1 = $[4]; - } - return t1; + return t0; } function Inner(props) { - const $ = _c(7); + const $ = _c(4); let input; input = null; if (props.cond) { @@ -102,22 +97,13 @@ function Inner(props) { const t3 = input; let t4; if ($[2] !== t3) { - t4 = [t3]; + t4 = ; $[2] = t3; $[3] = t4; } else { t4 = $[3]; } - let t5; - if ($[4] !== t4 || $[5] !== output) { - t5 = ; - $[4] = t4; - $[5] = output; - $[6] = t5; - } else { - t5 = $[6]; - } - return t5; + return t4; } export const FIXTURE_ENTRYPOINT = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-operator-method-call.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-operator-method-call.expect.md index 1e6ef8e610748..62c33a74dfc22 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-operator-method-call.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-operator-method-call.expect.md @@ -69,7 +69,7 @@ function Component(props) { } function Inner(props) { - const $ = _c(7); + const $ = _c(4); const input = React.use(FooContext); let t0; let t1; @@ -84,22 +84,13 @@ function Inner(props) { const output = t0; let t2; if ($[2] !== input) { - t2 = [input]; + t2 = ; $[2] = input; $[3] = t2; } else { t2 = $[3]; } - let t3; - if ($[4] !== t2 || $[5] !== output) { - t3 = ; - $[4] = t2; - $[5] = output; - $[6] = t3; - } else { - t3 = $[6]; - } - return t3; + return t2; } export const FIXTURE_ENTRYPOINT = {