import runtime from "React.unstable_ForgetRuntime"
Imports the runtime from `React.unstable_ForgetRuntime` rather than from a separate module. The hope is that any code that gets transformed already has a dependency on React anyway, so we can avoid adding a new dependency that other systems don't know about. While here, i also cleaned up the `guardThrows` flag (we still parse it if present and warn, rather than throwing, to make it easier to adopt the latest version in various places).
Joseph Savona committed
Oct 21, 2022 at 09:13 UTC
a7450572faeca9c0d976c7620251475a48a13ed3
8 files changed
+52
-64
compiler/forget/scripts/jest/e2e-forget.config.js
+4
-1
@@ -7,4 +7,7 @@
7
8
const makeE2EConfig = require("../jest/makeE2EConfig");
9
10
-module.exports = makeE2EConfig("e2e with forget", true);
10
+const config = makeE2EConfig("e2e with forget", true);
11
+config.setupFilesAfterEnv = ["<rootDir>/../scripts/jest/setupEnvE2E.js"];
12
+
13
+module.exports = config;
compiler/forget/scripts/jest/makeTransform.js
+4
-3
@@ -42,9 +42,10 @@ module.exports = (useForget) => {
42
if (path.node.callee.name === "require") {
43
const arg = path.node.arguments[0];
44
if (arg.type === "StringLiteral") {
45
- if (arg.value === "react-forget-runtime") {
46
- arg.value =
47
- "../../../packages/react-forget-runtime";
45
+ // The compiler adds requires of "React", which is expected to be a wrapper
46
+ // around the "react" package. For tests, we just rewrite the require.
47
+ if (arg.value === "React") {
48
+ arg.value = "react";
49
}
50
}
51
}
compiler/forget/scripts/jest/setupEnvE2E.js
new
+11
@@ -0,0 +1,11 @@
1
+/**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+const React = require("react");
9
+const ForgetRuntime = require("../../packages/react-forget-runtime");
10
+React.unstable_ForgetRuntime = ForgetRuntime;
11
+React.unstable_useMemoCache = ForgetRuntime.unstable_useMemoCache;
compiler/forget/src/BackEnd/JSGen.ts
+27
-43
@@ -52,17 +52,36 @@ export function run(lirProg: LIR.Prog, context: CompilerContext) {
52
if (context.opts.flags.addFreeze) {
53
utils.push("$makeReadOnly");
54
}
55
- if (context.opts.flags.guardThrows) {
56
- utils.push("$reset");
57
- }
55
if (utils.length > 0) {
56
prog.unshiftContainer(
57
"body",
61
- t.importDeclaration(
62
- utils.map((name) =>
63
- t.importSpecifier(t.identifier(name), t.identifier(name))
58
+ t.variableDeclaration("const", [
59
+ t.variableDeclarator(
60
+ t.objectPattern(
61
+ utils.map((util) =>
62
+ t.objectProperty(
63
+ t.identifier(util),
64
+ t.identifier(util),
65
+ false,
66
+ true,
67
+ null
68
+ )
69
+ )
70
+ ),
71
+ t.identifier("$ForgetRuntime")
72
),
65
- t.stringLiteral("react-forget-runtime")
73
+ ])
74
+ );
75
+ prog.unshiftContainer(
76
+ "body",
77
+ t.importDeclaration(
78
+ [
79
+ t.importSpecifier(
80
+ t.identifier("$ForgetRuntime"),
81
+ t.identifier("unstable_ForgetRuntime")
82
+ ),
83
+ ],
84
+ t.stringLiteral("React")
85
)
86
);
87
}
@@ -155,42 +174,7 @@ export function runFunc(
174
const directives = funcBody.node.directives;
175
176
let code = jsFunc.code;
158
- if (context.opts.flags.guardThrows) {
159
- code = [
160
- jsFunc.useMemoCacheCall(lirFunc.memoCache.size),
161
- t.tryStatement(
162
- t.blockStatement(
163
- code.map((node) => {
164
- if (t.isStatement(node)) {
165
- return node;
166
- } else if (t.isExpression(node)) {
167
- return t.expressionStatement(node);
168
- } else {
169
- throw new Error(`unhandled node type: ${node.type}`);
170
- }
171
- })
172
- ),
173
- t.catchClause(
174
- t.identifier("e"),
175
- t.blockStatement([
176
- t.expressionStatement(
177
- t.callExpression(
178
- t.memberExpression(
179
- t.identifier("useMemoCache"),
180
- t.identifier("reset")
181
- ),
182
- [jsFunc.memoCache.id]
183
- )
184
- ),
185
- t.throwStatement(t.identifier("e")),
186
- ])
187
- ),
188
- null
189
- ),
190
- ];
191
- } else {
192
- code.unshift(jsFunc.useMemoCacheCall(lirFunc.memoCache.size));
193
- }
177
+ code.unshift(jsFunc.useMemoCacheCall(lirFunc.memoCache.size));
178
funcBody.replaceWithMultiple(code);
179
180
// recover directives.
compiler/forget/src/CompilerFlags.ts
+6
-10
@@ -73,14 +73,6 @@ export type CompilerFlags = {
73
*/
74
guardHooks: boolean;
75
76
- /**
77
- * Adds a guard around the whole function to ensure the memo cache is reset
78
- * on any throw.
79
- *
80
- * When https://github.com/facebook/react/pull/25143 lands on internally, we
81
- * can remove this flag.
82
- */
83
- guardThrows: boolean;
76
/**
77
* Experimental runtime logging to collect data
78
*/
@@ -98,7 +90,6 @@ export function createCompilerFlags(): CompilerFlags {
90
condCache: false,
91
guardReads: false,
92
guardHooks: false,
101
- guardThrows: false,
93
addFreeze: false,
94
};
95
}
@@ -119,13 +110,18 @@ export function parseCompilerFlags(
110
case "condCache":
111
case "guardReads":
112
case "guardHooks":
122
- case "guardThrows":
113
case "addFreeze":
114
if (typeof value !== "boolean") {
115
throw `Expected boolean for flag '${key}': ${value}`;
116
}
117
res[key] = value;
118
break;
119
+ case "guardThrows": {
120
+ console.warn(
121
+ `the 'guardThrows' flag is no longer supported, this feature is built into React now`
122
+ );
123
+ break;
124
+ }
125
default:
126
if (!ignoreInvalidInput) {
127
throw `Unknown flag: ${key}`;
compiler/forget/src/__tests__/CompilerOptions-test.ts
-1
@@ -53,7 +53,6 @@ describe("CompilerOptions", () => {
53
condCache: true,
54
guardReads: true,
55
guardHooks: true,
56
- guardThrows: true,
56
localMutationThroughFreeVars: false,
57
bailOnMultipleReturns: true,
58
bailOnCapitalizedFunctionCalls: true,
compiler/forget/src/__tests__/e2e/hello.e2e.js
-3
@@ -9,9 +9,6 @@ import * as React from "react";
9
import { render } from "@testing-library/react";
10
import { expectLogsAndClear, log } from "./expectLogs";
11
12
-import { unstable_useMemoCache } from "react-forget-runtime";
13
-React.unstable_useMemoCache = unstable_useMemoCache;
14
-
12
function Hello({ name }) {
13
"use forget";
14
const items = [1, 2, 3].map((item) => <div key={item}>Item {item}</div>);
compiler/forget/src/__tests__/e2e/update-button.e2e.js
-3
@@ -8,9 +8,6 @@
8
import * as React from "react";
9
import { render } from "@testing-library/react";
10
11
-import { unstable_useMemoCache } from "react-forget-runtime";
12
-React.unstable_useMemoCache = unstable_useMemoCache;
13
-
11
function Button({ label }) {
12
const theme = useTheme();
13
const style = computeStyle(theme);