mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Fix JSXMemberExpression dependency calculation
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
This commit is contained in:
@@ -3803,6 +3803,7 @@ function gatherCapturedDeps(
|
||||
*/
|
||||
let dependency:
|
||||
| NodePath<t.MemberExpression>
|
||||
| NodePath<t.JSXMemberExpression>
|
||||
| NodePath<t.Identifier>
|
||||
| NodePath<t.JSXIdentifier>;
|
||||
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<t.JSXMemberExpression>
|
||||
| NodePath<t.Identifier>
|
||||
| NodePath<t.JSXIdentifier> = baseIdentifier;
|
||||
|
||||
while (true) {
|
||||
const nextDep: null | NodePath<t.Node> = currentDep.parentPath;
|
||||
if (nextDep && nextDep.isJSXMemberExpression()) {
|
||||
currentDep = nextDep;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
dependency = currentDep;
|
||||
} else if (path.isMemberExpression()) {
|
||||
// Calculate baseIdentifier
|
||||
let currentId: NodePath<Expression> = path;
|
||||
@@ -3885,6 +3904,15 @@ function gatherCapturedDeps(
|
||||
}
|
||||
|
||||
exprKey += "." + pathTokens.reverse().join(".");
|
||||
} else if (dependency.isJSXMemberExpression()) {
|
||||
let pathTokens = [];
|
||||
let current: NodePath<t.JSXMemberExpression | t.JSXIdentifier> =
|
||||
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);
|
||||
}
|
||||
|
||||
+4
-1
@@ -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 = () => <MyLocal.Text value={4} />;
|
||||
@@ -49,4 +50,6 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
|
||||
### Eval output
|
||||
(kind: ok) <div>4</div>
|
||||
Reference in New Issue
Block a user