@samitouri / QOS-React-2 / commits / a21660de00

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.

Joe Savona committed Jun 14, 2023 at 14:04 UTC a21660de006416018d1fc799be92540417fcb8bb
3 files changed +79 -1
compiler/forget/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts
+1 -1
@@ -2344,7 +2344,7 @@ function lowerFunctionExpression(
2344 if (expr.isFunctionExpression()) {
2345 name = expr.get("id")?.node?.name ?? null;
2346 }
2347 - const componentScope: Scope = expr.scope.parent.getFunctionParent()!;
2347 + const componentScope: Scope = builder.parentFunction.scope;
2348 const captured = gatherCapturedDeps(builder, expr, componentScope);
2349
2350 // TODO(gsn): In the future, we could only pass in the context identifiers
compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/repro.expect.md new
+64
@@ -0,0 +1,64 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function Component(props) {
6 + const item = props.item;
7 + const thumbnails = [];
8 + const baseVideos = getBaseVideos(item);
9 + useMemo(() => {
10 + baseVideos.forEach((video) => {
11 + const baseVideo = video.hasBaseVideo;
12 + if (Boolean(baseVideo)) {
13 + thumbnails.push({ extraVideo: true });
14 + }
15 + });
16 + });
17 + return <FlatList baseVideos={baseVideos} items={thumbnails} />;
18 +}
19 +
20 +```
21 +
22 +## Code
23 +
24 +```javascript
25 +import { unstable_useMemoCache as useMemoCache } from "react";
26 +function Component(props) {
27 + const $ = useMemoCache(6);
28 + const item = props.item;
29 + const c_0 = $[0] !== item;
30 + let baseVideos;
31 + let thumbnails;
32 + if (c_0) {
33 + thumbnails = [];
34 + baseVideos = getBaseVideos(item);
35 +
36 + baseVideos.forEach((video) => {
37 + const baseVideo = video.hasBaseVideo;
38 + if (Boolean(baseVideo)) {
39 + thumbnails.push({ extraVideo: true });
40 + }
41 + });
42 + $[0] = item;
43 + $[1] = baseVideos;
44 + $[2] = thumbnails;
45 + } else {
46 + baseVideos = $[1];
47 + thumbnails = $[2];
48 + }
49 + const c_3 = $[3] !== baseVideos;
50 + const c_4 = $[4] !== thumbnails;
51 + let t0;
52 + if (c_3 || c_4) {
53 + t0 = <FlatList baseVideos={baseVideos} items={thumbnails} />;
54 + $[3] = baseVideos;
55 + $[4] = thumbnails;
56 + $[5] = t0;
57 + } else {
58 + t0 = $[5];
59 + }
60 + return t0;
61 +}
62 +
63 +```
64 +
\ No newline at end of file
compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/repro.js new
+14
@@ -0,0 +1,14 @@
1 +function Component(props) {
2 + const item = props.item;
3 + const thumbnails = [];
4 + const baseVideos = getBaseVideos(item);
5 + useMemo(() => {
6 + baseVideos.forEach((video) => {
7 + const baseVideo = video.hasBaseVideo;
8 + if (Boolean(baseVideo)) {
9 + thumbnails.push({ extraVideo: true });
10 + }
11 + });
12 + });
13 + return <FlatList baseVideos={baseVideos} items={thumbnails} />;
14 +}