Skip to content

Commit f5d99ba

Browse files
committed
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?
1 parent 7f99424 commit f5d99ba

File tree

5 files changed

+99
-18
lines changed

5 files changed

+99
-18
lines changed

compiler/packages/babel-plugin-react-forget/src/Entrypoint/Options.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ export type PluginOptions = {
104104
eslintSuppressionRules?: Array<string> | null | undefined;
105105

106106
flowSuppressions: boolean;
107+
/*
108+
* Ignore 'use no forget' annotations. Helpful during testing but should not be used in production.
109+
*/
110+
ignoreUseNoForget: boolean;
107111
};
108112

109113
const CompilationModeSchema = z.enum([
@@ -172,6 +176,7 @@ export const defaultOptions: PluginOptions = {
172176
enableUseMemoCachePolyfill: false,
173177
eslintSuppressionRules: null,
174178
flowSuppressions: false,
179+
ignoreUseNoForget: false,
175180
} as const;
176181

177182
export function parsePluginOptions(obj: unknown): PluginOptions {

compiler/packages/babel-plugin-react-forget/src/Entrypoint/Program.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,15 @@ function findDirectiveEnablingMemoization(
5151
}
5252

5353
function findDirectiveDisablingMemoization(
54-
directives: t.Directive[]
54+
directives: t.Directive[],
55+
options: PluginOptions
5556
): t.Directive | null {
5657
for (const directive of directives) {
5758
const directiveValue = directive.value.value;
5859
if (
59-
directiveValue === "use no forget" ||
60-
directiveValue === "use no memo"
60+
(directiveValue === "use no forget" ||
61+
directiveValue === "use no memo") &&
62+
!options.ignoreUseNoForget
6163
) {
6264
return directive;
6365
}
@@ -197,12 +199,15 @@ export function compileProgram(
197199
program: NodePath<t.Program>,
198200
pass: CompilerPass
199201
): void {
202+
const options = parsePluginOptions(pass.opts);
203+
200204
// 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+
) {
202208
return;
203209
}
204210

205-
const options = parsePluginOptions(pass.opts);
206211
const environment = parseEnvironmentConfig(pass.opts.environment ?? {});
207212

208213
/*
@@ -400,7 +405,8 @@ function getReactFunctionType(
400405
if (fn.node.body.type === "BlockStatement") {
401406
// Opt-outs disable compilation regardless of mode
402407
const useNoForget = findDirectiveDisablingMemoization(
403-
fn.node.body.directives
408+
fn.node.body.directives,
409+
pass.opts
404410
);
405411
if (useNoForget != null) {
406412
pass.opts.logger?.logEvent(pass.filename, {
Original file line numberDiff line numberDiff line change
@@ -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>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,11 @@ function makePluginOptions(
108108
flowSuppressions = true;
109109
}
110110

111+
let ignoreUseNoForget: boolean = false;
112+
if (firstLine.includes("@ignoreUseNoForget")) {
113+
ignoreUseNoForget = true;
114+
}
115+
111116
const hookPatternMatch = /@hookPattern:"([^"]+)"/.exec(firstLine);
112117
if (
113118
hookPatternMatch &&
@@ -168,6 +173,7 @@ function makePluginOptions(
168173
enableUseMemoCachePolyfill,
169174
eslintSuppressionRules,
170175
flowSuppressions,
176+
ignoreUseNoForget
171177
};
172178
}
173179

@@ -205,18 +211,18 @@ function getEvaluatorPresets(
205211
presets.push(
206212
language === "typescript"
207213
? [
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+
]
220226
: "@babel/preset-flow"
221227
);
222228

0 commit comments

Comments
 (0)