From ecb084c4b8b0e7dddadf5fce73e194a8b58d3187 Mon Sep 17 00:00:00 2001 From: mofeiZ <34200447+mofeiZ@users.noreply.github.com> Date: Fri, 3 Feb 2023 14:52:46 -0500 Subject: [PATCH] [ReactiveHIR] Infer reactive identifiers and promote temporaries Messed up ghstack, this is a duplicate of #1093 --- compiler/forget/src/CompilerPipeline.ts | 8 ++ .../ReactiveScopes/CodegenReactiveFunction.ts | 7 +- .../InferReactiveIdentifiers.ts | 127 ++++++++++++++++++ .../ReactiveScopes/PromoteUsedTemporaries.ts | 37 +++++ .../PropagateScopeDependencies.ts | 29 ++-- compiler/forget/src/ReactiveScopes/index.ts | 1 + .../hir/alias-nested-member-path.expect.md | 16 +-- .../src/__tests__/fixtures/hir/call.expect.md | 16 +-- .../hir/capture-param-mutate.expect.md | 10 +- .../capturing-nested-member-call.expect.md | 14 +- ...ested-member-expr-in-nested-func.expect.md | 14 +- .../capturing-nested-member-expr.expect.md | 14 +- .../fixtures/hir/component.expect.md | 24 ++-- .../fixtures/hir/concise-arrow-expr.expect.md | 22 ++- .../hir/conditional-on-mutable.expect.md | 20 +-- .../fixtures/hir/constructor.expect.md | 16 +-- .../fixtures/hir/hook-call.expect.md | 24 ++-- .../hir/independent-across-if.expect.md | 10 +- .../fixtures/hir/independent.expect.md | 10 +- ...endently-memoize-object-property.expect.md | 10 +- .../hir/interdependent-across-if.expect.md | 10 +- .../fixtures/hir/interdependent.expect.md | 10 +- .../fixtures/hir/jsx-fragment.expect.md | 32 ++--- .../fixtures/hir/jsx-spread.expect.md | 34 ++--- .../hir/logical-expression-object.expect.md | 30 ++--- .../fixtures/hir/logical-expression.expect.md | 30 ++--- .../hir/object-pattern-params.expect.md | 10 +- ...ng-scopes-shadowing-within-block.expect.md | 10 +- .../hir/property-assignment.expect.md | 10 +- .../fixtures/hir/reactive-scopes-if.expect.md | 10 +- .../fixtures/hir/reactive-scopes.expect.md | 10 +- .../hir/reassignment-conditional.expect.md | 10 +- .../reassignment-separate-scopes.expect.md | 10 +- .../fixtures/hir/reassignment.expect.md | 18 ++- .../hir/sequence-expression.expect.md | 8 +- .../__tests__/fixtures/hir/simple.expect.md | 22 +-- .../fixtures/hir/ssa-call-jsx-2.expect.md | 26 ++-- .../fixtures/hir/ssa-call-jsx.expect.md | 16 +-- .../fixtures/hir/ssa-property.expect.md | 8 +- .../hir/switch-non-final-default.expect.md | 10 +- .../__tests__/fixtures/hir/switch.expect.md | 10 +- .../fixtures/hir/ternary-expression.expect.md | 30 ++--- .../type-test-field-load-binary-op.expect.md | 10 +- .../hir/type-test-polymorphic.expect.md | 8 +- .../fixtures/hir/unary-expr.expect.md | 26 +++- .../fixtures/hir/update-expression.expect.md | 12 +- 46 files changed, 505 insertions(+), 344 deletions(-) create mode 100644 compiler/forget/src/ReactiveScopes/InferReactiveIdentifiers.ts create mode 100644 compiler/forget/src/ReactiveScopes/PromoteUsedTemporaries.ts diff --git a/compiler/forget/src/CompilerPipeline.ts b/compiler/forget/src/CompilerPipeline.ts index 88b654485b..7ed34d2351 100644 --- a/compiler/forget/src/CompilerPipeline.ts +++ b/compiler/forget/src/CompilerPipeline.ts @@ -27,6 +27,7 @@ import { flattenReactiveLoops, inferReactiveScopeVariables, mergeOverlappingReactiveScopes, + promoteUsedTemporaries, propagateScopeDependencies, pruneUnusedLabels, pruneUnusedLValues, @@ -128,6 +129,13 @@ export function* run( value: reactiveFunction, }); + promoteUsedTemporaries(reactiveFunction); + yield log({ + kind: "reactive", + name: "promoteUsedTemporaries", + value: reactiveFunction, + }); + pruneUnusedLabels(reactiveFunction); yield log({ kind: "reactive", diff --git a/compiler/forget/src/ReactiveScopes/CodegenReactiveFunction.ts b/compiler/forget/src/ReactiveScopes/CodegenReactiveFunction.ts index db1f42003b..5ad5e480bf 100644 --- a/compiler/forget/src/ReactiveScopes/CodegenReactiveFunction.ts +++ b/compiler/forget/src/ReactiveScopes/CodegenReactiveFunction.ts @@ -185,8 +185,11 @@ function codegenReactiveScope( firstOutputIndex = index; } - // TODO @josephsavona: ensure change and temp variables have non-conflicting names - output.name ??= `t${index}`; + invariant( + output.name != null, + "Expected identifier '@%s' to be named", + output.id + ); const name = convertIdentifier(output); cx.declare(output); diff --git a/compiler/forget/src/ReactiveScopes/InferReactiveIdentifiers.ts b/compiler/forget/src/ReactiveScopes/InferReactiveIdentifiers.ts new file mode 100644 index 0000000000..654353ff0e --- /dev/null +++ b/compiler/forget/src/ReactiveScopes/InferReactiveIdentifiers.ts @@ -0,0 +1,127 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { + Identifier, + ReactiveFunction, + ReactiveInstruction, + ReactiveScope, +} from "../HIR/HIR"; +import { + eachReactiveValueOperand, + ReactiveFunctionVisitor, + visitReactiveFunction, +} from "./visitors"; + +type IdentifierReactivity = Map; +class Environment extends ReactiveFunctionVisitor { + override visitInstruction( + instr: ReactiveInstruction, + reactivityMap: IdentifierReactivity + ) { + this.traverseInstruction(instr, reactivityMap); + const lval = instr.lvalue; + if (lval == null || reactivityMap.get(lval.place.identifier) === true) { + return; + } + const { value } = instr; + let hasReactiveInput = false; + for (const operand of eachReactiveValueOperand(value)) { + // We currently treat free variables (from module or global scope) as + // non-reactive. We may later want type information about specific + // free variables, or a toggle `treatFreeVarsAsReactive`. + if (reactivityMap.get(operand.identifier)) { + hasReactiveInput = true; + break; + } + } + reactivityMap.set(lval.place.identifier, hasReactiveInput); + + if (hasReactiveInput) { + // all mutating effects must also be marked as reactive + for (const operand of eachReactiveValueOperand(value)) { + if (operand.effect === "store" || operand.effect === "mutate") { + // Explicitly compare to `false` here, since absence from the + // map indicates a free variable + // todo [@mofeiZ] add knowledge about free variables + if (reactivityMap.get(operand.identifier) === false) { + reactivityMap.set(operand.identifier, true); + } + } + } + } + } +} +/** + * Computes a map of {@link Place} -> reactivityMap. A Place is reactive if any + * operant used in its construction is reactive. Sources of reactivity are + * {@link ReactiveFunction.params} and HookCall return values (TODO). + * Free values are currently not populated. + * + * This relies on alias analysis done by InferReactiveScopeVariables, which + * creates reactive scopes for variables that mutate together. If one value + * declared in a scope is Reactive, then the rest are marked as reactive as + * well. + * e.g. + * ```javascript + * function foo(props) { + * let x = {}; + * let y = []; + * x.y = y; + * y.push(props.a) + * // references to x are reactive here + * } + * ``` + * This an overestimate when two identifiers have overlapping scope, but + * one is not actually reactive. However, since the same ReactiveBlock now + * produces both identifiers, they are effectively both effective (i.e. + * object creation is not stable) + * e.g. + * ```javascript + * function bar(props) { + * let x = {}; + * let y = []; + * mutate1(x, props); + * mutate2(y); + * } + * ``` + */ +export function inferReactiveIdentifiers( + fn: ReactiveFunction +): Set { + const visitor = new Environment(); + const reactivityMap: IdentifierReactivity = new Map(); + for (const param of fn.params) { + reactivityMap.set(param.identifier, true); + } + const actuallyReactiveScopes = new Set(); + let prevScopesSize = -1; + + // TODO(mofeiZ): avoid fixpoint iteration by keeping a map of identifiers + // read by a ReactiveScope (that are produced outside of it) + while (actuallyReactiveScopes.size > prevScopesSize) { + prevScopesSize = actuallyReactiveScopes.size; + visitReactiveFunction(fn, visitor, reactivityMap); + + for (const [id, value] of reactivityMap) { + const { scope } = id; + if (value && scope != null) { + actuallyReactiveScopes.add(scope); + } + } + for (const [id, _] of reactivityMap) { + if (id.scope && actuallyReactiveScopes.has(id.scope)) { + reactivityMap.set(id, true); + } + } + } + const result = new Set(); + reactivityMap.forEach((isReactive, id) => { + if (isReactive) result.add(id); + }); + return result; +} diff --git a/compiler/forget/src/ReactiveScopes/PromoteUsedTemporaries.ts b/compiler/forget/src/ReactiveScopes/PromoteUsedTemporaries.ts new file mode 100644 index 0000000000..d15dda3236 --- /dev/null +++ b/compiler/forget/src/ReactiveScopes/PromoteUsedTemporaries.ts @@ -0,0 +1,37 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { ReactiveFunction, ReactiveScopeBlock } from "../HIR/HIR"; +import { ReactiveFunctionVisitor, visitReactiveFunction } from "./visitors"; + +type VisitorState = { + nextId: number; +}; +class Visitor extends ReactiveFunctionVisitor { + override visitScope(block: ReactiveScopeBlock, state: VisitorState) { + this.traverseScope(block, state); + for (const dep of block.scope.dependencies) { + const { identifier } = dep.place; + if (identifier.name == null) { + identifier.name = `t${state.nextId++}`; + } + } + // This is technically optional. We could prune ReactiveScopes + // whose outputs are not used in another computation or return + // value. + // Many of our current test fixtures do not return a value, so + // it is better for now to promote (and memoize) every output. + for (const identifier of block.scope.outputs) { + if (identifier.name == null) { + identifier.name = `t${state.nextId++}`; + } + } + } +} +export function promoteUsedTemporaries(fn: ReactiveFunction) { + visitReactiveFunction(fn, new Visitor(), { nextId: 0 }); +} diff --git a/compiler/forget/src/ReactiveScopes/PropagateScopeDependencies.ts b/compiler/forget/src/ReactiveScopes/PropagateScopeDependencies.ts index e8bbc8cd25..71107c4a2e 100644 --- a/compiler/forget/src/ReactiveScopes/PropagateScopeDependencies.ts +++ b/compiler/forget/src/ReactiveScopes/PropagateScopeDependencies.ts @@ -9,7 +9,6 @@ import { Identifier, InstructionId, InstructionKind, - isPrimitiveType, LValue, makeInstructionId, Place, @@ -22,6 +21,7 @@ import { } from "../HIR/HIR"; import { eachInstructionValueOperand } from "../HIR/visitors"; import { assertExhaustive } from "../Utils/utils"; +import { inferReactiveIdentifiers } from "./InferReactiveIdentifiers"; import { eachReactiveValueOperand } from "./visitors"; /** @@ -31,7 +31,7 @@ import { eachReactiveValueOperand } from "./visitors"; * their direct dependencies and those of their child scopes. */ export function propagateScopeDependencies(fn: ReactiveFunction): void { - const context = new Context(); + const context = new Context(inferReactiveIdentifiers(fn)); if (fn.id !== null) { context.declare(fn.id, { kind: DeclKind.Const, id: makeInstructionId(0) }); } @@ -57,9 +57,16 @@ type Scopes = Array; class Context { #declarations: DeclMap = new Map(); #dependencies: Set = new Set(); + #reactiveIdentifiers: Set; + // Produces a de-duplicated mapping of Id -> ReactiveScopeDependency + // This helps with.. temporaries that are created only for property loads + // but can be generalized to all non-allocating temporaries #properties: Map = new Map(); #scopes: Scopes = []; + constructor(reactiveIdentifiers: Set) { + this.#reactiveIdentifiers = reactiveIdentifiers; + } enter(scope: ReactiveScope, fn: () => void): Set { const previousDependencies = this.#dependencies; const scopedDependencies = new Set(); @@ -97,6 +104,10 @@ class Context { return this.#scopes.at(-1)!; } + isReactive(id: Identifier): boolean { + return this.#reactiveIdentifiers.has(id); + } + visitOperand(place: Place): void { this.visitDependency({ place, path: null }); } @@ -133,6 +144,8 @@ class Context { } const decl = this.#declarations.get(maybeDependency.place.identifier); + // if decl is undefined here, then this is a free var + // (all other decls e.g. `let x;` should be initialized in BuildHIR) // Any value used after its defining scope has concluded must be added as an // output of its defining scope. Regardless of whether its a const or not, @@ -323,19 +336,13 @@ function visitInstruction(context: Context, instr: ReactiveInstruction): void { const { lvalue } = instr; visitInstructionValue(context, instr.value, lvalue); if (lvalue !== null && lvalue.kind !== InstructionKind.Reassign) { - const range = lvalue.place.identifier.mutableRange; // TODO: only assign Const if the value is never reassigned - const kind = - range.end === range.start + 1 - ? valueKind(lvalue.place.identifier) - : DeclKind.Dynamic; + const kind = context.isReactive(lvalue.place.identifier) + ? DeclKind.Dynamic + : DeclKind.Const; context.declare(lvalue.place.identifier, { kind, id: lvalue.place.identifier.mutableRange.start, }); } } - -function valueKind(id: Identifier): DeclKind { - return isPrimitiveType(id) ? DeclKind.Const : DeclKind.Dynamic; -} diff --git a/compiler/forget/src/ReactiveScopes/index.ts b/compiler/forget/src/ReactiveScopes/index.ts index b848df584e..9ae824a373 100644 --- a/compiler/forget/src/ReactiveScopes/index.ts +++ b/compiler/forget/src/ReactiveScopes/index.ts @@ -13,6 +13,7 @@ export { flattenReactiveLoops } from "./FlattenReactiveLoops"; export { inferReactiveScopeVariables } from "./InferReactiveScopeVariables"; export { mergeOverlappingReactiveScopes } from "./MergeOverlappingReactiveScopes"; export { printReactiveFunction } from "./PrintReactiveFunction"; +export { promoteUsedTemporaries } from "./PromoteUsedTemporaries"; export { propagateScopeDependencies } from "./PropagateScopeDependencies"; export { pruneTemporaryLValues as pruneUnusedLValues } from "./PruneTemporaryLValues"; export { pruneUnusedLabels } from "./PruneUnusedLabels"; diff --git a/compiler/forget/src/__tests__/fixtures/hir/alias-nested-member-path.expect.md b/compiler/forget/src/__tests__/fixtures/hir/alias-nested-member-path.expect.md index 0c334b707d..503fd28b3a 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/alias-nested-member-path.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/alias-nested-member-path.expect.md @@ -25,25 +25,21 @@ function component() { } else { z = $[0]; } - const c_1 = $[1] !== z; let y; - if (c_1) { + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { y = {}; y.z = z; - $[1] = z; - $[2] = y; + $[1] = y; } else { - y = $[2]; + y = $[1]; } - const c_3 = $[3] !== y; let x; - if (c_3) { + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { x = {}; x.y = y; - $[3] = y; - $[4] = x; + $[2] = x; } else { - x = $[4]; + x = $[2]; } return x; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/call.expect.md b/compiler/forget/src/__tests__/fixtures/hir/call.expect.md index a7c6bca8b9..890ddb71e7 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/call.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/call.expect.md @@ -36,18 +36,14 @@ function Component(props) { a = $[0]; b = $[1]; } - const c_2 = $[2] !== a; - const c_3 = $[3] !== b; - let t4; - if (c_2 || c_3) { - t4 =
; - $[2] = a; - $[3] = b; - $[4] = t4; + let t0; + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { + t0 =
; + $[2] = t0; } else { - t4 = $[4]; + t0 = $[2]; } - return t4; + return t0; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/capture-param-mutate.expect.md b/compiler/forget/src/__tests__/fixtures/hir/capture-param-mutate.expect.md index 3a4cadfef2..ef532db205 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/capture-param-mutate.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/capture-param-mutate.expect.md @@ -48,9 +48,9 @@ function getNativeLogFunction(level) { function getNativeLogFunction(level) { const $ = React.useMemoCache(); const c_0 = $[0] !== level; - let t1; + let t0; if (c_0) { - t1 = function () { + t0 = function () { let str; if (arguments.length === 1 && typeof arguments[0] === "string") { str = arguments[0]; @@ -86,11 +86,11 @@ function getNativeLogFunction(level) { global.nativeLoggingHook(str, logLevel); }; $[0] = level; - $[1] = t1; + $[1] = t0; } else { - t1 = $[1]; + t0 = $[1]; } - return t1; + return t0; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/capturing-nested-member-call.expect.md b/compiler/forget/src/__tests__/fixtures/hir/capturing-nested-member-call.expect.md index 97ca8ed82d..a94432c3a9 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/capturing-nested-member-call.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/capturing-nested-member-call.expect.md @@ -18,19 +18,19 @@ function component(a) { function component(a) { const $ = React.useMemoCache(); const c_0 = $[0] !== a; - let t1; + let t0; if (c_0) { - t1 = { a: a }; + t0 = { a: a }; $[0] = a; - $[1] = t1; + $[1] = t0; } else { - t1 = $[1]; + t0 = $[1]; } - const c_2 = $[2] !== t1; + const c_2 = $[2] !== t0; let z; if (c_2) { - z = { a: t1 }; - $[2] = t1; + z = { a: t0 }; + $[2] = t0; $[3] = z; } else { z = $[3]; diff --git a/compiler/forget/src/__tests__/fixtures/hir/capturing-nested-member-expr-in-nested-func.expect.md b/compiler/forget/src/__tests__/fixtures/hir/capturing-nested-member-expr-in-nested-func.expect.md index c151e82a6a..c61ce1d035 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/capturing-nested-member-expr-in-nested-func.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/capturing-nested-member-expr-in-nested-func.expect.md @@ -20,19 +20,19 @@ function component(a) { function component(a) { const $ = React.useMemoCache(); const c_0 = $[0] !== a; - let t1; + let t0; if (c_0) { - t1 = { a: a }; + t0 = { a: a }; $[0] = a; - $[1] = t1; + $[1] = t0; } else { - t1 = $[1]; + t0 = $[1]; } - const c_2 = $[2] !== t1; + const c_2 = $[2] !== t0; let z; if (c_2) { - z = { a: t1 }; - $[2] = t1; + z = { a: t0 }; + $[2] = t0; $[3] = z; } else { z = $[3]; diff --git a/compiler/forget/src/__tests__/fixtures/hir/capturing-nested-member-expr.expect.md b/compiler/forget/src/__tests__/fixtures/hir/capturing-nested-member-expr.expect.md index 6fd615e2a8..f8d5a90dc3 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/capturing-nested-member-expr.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/capturing-nested-member-expr.expect.md @@ -18,19 +18,19 @@ function component(a) { function component(a) { const $ = React.useMemoCache(); const c_0 = $[0] !== a; - let t1; + let t0; if (c_0) { - t1 = { a: a }; + t0 = { a: a }; $[0] = a; - $[1] = t1; + $[1] = t0; } else { - t1 = $[1]; + t0 = $[1]; } - const c_2 = $[2] !== t1; + const c_2 = $[2] !== t0; let z; if (c_2) { - z = { a: t1 }; - $[2] = t1; + z = { a: t0 }; + $[2] = t0; $[3] = z; } else { z = $[3]; diff --git a/compiler/forget/src/__tests__/fixtures/hir/component.expect.md b/compiler/forget/src/__tests__/fixtures/hir/component.expect.md index 6adcc0b3df..f935af44d7 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/component.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/component.expect.md @@ -74,31 +74,31 @@ function Component(props) { const count = renderedItems.length; const c_5 = $[5] !== count; - let t6; + let t0; if (c_5) { - t6 =

{count} Items

; + t0 =

{count} Items

; $[5] = count; - $[6] = t6; + $[6] = t0; } else { - t6 = $[6]; + t0 = $[6]; } - const c_7 = $[7] !== t6; + const c_7 = $[7] !== t0; const c_8 = $[8] !== renderedItems; - let t9; + let t1; if (c_7 || c_8) { - t9 = ( + t1 = (
- {t6} + {t0} {renderedItems}
); - $[7] = t6; + $[7] = t0; $[8] = renderedItems; - $[9] = t9; + $[9] = t1; } else { - t9 = $[9]; + t1 = $[9]; } - return t9; + return t1; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/concise-arrow-expr.expect.md b/compiler/forget/src/__tests__/fixtures/hir/concise-arrow-expr.expect.md index 64bab0f4c1..88504d3c0b 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/concise-arrow-expr.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/concise-arrow-expr.expect.md @@ -24,25 +24,21 @@ function component() { } const x = t0[0]; const setX = t0[1]; - const c_1 = $[1] !== setX; let handler; - if (c_1) { + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { handler = (v) => setX(v); - $[1] = setX; - $[2] = handler; + $[1] = handler; } else { - handler = $[2]; + handler = $[1]; } - const c_3 = $[3] !== handler; - let t4; - if (c_3) { - t4 = ; - $[3] = handler; - $[4] = t4; + let t1; + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { + t1 = ; + $[2] = t1; } else { - t4 = $[4]; + t1 = $[2]; } - return t4; + return t1; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/conditional-on-mutable.expect.md b/compiler/forget/src/__tests__/fixtures/hir/conditional-on-mutable.expect.md index 7ced099303..98104268a8 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/conditional-on-mutable.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/conditional-on-mutable.expect.md @@ -61,16 +61,16 @@ function ComponentA(props) { } const c_5 = $[5] !== a; const c_6 = $[6] !== b; - let t7; + let t0; if (c_5 || c_6) { - t7 = ; + t0 = ; $[5] = a; $[6] = b; - $[7] = t7; + $[7] = t0; } else { - t7 = $[7]; + t0 = $[7]; } - return t7; + return t0; } function ComponentB(props) { @@ -100,16 +100,16 @@ function ComponentB(props) { } const c_5 = $[5] !== a; const c_6 = $[6] !== b; - let t7; + let t0; if (c_5 || c_6) { - t7 = ; + t0 = ; $[5] = a; $[6] = b; - $[7] = t7; + $[7] = t0; } else { - t7 = $[7]; + t0 = $[7]; } - return t7; + return t0; } function Foo() {} diff --git a/compiler/forget/src/__tests__/fixtures/hir/constructor.expect.md b/compiler/forget/src/__tests__/fixtures/hir/constructor.expect.md index b1435869fc..1a2134d653 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/constructor.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/constructor.expect.md @@ -37,18 +37,14 @@ function Component(props) { a = $[0]; b = $[1]; } - const c_2 = $[2] !== a; - const c_3 = $[3] !== b; - let t4; - if (c_2 || c_3) { - t4 =
; - $[2] = a; - $[3] = b; - $[4] = t4; + let t0; + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { + t0 =
; + $[2] = t0; } else { - t4 = $[4]; + t0 = $[2]; } - return t4; + return t0; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/hook-call.expect.md b/compiler/forget/src/__tests__/fixtures/hir/hook-call.expect.md index bcc9d40e84..dd07baa66c 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/hook-call.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/hook-call.expect.md @@ -34,33 +34,27 @@ function Component(props) { } else { x = $[0]; } - const c_1 = $[1] !== x; let y; - if (c_1) { + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { y = useFreeze(x); - $[1] = x; - $[2] = y; + $[1] = y; } else { - y = $[2]; + y = $[1]; } foo(y, x); - const c_3 = $[3] !== x; - const c_4 = $[4] !== y; - let t5; - if (c_3 || c_4) { - t5 = ( + let t0; + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { + t0 = ( {x} {y} ); - $[3] = x; - $[4] = y; - $[5] = t5; + $[2] = t0; } else { - t5 = $[5]; + t0 = $[2]; } - return t5; + return t0; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/independent-across-if.expect.md b/compiler/forget/src/__tests__/fixtures/hir/independent-across-if.expect.md index 1b554966c2..c4c9591424 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/independent-across-if.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/independent-across-if.expect.md @@ -80,16 +80,16 @@ function Component(props) { } const c_5 = $[5] !== a; const c_6 = $[6] !== b; - let t7; + let t0; if (c_5 || c_6) { - t7 = ; + t0 = ; $[5] = a; $[6] = b; - $[7] = t7; + $[7] = t0; } else { - t7 = $[7]; + t0 = $[7]; } - return t7; + return t0; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/independent.expect.md b/compiler/forget/src/__tests__/fixtures/hir/independent.expect.md index d75aadfb5c..4110de0dd7 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/independent.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/independent.expect.md @@ -59,16 +59,16 @@ function Component(props) { } const c_4 = $[4] !== a; const c_5 = $[5] !== b; - let t6; + let t0; if (c_4 || c_5) { - t6 = ; + t0 = ; $[4] = a; $[5] = b; - $[6] = t6; + $[6] = t0; } else { - t6 = $[6]; + t0 = $[6]; } - return t6; + return t0; } function compute() {} diff --git a/compiler/forget/src/__tests__/fixtures/hir/independently-memoize-object-property.expect.md b/compiler/forget/src/__tests__/fixtures/hir/independently-memoize-object-property.expect.md index 05014d499d..6d67a3e778 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/independently-memoize-object-property.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/independently-memoize-object-property.expect.md @@ -25,16 +25,16 @@ function foo(a, b, c) { x = { a: a }; const c_4 = $[4] !== b; const c_5 = $[5] !== c; - let t6; + let t0; if (c_4 || c_5) { - t6 = [b, c]; + t0 = [b, c]; $[4] = b; $[5] = c; - $[6] = t6; + $[6] = t0; } else { - t6 = $[6]; + t0 = $[6]; } - x.y = t6; + x.y = t0; $[0] = a; $[1] = b; $[2] = c; diff --git a/compiler/forget/src/__tests__/fixtures/hir/interdependent-across-if.expect.md b/compiler/forget/src/__tests__/fixtures/hir/interdependent-across-if.expect.md index 62646e2447..8828da6b15 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/interdependent-across-if.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/interdependent-across-if.expect.md @@ -68,16 +68,16 @@ function Component(props) { } const c_5 = $[5] !== a; const c_6 = $[6] !== b; - let t7; + let t0; if (c_5 || c_6) { - t7 = ; + t0 = ; $[5] = a; $[6] = b; - $[7] = t7; + $[7] = t0; } else { - t7 = $[7]; + t0 = $[7]; } - return t7; + return t0; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/interdependent.expect.md b/compiler/forget/src/__tests__/fixtures/hir/interdependent.expect.md index e0bc030839..bcf1fcf03b 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/interdependent.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/interdependent.expect.md @@ -56,16 +56,16 @@ function Component(props) { } const c_4 = $[4] !== a; const c_5 = $[5] !== b; - let t6; + let t0; if (c_4 || c_5) { - t6 = ; + t0 = ; $[4] = a; $[5] = b; - $[6] = t6; + $[6] = t0; } else { - t6 = $[6]; + t0 = $[6]; } - return t6; + return t0; } function compute() {} diff --git a/compiler/forget/src/__tests__/fixtures/hir/jsx-fragment.expect.md b/compiler/forget/src/__tests__/fixtures/hir/jsx-fragment.expect.md index caa5b712d2..0b33ac6033 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/jsx-fragment.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/jsx-fragment.expect.md @@ -27,32 +27,28 @@ function Foo(props) { } else { t0 = $[0]; } - const c_1 = $[1] !== t0; - let t2; - if (c_1) { - t2 =
{t0}
; - $[1] = t0; - $[2] = t2; + let t1; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + t1 =
{t0}
; + $[1] = t1; } else { - t2 = $[2]; + t1 = $[1]; } - const c_3 = $[3] !== props.greeting; - const c_4 = $[4] !== t2; - let t5; - if (c_3 || c_4) { - t5 = ( + const c_2 = $[2] !== props.greeting; + let t2; + if (c_2) { + t2 = ( <> Hello {props.greeting} - {t2} + {t1} ); - $[3] = props.greeting; - $[4] = t2; - $[5] = t5; + $[2] = props.greeting; + $[3] = t2; } else { - t5 = $[5]; + t2 = $[3]; } - return t5; + return t2; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/jsx-spread.expect.md b/compiler/forget/src/__tests__/fixtures/hir/jsx-spread.expect.md index 260fa1f7c6..1df2983d79 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/jsx-spread.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/jsx-spread.expect.md @@ -16,35 +16,35 @@ function Component(props) { function Component(props) { const $ = React.useMemoCache(); const c_0 = $[0] !== props; - let t1; + let t0; if (c_0) { - t1 = props.cond ? props.foo : props.bar; + t0 = props.cond ? props.foo : props.bar; $[0] = props; - $[1] = t1; + $[1] = t0; } else { - t1 = $[1]; + t0 = $[1]; } - const c_2 = $[2] !== t1; - let t3; + const c_2 = $[2] !== t0; + let t1; if (c_2) { - t3 = { bar: t1 }; - $[2] = t1; - $[3] = t3; + t1 = { bar: t0 }; + $[2] = t0; + $[3] = t1; } else { - t3 = $[3]; + t1 = $[3]; } const c_4 = $[4] !== props; - const c_5 = $[5] !== t3; - let t6; + const c_5 = $[5] !== t1; + let t2; if (c_4 || c_5) { - t6 = ; + t2 = ; $[4] = props; - $[5] = t3; - $[6] = t6; + $[5] = t1; + $[6] = t2; } else { - t6 = $[6]; + t2 = $[6]; } - return t6; + return t2; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/logical-expression-object.expect.md b/compiler/forget/src/__tests__/fixtures/hir/logical-expression-object.expect.md index 01cd635182..39962a6714 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/logical-expression-object.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/logical-expression-object.expect.md @@ -21,37 +21,37 @@ function component(props) { function component(props) { const $ = React.useMemoCache(); const c_0 = $[0] !== props; - let t1; + let t0; if (c_0) { - t1 = props.a || (props.b && props.c && props.d); + t0 = props.a || (props.b && props.c && props.d); $[0] = props; - $[1] = t1; + $[1] = t0; } else { - t1 = $[1]; + t0 = $[1]; } - const a = t1; + const a = t0; const c_2 = $[2] !== props; - let t3; + let t1; if (c_2) { - t3 = (props.a && props.b && props.c) || props.d; + t1 = (props.a && props.b && props.c) || props.d; $[2] = props; - $[3] = t3; + $[3] = t1; } else { - t3 = $[3]; + t1 = $[3]; } - const b = t3; + const b = t1; const c_4 = $[4] !== a; const c_5 = $[5] !== b; - let t6; + let t2; if (c_4 || c_5) { - t6 = { a: a, b: b }; + t2 = { a: a, b: b }; $[4] = a; $[5] = b; - $[6] = t6; + $[6] = t2; } else { - t6 = $[6]; + t2 = $[6]; } - return t6; + return t2; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/logical-expression.expect.md b/compiler/forget/src/__tests__/fixtures/hir/logical-expression.expect.md index 07ffec0304..de302a284c 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/logical-expression.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/logical-expression.expect.md @@ -16,39 +16,39 @@ function component(props) { function component(props) { const $ = React.useMemoCache(); const c_0 = $[0] !== props; - let t1; + let t0; if (c_0) { - t1 = props.a || (props.b && props.c && props.d); + t0 = props.a || (props.b && props.c && props.d); $[0] = props; - $[1] = t1; + $[1] = t0; } else { - t1 = $[1]; + t0 = $[1]; } - const a = t1; + const a = t0; const c_2 = $[2] !== props; - let t3; + let t1; if (c_2) { - t3 = (props.a && props.b && props.c) || props.d; + t1 = (props.a && props.b && props.c) || props.d; $[2] = props; - $[3] = t3; + $[3] = t1; } else { - t3 = $[3]; + t1 = $[3]; } - const b = t3; + const b = t1; const c_4 = $[4] !== a; const c_5 = $[5] !== b; const c_6 = $[6] !== props; - let t7; + let t2; if (c_4 || c_5 || c_6) { - t7 = a ? b : props.c; + t2 = a ? b : props.c; $[4] = a; $[5] = b; $[6] = props; - $[7] = t7; + $[7] = t2; } else { - t7 = $[7]; + t2 = $[7]; } - return t7; + return t2; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/object-pattern-params.expect.md b/compiler/forget/src/__tests__/fixtures/hir/object-pattern-params.expect.md index 628324fd48..a8b4f10915 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/object-pattern-params.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/object-pattern-params.expect.md @@ -37,16 +37,16 @@ function component(t8) { } const c_4 = $[4] !== y; const c_5 = $[5] !== z; - let t6; + let t0; if (c_4 || c_5) { - t6 = { y: y, z: z }; + t0 = { y: y, z: z }; $[4] = y; $[5] = z; - $[6] = t6; + $[6] = t0; } else { - t6 = $[6]; + t0 = $[6]; } - return t6; + return t0; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-shadowing-within-block.expect.md b/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-shadowing-within-block.expect.md index 8ae89b74ff..45af7c1ef3 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-shadowing-within-block.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-shadowing-within-block.expect.md @@ -44,15 +44,15 @@ function foo(a, b, c) { y = $[6]; } const c_7 = $[7] !== y; - let t8; + let t0; if (c_7) { - t8 =
{y}
; + t0 =
{y}
; $[7] = y; - $[8] = t8; + $[8] = t0; } else { - t8 = $[8]; + t0 = $[8]; } - x.push(t8); + x.push(t0); } $[0] = a; $[1] = b; diff --git a/compiler/forget/src/__tests__/fixtures/hir/property-assignment.expect.md b/compiler/forget/src/__tests__/fixtures/hir/property-assignment.expect.md index ca51d65bf2..76ea4fdbe7 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/property-assignment.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/property-assignment.expect.md @@ -37,16 +37,16 @@ function Component(props) { } const c_3 = $[3] !== x; const c_4 = $[4] !== child; - let t5; + let t0; if (c_3 || c_4) { - t5 = {child}; + t0 = {child}; $[3] = x; $[4] = child; - $[5] = t5; + $[5] = t0; } else { - t5 = $[5]; + t0 = $[5]; } - return t5; + return t0; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/reactive-scopes-if.expect.md b/compiler/forget/src/__tests__/fixtures/hir/reactive-scopes-if.expect.md index e2bf8d322a..6650e1607e 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/reactive-scopes-if.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/reactive-scopes-if.expect.md @@ -39,15 +39,15 @@ function foo(a, b, c) { y = $[5]; } const c_6 = $[6] !== y; - let t7; + let t0; if (c_6) { - t7 =
{y}
; + t0 =
{y}
; $[6] = y; - $[7] = t7; + $[7] = t0; } else { - t7 = $[7]; + t0 = $[7]; } - x.push(t7); + x.push(t0); } else { x.push(c); } diff --git a/compiler/forget/src/__tests__/fixtures/hir/reactive-scopes.expect.md b/compiler/forget/src/__tests__/fixtures/hir/reactive-scopes.expect.md index bc91a20009..e655b2d9fe 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/reactive-scopes.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/reactive-scopes.expect.md @@ -37,15 +37,15 @@ function f(a, b) { x = $[2]; } const c_3 = $[3] !== x; - let t4; + let t0; if (c_3) { - t4 =
{x}
; + t0 =
{x}
; $[3] = x; - $[4] = t4; + $[4] = t0; } else { - t4 = $[4]; + t0 = $[4]; } - return t4; + return t0; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md b/compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md index 95aac57679..085ed96e1d 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md @@ -59,16 +59,16 @@ function Component(props) { y.push(props.p2); const c_5 = $[5] !== x$0; const c_6 = $[6] !== y; - let t7; + let t0; if (c_5 || c_6) { - t7 = ; + t0 = ; $[5] = x$0; $[6] = y; - $[7] = t7; + $[7] = t0; } else { - t7 = $[7]; + t0 = $[7]; } - return t7; + return t0; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/reassignment-separate-scopes.expect.md b/compiler/forget/src/__tests__/fixtures/hir/reassignment-separate-scopes.expect.md index 053ee9f94f..efdc1fd9aa 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/reassignment-separate-scopes.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/reassignment-separate-scopes.expect.md @@ -98,9 +98,9 @@ function foo(a, b, c) { } const c_11 = $[11] !== y; const c_12 = $[12] !== x$0; - let t13; + let t0; if (c_11 || c_12) { - t13 = ( + t0 = (
{y} {x$0} @@ -108,11 +108,11 @@ function foo(a, b, c) { ); $[11] = y; $[12] = x$0; - $[13] = t13; + $[13] = t0; } else { - t13 = $[13]; + t0 = $[13]; } - return t13; + return t0; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md b/compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md index 015b228019..280ba31389 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md @@ -45,18 +45,16 @@ function Component(props) { } else { y = $[2]; } - const c_4 = $[4] !== x$0; - const c_5 = $[5] !== y; - let t6; - if (c_4 || c_5) { - t6 = ; - $[4] = x$0; - $[5] = y; - $[6] = t6; + const c_4 = $[4] !== y; + let t0; + if (c_4) { + t0 = ; + $[4] = y; + $[5] = t0; } else { - t6 = $[6]; + t0 = $[5]; } - return t6; + return t0; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/sequence-expression.expect.md b/compiler/forget/src/__tests__/fixtures/hir/sequence-expression.expect.md index 6910409d26..2229452ce8 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/sequence-expression.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/sequence-expression.expect.md @@ -28,19 +28,17 @@ function sequence(props) { } else { t0 = $[0]; } - const c_1 = $[1] !== t0; let x; - if (c_1) { + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { x = t0; while ((foo(), true)) { foo(); 2; x = 2; } - $[1] = t0; - $[2] = x; + $[1] = x; } else { - x = $[2]; + x = $[1]; } return x; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/simple.expect.md b/compiler/forget/src/__tests__/fixtures/hir/simple.expect.md index 585974ae54..fd111438ba 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/simple.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/simple.expect.md @@ -18,22 +18,26 @@ export default function foo(x, y) { const $ = React.useMemoCache(); if (x) { const c_0 = $[0] !== y; - let t1; + let t0; if (c_0) { - t1 = foo(false, y); + t0 = foo(false, y); $[0] = y; - $[1] = t1; + $[1] = t0; } else { - t1 = $[1]; + t0 = $[1]; } - return t1; + return t0; } + + const t1 = y * 10; + const c_2 = $[2] !== t1; let t2; - if ($[2] === Symbol.for("react.memo_cache_sentinel")) { - t2 = [y * 10]; - $[2] = t2; + if (c_2) { + t2 = [t1]; + $[2] = t1; + $[3] = t2; } else { - t2 = $[2]; + t2 = $[3]; } return t2; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx-2.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx-2.expect.md index b7941f12d3..ba8d2049fb 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx-2.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx-2.expect.md @@ -32,14 +32,14 @@ function Component(props) { a = []; b = {}; foo(a, b); - let t2; + let t0; if ($[2] === Symbol.for("react.memo_cache_sentinel")) { - t2 = foo(); - $[2] = t2; + t0 = foo(); + $[2] = t0; } else { - t2 = $[2]; + t0 = $[2]; } - if (t2) { + if (t0) { const _ =
; } @@ -50,18 +50,14 @@ function Component(props) { a = $[0]; b = $[1]; } - const c_3 = $[3] !== a; - const c_4 = $[4] !== b; - let t5; - if (c_3 || c_4) { - t5 =
; - $[3] = a; - $[4] = b; - $[5] = t5; + let t1; + if ($[3] === Symbol.for("react.memo_cache_sentinel")) { + t1 =
; + $[3] = t1; } else { - t5 = $[5]; + t1 = $[3]; } - return t5; + return t1; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx.expect.md index 6983f45d60..22fa95c7cb 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx.expect.md @@ -36,18 +36,14 @@ function Component(props) { a = $[0]; b = $[1]; } - const c_2 = $[2] !== a; - const c_3 = $[3] !== b; - let t4; - if (c_2 || c_3) { - t4 =
; - $[2] = a; - $[3] = b; - $[4] = t4; + let t0; + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { + t0 =
; + $[2] = t0; } else { - t4 = $[4]; + t0 = $[2]; } - return t4; + return t0; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-property.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-property.expect.md index a6b039de63..1a1e9b4cf4 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-property.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-property.expect.md @@ -23,15 +23,13 @@ function foo() { } else { x = $[0]; } - const c_1 = $[1] !== x; let y; - if (c_1) { + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { y = {}; y.x = x; - $[1] = x; - $[2] = y; + $[1] = y; } else { - y = $[2]; + y = $[1]; } return y; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/switch-non-final-default.expect.md b/compiler/forget/src/__tests__/fixtures/hir/switch-non-final-default.expect.md index 6b2c6710d4..8731df2ab8 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/switch-non-final-default.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/switch-non-final-default.expect.md @@ -85,16 +85,16 @@ function Component(props) { y$0.push(props.p4); const c_7 = $[7] !== y$0; const c_8 = $[8] !== child; - let t9; + let t0; if (c_7 || c_8) { - t9 = {child}; + t0 = {child}; $[7] = y$0; $[8] = child; - $[9] = t9; + $[9] = t0; } else { - t9 = $[9]; + t0 = $[9]; } - return t9; + return t0; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md b/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md index 5ed54310bb..079e07d6d9 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md @@ -69,16 +69,16 @@ function Component(props) { y$0.push(props.p4); const c_7 = $[7] !== y$0; const c_8 = $[8] !== child; - let t9; + let t0; if (c_7 || c_8) { - t9 = {child}; + t0 = {child}; $[7] = y$0; $[8] = child; - $[9] = t9; + $[9] = t0; } else { - t9 = $[9]; + t0 = $[9]; } - return t9; + return t0; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/ternary-expression.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ternary-expression.expect.md index ffd55cfbfd..2a6673c632 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ternary-expression.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ternary-expression.expect.md @@ -16,37 +16,37 @@ function ternary(props) { function ternary(props) { const $ = React.useMemoCache(); const c_0 = $[0] !== props; - let t1; + let t0; if (c_0) { - t1 = props.a && props.b ? props.c || props.d : props.e ?? props.f; + t0 = props.a && props.b ? props.c || props.d : props.e ?? props.f; $[0] = props; - $[1] = t1; + $[1] = t0; } else { - t1 = $[1]; + t0 = $[1]; } - const a = t1; + const a = t0; const c_2 = $[2] !== props; - let t3; + let t1; if (c_2) { - t3 = props.a ? (props.b && props.c ? props.d : props.e) : props.f; + t1 = props.a ? (props.b && props.c ? props.d : props.e) : props.f; $[2] = props; - $[3] = t3; + $[3] = t1; } else { - t3 = $[3]; + t1 = $[3]; } - const b = t3; + const b = t1; const c_4 = $[4] !== a; const c_5 = $[5] !== b; - let t6; + let t2; if (c_4 || c_5) { - t6 = a ? b : (null, null); + t2 = a ? b : (null, null); $[4] = a; $[5] = b; - $[6] = t6; + $[6] = t2; } else { - t6 = $[6]; + t2 = $[6]; } - return t6; + return t2; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/type-test-field-load-binary-op.expect.md b/compiler/forget/src/__tests__/fixtures/hir/type-test-field-load-binary-op.expect.md index 6af4d7a98b..783a26d730 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/type-test-field-load-binary-op.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/type-test-field-load-binary-op.expect.md @@ -34,16 +34,12 @@ function component() { } else { t1 = $[1]; } - const c_2 = $[2] !== t0; - const c_3 = $[3] !== t1; let x; - if (c_2 || c_3) { + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { x = { u: t0, v: t1 }; - $[2] = t0; - $[3] = t1; - $[4] = x; + $[2] = x; } else { - x = $[4]; + x = $[2]; } const u = x.u; const v = x.v; diff --git a/compiler/forget/src/__tests__/fixtures/hir/type-test-polymorphic.expect.md b/compiler/forget/src/__tests__/fixtures/hir/type-test-polymorphic.expect.md index 69c7e8552b..1dd78727d0 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/type-test-polymorphic.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/type-test-polymorphic.expect.md @@ -38,18 +38,16 @@ function component() { } else { o = $[1]; } - const c_2 = $[2] !== o; let x; - if (c_2) { + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { x = {}; x.t = p; const z = x.t; x.t = o; - $[2] = o; - $[3] = x; + $[2] = x; } else { - x = $[3]; + x = $[2]; } const y = x.t; diff --git a/compiler/forget/src/__tests__/fixtures/hir/unary-expr.expect.md b/compiler/forget/src/__tests__/fixtures/hir/unary-expr.expect.md index 7ca618c6f6..0f26f4d4fa 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/unary-expr.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/unary-expr.expect.md @@ -37,14 +37,28 @@ function component(a) { const m = !t.t; const e = ~t.t; const f = typeof t.t; - let t2; - if ($[2] === Symbol.for("react.memo_cache_sentinel")) { - t2 = { z: z, p: p, q: q, n: n, m: m, e: e, f: f }; - $[2] = t2; + const c_2 = $[2] !== z; + const c_3 = $[3] !== p; + const c_4 = $[4] !== q; + const c_5 = $[5] !== n; + const c_6 = $[6] !== m; + const c_7 = $[7] !== e; + const c_8 = $[8] !== f; + let t0; + if (c_2 || c_3 || c_4 || c_5 || c_6 || c_7 || c_8) { + t0 = { z: z, p: p, q: q, n: n, m: m, e: e, f: f }; + $[2] = z; + $[3] = p; + $[4] = q; + $[5] = n; + $[6] = m; + $[7] = e; + $[8] = f; + $[9] = t0; } else { - t2 = $[2]; + t0 = $[9]; } - return t2; + return t0; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/update-expression.expect.md b/compiler/forget/src/__tests__/fixtures/hir/update-expression.expect.md index fdbff2d6eb..5f90acd09d 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/update-expression.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/update-expression.expect.md @@ -21,12 +21,18 @@ function foo(props) { const y = x$0; const x$1 = x$0 - 1; const z = x$1; + const c_0 = $[0] !== x$1; + const c_1 = $[1] !== y; + const c_2 = $[2] !== z; let t0; - if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + if (c_0 || c_1 || c_2) { t0 = { x: x$1, y: y, z: z }; - $[0] = t0; + $[0] = x$1; + $[1] = y; + $[2] = z; + $[3] = t0; } else { - t0 = $[0]; + t0 = $[3]; } return t0; }