Fix calculation of nested function dependencies

We were incorrectly calculating the dependencies of nested lambdas, because the 
"component" scope was incorrectly set to the next closest parent rather than 
outermost React function (component/hook) being compiled.
This commit is contained in:
Joe Savona
2023-06-14 14:04:26 -07:00
parent a8fff7cc5c
commit a21660de00
3 changed files with 79 additions and 1 deletions
@@ -2344,7 +2344,7 @@ function lowerFunctionExpression(
if (expr.isFunctionExpression()) {
name = expr.get("id")?.node?.name ?? null;
}
const componentScope: Scope = expr.scope.parent.getFunctionParent()!;
const componentScope: Scope = builder.parentFunction.scope;
const captured = gatherCapturedDeps(builder, expr, componentScope);
// TODO(gsn): In the future, we could only pass in the context identifiers
@@ -0,0 +1,64 @@
## Input
```javascript
function Component(props) {
const item = props.item;
const thumbnails = [];
const baseVideos = getBaseVideos(item);
useMemo(() => {
baseVideos.forEach((video) => {
const baseVideo = video.hasBaseVideo;
if (Boolean(baseVideo)) {
thumbnails.push({ extraVideo: true });
}
});
});
return <FlatList baseVideos={baseVideos} items={thumbnails} />;
}
```
## Code
```javascript
import { unstable_useMemoCache as useMemoCache } from "react";
function Component(props) {
const $ = useMemoCache(6);
const item = props.item;
const c_0 = $[0] !== item;
let baseVideos;
let thumbnails;
if (c_0) {
thumbnails = [];
baseVideos = getBaseVideos(item);
baseVideos.forEach((video) => {
const baseVideo = video.hasBaseVideo;
if (Boolean(baseVideo)) {
thumbnails.push({ extraVideo: true });
}
});
$[0] = item;
$[1] = baseVideos;
$[2] = thumbnails;
} else {
baseVideos = $[1];
thumbnails = $[2];
}
const c_3 = $[3] !== baseVideos;
const c_4 = $[4] !== thumbnails;
let t0;
if (c_3 || c_4) {
t0 = <FlatList baseVideos={baseVideos} items={thumbnails} />;
$[3] = baseVideos;
$[4] = thumbnails;
$[5] = t0;
} else {
t0 = $[5];
}
return t0;
}
```
@@ -0,0 +1,14 @@
function Component(props) {
const item = props.item;
const thumbnails = [];
const baseVideos = getBaseVideos(item);
useMemo(() => {
baseVideos.forEach((video) => {
const baseVideo = video.hasBaseVideo;
if (Boolean(baseVideo)) {
thumbnails.push({ extraVideo: true });
}
});
});
return <FlatList baseVideos={baseVideos} items={thumbnails} />;
}