From d81da8e2f55ae9f46384a7a9d73e43fdca26994a Mon Sep 17 00:00:00 2001 From: Joe Savona Date: Mon, 26 Feb 2024 15:04:44 -0800 Subject: [PATCH] Fix JSXMemberExpression dependency calculation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes T173101142 — we previously computed incorrect function expression dependencies for JSXMemberExpressions. This PR applies similar logic to JSXMemberExpression as we use for MemberExpression. ## Test Plan Synced internally, only one file changes output. I manually investigated to confirm — the change is that a function expression's dependencies are more precise and correct. See https://fburl.com/everpaste/4dqewxqv --- .../src/HIR/BuildHIR.ts | 32 ++++++++++++++++++- ...=> jsx-memberexpr-tag-in-lambda.expect.md} | 5 ++- ...bda.js => jsx-memberexpr-tag-in-lambda.js} | 0 3 files changed, 35 insertions(+), 2 deletions(-) rename compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/{bug-jsx-memberexpr-tag-in-lambda.expect.md => jsx-memberexpr-tag-in-lambda.expect.md} (91%) rename compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/{bug-jsx-memberexpr-tag-in-lambda.js => jsx-memberexpr-tag-in-lambda.js} (100%) diff --git a/compiler/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts b/compiler/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts index a3b3142393..e1d3b88619 100644 --- a/compiler/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts +++ b/compiler/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts @@ -3803,6 +3803,7 @@ function gatherCapturedDeps( */ let dependency: | NodePath + | NodePath | NodePath | NodePath; if (path.isJSXOpeningElement()) { @@ -3820,7 +3821,25 @@ function gatherCapturedDeps( "Invalid logic in gatherCapturedDeps" ); baseIdentifier = current; - dependency = current; + + /* + * Get the expression to depend on, which may involve PropertyLoads + * for member expressions + */ + let currentDep: + | NodePath + | NodePath + | NodePath = baseIdentifier; + + while (true) { + const nextDep: null | NodePath = currentDep.parentPath; + if (nextDep && nextDep.isJSXMemberExpression()) { + currentDep = nextDep; + } else { + break; + } + } + dependency = currentDep; } else if (path.isMemberExpression()) { // Calculate baseIdentifier let currentId: NodePath = path; @@ -3885,6 +3904,15 @@ function gatherCapturedDeps( } exprKey += "." + pathTokens.reverse().join("."); + } else if (dependency.isJSXMemberExpression()) { + let pathTokens = []; + let current: NodePath = + dependency; + while (current.isJSXMemberExpression()) { + const property = current.get("property"); + pathTokens.push(property.node.name); + current = current.get("object"); + } } if (!seenPaths.has(exprKey)) { @@ -3895,6 +3923,8 @@ function gatherCapturedDeps( place: lowerIdentifier(builder, dependency), loc: path.node.loc ?? GeneratedSource, }); + } else if (dependency.isJSXMemberExpression()) { + loweredDep = lowerJsxMemberExpression(builder, dependency); } else { loweredDep = lowerExpressionToTemporary(builder, dependency); } diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/bug-jsx-memberexpr-tag-in-lambda.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/jsx-memberexpr-tag-in-lambda.expect.md similarity index 91% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/bug-jsx-memberexpr-tag-in-lambda.expect.md rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/jsx-memberexpr-tag-in-lambda.expect.md index 5030bbb431..b8e2e1acc9 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/bug-jsx-memberexpr-tag-in-lambda.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/jsx-memberexpr-tag-in-lambda.expect.md @@ -25,6 +25,7 @@ import { unstable_useMemoCache as useMemoCache } from "react"; import * as SharedRuntime from "shared-runtime"; function useFoo() { const $ = useMemoCache(2); + const MyLocal = SharedRuntime; let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { t0 = () => ; @@ -49,4 +50,6 @@ export const FIXTURE_ENTRYPOINT = { }; ``` - \ No newline at end of file + +### Eval output +(kind: ok)
4
\ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/bug-jsx-memberexpr-tag-in-lambda.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/jsx-memberexpr-tag-in-lambda.js similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/bug-jsx-memberexpr-tag-in-lambda.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/jsx-memberexpr-tag-in-lambda.js