[tests] Tests and patch for context variables
--- - [patch] Find context variables within FunctionDeclarations (previously missing) - [todo] Need to fix non-allocating values / variables being DCE'd One approach is to label everything referenced by a lambda as context variables. I couldn't come up with other examples that break without this change, so I wonder if something lighter / hackier works just as well. (My only hesitation is that we may end up losing out on potential optimizations for everything aliased to these variables).
Mofei Zhang committed
Jun 5, 2023 at 15:04 UTC
b160ee85223e80941c2361f28c417df349e7484e
3 files changed
+72
-1
compiler/forget/packages/babel-plugin-react-forget/src/HIR/FindContextIdentifiers.ts
+18
-1
@@ -6,7 +6,9 @@ import { GeneratedSource } from "./HIR";
6
type FindContextIdentifierState = {
7
inLambda: number;
8
currentLambda: Array<
9
- NodePath<t.FunctionExpression> | NodePath<t.ArrowFunctionExpression>
9
+ | NodePath<t.FunctionDeclaration>
10
+ | NodePath<t.FunctionExpression>
11
+ | NodePath<t.ArrowFunctionExpression>
12
>;
13
contextIdentifiers: Set<t.Identifier>;
14
};
@@ -22,6 +24,20 @@ export function findContextIdentifiers(
24
25
func.traverse<FindContextIdentifierState>(
26
{
27
+ FunctionDeclaration: {
28
+ enter(
29
+ fn: NodePath<t.FunctionDeclaration>,
30
+ state: FindContextIdentifierState
31
+ ): void {
32
+ state.currentLambda.push(fn);
33
+ },
34
+ exit(
35
+ fn: NodePath<t.FunctionDeclaration>,
36
+ state: FindContextIdentifierState
37
+ ): void {
38
+ state.currentLambda.pop();
39
+ },
40
+ },
41
FunctionExpression: {
42
enter(
43
fn: NodePath<t.FunctionExpression>,
@@ -69,6 +85,7 @@ export function findContextIdentifiers(
85
86
function handleAssignment(
87
currentLambda:
88
+ | NodePath<t.FunctionDeclaration>
89
| NodePath<t.FunctionExpression>
90
| NodePath<t.ArrowFunctionExpression>,
91
contextIdentifiers: Set<t.Identifier>,
compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/declare-reassign-variable-in-function-declaration.expect.md
new
+46
@@ -0,0 +1,46 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+function Component() {
6
+ let x = null;
7
+ function foo() {
8
+ x = 9;
9
+ }
10
+ const y = bar(foo);
11
+ return <Child y={y} />;
12
+}
13
+
14
+```
15
+
16
+## Code
17
+
18
+```javascript
19
+import { unstable_useMemoCache as useMemoCache } from "react";
20
+function Component() {
21
+ const $ = useMemoCache(2);
22
+ let t0;
23
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
24
+ let x;
25
+ x = null;
26
+ const foo = function foo() {
27
+ x = 9;
28
+ };
29
+ t0 = bar(foo);
30
+ $[0] = t0;
31
+ } else {
32
+ t0 = $[0];
33
+ }
34
+ const y = t0;
35
+ let t1;
36
+ if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
37
+ t1 = <Child y={y} />;
38
+ $[1] = t1;
39
+ } else {
40
+ t1 = $[1];
41
+ }
42
+ return t1;
43
+}
44
+
45
+```
46
+
\ No newline at end of file
compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/declare-reassign-variable-in-function-declaration.js
new
+8
@@ -0,0 +1,8 @@
1
+function Component() {
2
+ let x = null;
3
+ function foo() {
4
+ x = 9;
5
+ }
6
+ const y = bar(foo);
7
+ return <Child y={y} />;
8
+}