diff --git a/compiler/forget/src/HIR/BuildHIR.ts b/compiler/forget/src/HIR/BuildHIR.ts index 3f92439691..2539141fa2 100644 --- a/compiler/forget/src/HIR/BuildHIR.ts +++ b/compiler/forget/src/HIR/BuildHIR.ts @@ -1425,7 +1425,11 @@ function lowerExpression( } } } - case "OptionalMemberExpression": + case "OptionalMemberExpression": { + const expr = exprPath as NodePath; + const { value } = lowerOptionalMemberExpression(builder, expr, null); + return { kind: "LoadLocal", place: value, loc: value.loc }; + } case "MemberExpression": { const expr = exprPath as NodePath< t.MemberExpression | t.OptionalMemberExpression diff --git a/compiler/forget/src/ReactiveScopes/PruneNonEscapingScopes.ts b/compiler/forget/src/ReactiveScopes/PruneNonEscapingScopes.ts index 9ced59c1e5..0f5f75c6a3 100644 --- a/compiler/forget/src/ReactiveScopes/PruneNonEscapingScopes.ts +++ b/compiler/forget/src/ReactiveScopes/PruneNonEscapingScopes.ts @@ -525,7 +525,19 @@ function computeMemoizationInputs( rvalues: [value.value], }; } - case "OptionalExpression": + case "OptionalExpression": { + // Indirection for the inner value, memoized if the value is + const lvalues = []; + if (lvalue !== null) { + lvalues.push({ place: lvalue, level: MemoizationLevel.Conditional }); + } + return { + lvalues: lvalues, + rvalues: [ + ...computeMemoizationInputs(value.value, null, options).rvalues, + ], + }; + } case "RegExpLiteral": case "FunctionExpression": case "TaggedTemplateExpression": diff --git a/compiler/forget/src/__tests__/fixtures/compiler/nested-optional-member-expr.expect.md b/compiler/forget/src/__tests__/fixtures/compiler/nested-optional-member-expr.expect.md index f7ae049619..1b26ffa475 100644 --- a/compiler/forget/src/__tests__/fixtures/compiler/nested-optional-member-expr.expect.md +++ b/compiler/forget/src/__tests__/fixtures/compiler/nested-optional-member-expr.expect.md @@ -18,16 +18,17 @@ import { unstable_useMemoCache as useMemoCache } from "react"; // We should code // (i.e. placing `?` in the correct PropertyLoad) function Component(props) { const $ = useMemoCache(2); - const c_0 = $[0] !== props.a; - let t0; + const t0 = props.a?.b.c.d; + const c_0 = $[0] !== t0; + let t1; if (c_0) { - t0 = foo(props.a?.b.c.d); - $[0] = props.a; - $[1] = t0; + t1 = foo(t0); + $[0] = t0; + $[1] = t1; } else { - t0 = $[1]; + t1 = $[1]; } - const x = t0; + const x = t1; return x; } diff --git a/compiler/forget/src/__tests__/fixtures/compiler/reduce-reactive-cond-memberexpr-join.expect.md b/compiler/forget/src/__tests__/fixtures/compiler/reduce-reactive-cond-memberexpr-join.expect.md index 46988d773f..017c800ec4 100644 --- a/compiler/forget/src/__tests__/fixtures/compiler/reduce-reactive-cond-memberexpr-join.expect.md +++ b/compiler/forget/src/__tests__/fixtures/compiler/reduce-reactive-cond-memberexpr-join.expect.md @@ -38,13 +38,13 @@ import { unstable_useMemoCache as useMemoCache } from "react"; // To preserve th function Component(props) { const $ = useMemoCache(2); - const c_0 = $[0] !== props.a.b; + const c_0 = $[0] !== props.a; let x; if (c_0) { x = []; x.push(props.a?.b); x.push(props.a.b.c); - $[0] = props.a.b; + $[0] = props.a; $[1] = x; } else { x = $[1];