diff --git a/compiler/forget/src/ReactiveScopes/MemoizeFbtOperandsInSameScope.ts b/compiler/forget/src/ReactiveScopes/MemoizeFbtOperandsInSameScope.ts index f326fac6b7..09d1265b5a 100644 --- a/compiler/forget/src/ReactiveScopes/MemoizeFbtOperandsInSameScope.ts +++ b/compiler/forget/src/ReactiveScopes/MemoizeFbtOperandsInSameScope.ts @@ -65,20 +65,20 @@ class Transform extends ReactiveFunctionVisitor { (value.kind === "CallExpression" && this.fbtValues.has(value.callee.identifier.id)) ) { + const fbtScope = lvalue.identifier.scope; + if (fbtScope === null) { + return; + } + // if the JSX element's tag was `fbt`, mark all its operands // to ensure that they end up in the same scope as the jsx element // itself. for (const operand of eachReactiveValueOperand(value)) { - operand.identifier.scope = lvalue.identifier.scope; - operand.identifier.mutableRange.end = - lvalue.identifier.mutableRange.end; + operand.identifier.scope = fbtScope; // Expand the jsx element's range to account for its operands - lvalue.identifier.mutableRange.start = makeInstructionId( - Math.min( - lvalue.identifier.mutableRange.start, - operand.identifier.mutableRange.start - ) + fbtScope.range.start = makeInstructionId( + Math.min(fbtScope.range.start, operand.identifier.mutableRange.start) ); } } diff --git a/compiler/forget/src/__tests__/fixtures/compiler/fbt-template-string-same-scope.expect.md b/compiler/forget/src/__tests__/fixtures/compiler/fbt-template-string-same-scope.expect.md new file mode 100644 index 0000000000..45ee3384b6 --- /dev/null +++ b/compiler/forget/src/__tests__/fixtures/compiler/fbt-template-string-same-scope.expect.md @@ -0,0 +1,61 @@ + +## Input + +```javascript +import fbt from "fbt"; + +export function Component(props) { + let count = 0; + if (props.items) { + count = props.items.length; + } + return ( + + {fbt( + `for ${fbt.param("count", count)} experiences`, + `Label for the number of items`, + { project: "public" } + )} + + ); +} + +``` + +## Code + +```javascript +import { unstable_useMemoCache as useMemoCache } from "react"; +import fbt from "fbt"; + +export function Component(props) { + const $ = useMemoCache(4); + let count = 0; + if (props.items) { + count = props.items.length; + } + const c_0 = $[0] !== count; + let t0; + if (c_0) { + t0 = fbt._("for {count} experiences", [fbt._param("count", count)], { + hk: "nmYpm", + }); + $[0] = count; + $[1] = t0; + } else { + t0 = $[1]; + } + const c_2 = $[2] !== t0; + let t1; + if (c_2) { + t1 = {t0}; + $[2] = t0; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; +} + +``` + \ No newline at end of file diff --git a/compiler/forget/src/__tests__/fixtures/compiler/fbt-template-string-same-scope.js b/compiler/forget/src/__tests__/fixtures/compiler/fbt-template-string-same-scope.js new file mode 100644 index 0000000000..09c531c33b --- /dev/null +++ b/compiler/forget/src/__tests__/fixtures/compiler/fbt-template-string-same-scope.js @@ -0,0 +1,17 @@ +import fbt from "fbt"; + +export function Component(props) { + let count = 0; + if (props.items) { + count = props.items.length; + } + return ( + + {fbt( + `for ${fbt.param("count", count)} experiences`, + `Label for the number of items`, + { project: "public" } + )} + + ); +}