Add config option to ignore 'use no forget' directives
This will let us test without taking into account the existing 'use no forget' directives to better understand what validations we may need to build. There are two other files that look for this directive that do not seem to take compiler options: 1. https://github.com/facebook/react-forget/blob/408617ec8a5caa815f61d4204cb3fec0775593ca/react/scripts/babel/transform-forget.js#L25 2. https://github.com/facebook/react-forget/blob/408617ec8a5caa815f61d4204cb3fec0775593ca/packages/babel-plugin-react-forget/scripts/jest/makeTransform.ts#L119 Do I need to do anything for those?
Jordan Brown committed
Mar 4, 2024 at 19:00 UTC
f5d99baf8e64530473fac5fe0dd2bd489f3bf8fc
5 files changed
+99
-18
compiler/packages/babel-plugin-react-forget/src/Entrypoint/Options.ts
+5
@@ -104,6 +104,10 @@ export type PluginOptions = {
104
eslintSuppressionRules?: Array<string> | null | undefined;
105
106
flowSuppressions: boolean;
107
+ /*
108
+ * Ignore 'use no forget' annotations. Helpful during testing but should not be used in production.
109
+ */
110
+ ignoreUseNoForget: boolean;
111
};
112
113
const CompilationModeSchema = z.enum([
@@ -172,6 +176,7 @@ export const defaultOptions: PluginOptions = {
176
enableUseMemoCachePolyfill: false,
177
eslintSuppressionRules: null,
178
flowSuppressions: false,
179
+ ignoreUseNoForget: false,
180
} as const;
181
182
export function parsePluginOptions(obj: unknown): PluginOptions {
compiler/packages/babel-plugin-react-forget/src/Entrypoint/Program.ts
+12
-6
@@ -51,13 +51,15 @@ function findDirectiveEnablingMemoization(
51
}
52
53
function findDirectiveDisablingMemoization(
54
- directives: t.Directive[]
54
+ directives: t.Directive[],
55
+ options: PluginOptions
56
): t.Directive | null {
57
for (const directive of directives) {
58
const directiveValue = directive.value.value;
59
if (
59
- directiveValue === "use no forget" ||
60
- directiveValue === "use no memo"
60
+ (directiveValue === "use no forget" ||
61
+ directiveValue === "use no memo") &&
62
+ !options.ignoreUseNoForget
63
) {
64
return directive;
65
}
@@ -197,12 +199,15 @@ export function compileProgram(
199
program: NodePath<t.Program>,
200
pass: CompilerPass
201
): void {
202
+ const options = parsePluginOptions(pass.opts);
203
+
204
// Top level "use no forget", skip this file entirely
201
- if (findDirectiveDisablingMemoization(program.node.directives) != null) {
205
+ if (
206
+ findDirectiveDisablingMemoization(program.node.directives, options) != null
207
+ ) {
208
return;
209
}
210
205
- const options = parsePluginOptions(pass.opts);
211
const environment = parseEnvironmentConfig(pass.opts.environment ?? {});
212
213
/*
@@ -400,7 +405,8 @@ function getReactFunctionType(
405
if (fn.node.body.type === "BlockStatement") {
406
// Opt-outs disable compilation regardless of mode
407
const useNoForget = findDirectiveDisablingMemoization(
403
- fn.node.body.directives
408
+ fn.node.body.directives,
409
+ pass.opts
410
);
411
if (useNoForget != null) {
412
pass.opts.logger?.logEvent(pass.filename, {
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/ignore-use-no-forget.expect.md
new
+53
@@ -0,0 +1,53 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+// @ignoreUseNoForget
6
+function Component(prop) {
7
+ "use no forget";
8
+ const result = prop.x.toFixed();
9
+ return <div>{result}</div>;
10
+}
11
+
12
+export const FIXTURE_ENTRYPOINT = {
13
+ fn: Component,
14
+ params: [{ x: 1 }],
15
+};
16
+
17
+```
18
+
19
+## Code
20
+
21
+```javascript
22
+import { unstable_useMemoCache as useMemoCache } from "react"; // @ignoreUseNoForget
23
+function Component(prop) {
24
+ const $ = useMemoCache(4);
25
+ let t0;
26
+ if ($[0] !== prop.x) {
27
+ t0 = prop.x.toFixed();
28
+ $[0] = prop.x;
29
+ $[1] = t0;
30
+ } else {
31
+ t0 = $[1];
32
+ }
33
+ const result = t0;
34
+ let t1;
35
+ if ($[2] !== result) {
36
+ t1 = <div>{result}</div>;
37
+ $[2] = result;
38
+ $[3] = t1;
39
+ } else {
40
+ t1 = $[3];
41
+ }
42
+ return t1;
43
+}
44
+
45
+export const FIXTURE_ENTRYPOINT = {
46
+ fn: Component,
47
+ params: [{ x: 1 }],
48
+};
49
+
50
+```
51
+
52
+### Eval output
53
+(kind: ok) <div>1</div>
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/ignore-use-no-forget.js
new
+11
@@ -0,0 +1,11 @@
1
+// @ignoreUseNoForget
2
+function Component(prop) {
3
+ "use no forget";
4
+ const result = prop.x.toFixed();
5
+ return <div>{result}</div>;
6
+}
7
+
8
+export const FIXTURE_ENTRYPOINT = {
9
+ fn: Component,
10
+ params: [{ x: 1 }],
11
+};
compiler/packages/snap/src/compiler.ts
+18
-12
@@ -108,6 +108,11 @@ function makePluginOptions(
108
flowSuppressions = true;
109
}
110
111
+ let ignoreUseNoForget: boolean = false;
112
+ if (firstLine.includes("@ignoreUseNoForget")) {
113
+ ignoreUseNoForget = true;
114
+ }
115
+
116
const hookPatternMatch = /@hookPattern:"([^"]+)"/.exec(firstLine);
117
if (
118
hookPatternMatch &&
@@ -168,6 +173,7 @@ function makePluginOptions(
173
enableUseMemoCachePolyfill,
174
eslintSuppressionRules,
175
flowSuppressions,
176
+ ignoreUseNoForget
177
};
178
}
179
@@ -205,18 +211,18 @@ function getEvaluatorPresets(
211
presets.push(
212
language === "typescript"
213
? [
208
- "@babel/preset-typescript",
209
- {
210
- /**
211
- * onlyRemoveTypeImports needs to be set as fbt imports
212
- * would otherwise be removed by this pass.
213
- * https://github.com/facebook/fbt/issues/49
214
- * https://github.com/facebook/sfbt/issues/72
215
- * https://dev.to/retyui/how-to-add-support-typescript-for-fbt-an-internationalization-framework-3lo0
216
- */
217
- onlyRemoveTypeImports: true,
218
- },
219
- ]
214
+ "@babel/preset-typescript",
215
+ {
216
+ /**
217
+ * onlyRemoveTypeImports needs to be set as fbt imports
218
+ * would otherwise be removed by this pass.
219
+ * https://github.com/facebook/fbt/issues/49
220
+ * https://github.com/facebook/sfbt/issues/72
221
+ * https://dev.to/retyui/how-to-add-support-typescript-for-fbt-an-internationalization-framework-3lo0
222
+ */
223
+ onlyRemoveTypeImports: true,
224
+ },
225
+ ]
226
: "@babel/preset-flow"
227
);
228