From 027f773179756bab308af2b3f0965f2dba36a067 Mon Sep 17 00:00:00 2001 From: mofeiZ <34200447+mofeiZ@users.noreply.github.com> Date: Mon, 27 Mar 2023 13:27:58 -0400 Subject: [PATCH] [rhir] Patch for reactive computed loads We need to check reactivity of both the operand and its resolved source (if operand is produced by a LoadLocal / PropertyLoad / ComputedLoad). Both the operand and its source can have reactivity. e.g. ```js const o = makeObject(); // source has no reactivity const x = o[props.x]; // x is reactive ``` --- .../ReactiveScopes/InferReactiveIdentifiers.ts | 16 +++++++++++++--- ...puted-load-primitive-as-dependency.expect.md} | 16 ++++++++++------ ... => computed-load-primitive-as-dependency.js} | 0 3 files changed, 23 insertions(+), 9 deletions(-) rename compiler/forget/src/__tests__/fixtures/compiler/{_bug.primitive-computed-load.expect.md => computed-load-primitive-as-dependency.expect.md} (65%) rename compiler/forget/src/__tests__/fixtures/compiler/{_bug.primitive-computed-load.js => computed-load-primitive-as-dependency.js} (100%) diff --git a/compiler/forget/src/ReactiveScopes/InferReactiveIdentifiers.ts b/compiler/forget/src/ReactiveScopes/InferReactiveIdentifiers.ts index c921d8e138..d5fc8a5e20 100644 --- a/compiler/forget/src/ReactiveScopes/InferReactiveIdentifiers.ts +++ b/compiler/forget/src/ReactiveScopes/InferReactiveIdentifiers.ts @@ -45,9 +45,19 @@ class Visitor extends ReactiveFunctionVisitor { if (operand.effect === Effect.Store) { continue; } - const resolvedId: IdentifierId = - state.temporaries.get(operand.identifier.id) ?? operand.identifier.id; - if (state.reactivityMap.get(resolvedId)) { + const ownId = operand.identifier.id; + const resolvedId = state.temporaries.get(ownId); + // We need to check reactivity of both the operand and its resolved source (if operand is + // produced by a LoadLocal / PropertyLoad / ComputedLoad). Both the operand and its source + // can have reactivity. e.g. + // ```js + // const o = makeObject(); // source has no reactivity + // const x = o[props.x]; // x is reactive + // ``` + if ( + state.reactivityMap.get(ownId) || + (resolvedId && state.reactivityMap.get(resolvedId)) + ) { hasReactiveInput = true; break; } diff --git a/compiler/forget/src/__tests__/fixtures/compiler/_bug.primitive-computed-load.expect.md b/compiler/forget/src/__tests__/fixtures/compiler/computed-load-primitive-as-dependency.expect.md similarity index 65% rename from compiler/forget/src/__tests__/fixtures/compiler/_bug.primitive-computed-load.expect.md rename to compiler/forget/src/__tests__/fixtures/compiler/computed-load-primitive-as-dependency.expect.md index 7886b720d0..12aa0694f9 100644 --- a/compiler/forget/src/__tests__/fixtures/compiler/_bug.primitive-computed-load.expect.md +++ b/compiler/forget/src/__tests__/fixtures/compiler/computed-load-primitive-as-dependency.expect.md @@ -18,16 +18,20 @@ function Component(props) { ```javascript function Component(props) { - const $ = React.unstable_useMemoCache(1); + const $ = React.unstable_useMemoCache(2); const a = foo(); - let t0; - if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t0 = bar(a[props.a] + 1); + + const t0 = a[props.a] + 1; + const c_0 = $[0] !== t0; + let t1; + if (c_0) { + t1 = bar(t0); $[0] = t0; + $[1] = t1; } else { - t0 = $[0]; + t1 = $[1]; } - const b = t0; + const b = t1; return b; } diff --git a/compiler/forget/src/__tests__/fixtures/compiler/_bug.primitive-computed-load.js b/compiler/forget/src/__tests__/fixtures/compiler/computed-load-primitive-as-dependency.js similarity index 100% rename from compiler/forget/src/__tests__/fixtures/compiler/_bug.primitive-computed-load.js rename to compiler/forget/src/__tests__/fixtures/compiler/computed-load-primitive-as-dependency.js