[config] Change compiler defaults to prepare for oss
Mofei Zhang committed
Mar 29, 2024 at 09:31 UTC
5656d5f078ee071ccd564e59d21d9a30d89e7f0a
30 files changed
+162
-131
compiler/packages/babel-plugin-react-forget/src/Entrypoint/Options.ts
+1
-1
@@ -173,7 +173,7 @@ export type Logger = {
173
174
export const defaultOptions: PluginOptions = {
175
compilationMode: "infer",
176
- panicThreshold: "CRITICAL_ERRORS",
176
+ panicThreshold: "NONE",
177
environment: {},
178
logger: null,
179
gating: null,
compiler/packages/babel-plugin-react-forget/src/HIR/Environment.ts
+5
-5
@@ -156,7 +156,7 @@ const EnvironmentConfigSchema = z.object({
156
* that the memoization was preserved. This can be useful for determining where referential equalities
157
* may change under Forget.
158
*/
159
- validatePreserveExistingMemoizationGuarantees: z.boolean().default(false),
159
+ validatePreserveExistingMemoizationGuarantees: z.boolean().default(true),
160
161
// 🌲
162
enableForest: z.boolean().default(false),
@@ -192,7 +192,7 @@ const EnvironmentConfigSchema = z.object({
192
* Validates that setState is not unconditionally called during render, as it can lead to
193
* infinite loops.
194
*/
195
- validateNoSetStateInRender: z.boolean().default(false),
195
+ validateNoSetStateInRender: z.boolean().default(true),
196
197
/**
198
* Validates that the dependencies of all effect hooks are memoized. This helps ensure
@@ -214,7 +214,7 @@ const EnvironmentConfigSchema = z.object({
214
* in this allowlist. You can enable this validation with no additional allowlisted calls by setting
215
* this option to the empty array.
216
*/
217
- validateNoCapitalizedCalls: z.nullable(z.array(z.string())).default(null),
217
+ validateNoCapitalizedCalls: z.nullable(z.array(z.string())).default([]),
218
219
/*
220
* When enabled, the compiler assumes that hooks follow the Rules of React:
@@ -223,7 +223,7 @@ const EnvironmentConfigSchema = z.object({
223
* - Hooks may memoize the result they return, thus the return value is
224
* assumed frozen.
225
*/
226
- enableAssumeHooksFollowRulesOfReact: z.boolean().default(false),
226
+ enableAssumeHooksFollowRulesOfReact: z.boolean().default(true),
227
228
/**
229
* When enabled, the compiler assumes that any values are not subsequently
@@ -231,7 +231,7 @@ const EnvironmentConfigSchema = z.object({
231
* if a value `x` is referenced inside a function expression passed to `useEffect`,
232
* then this flag will assume that `x` is not subusequently modified.
233
*/
234
- enableTransitivelyFreezeFunctionExpressions: z.boolean().default(false),
234
+ enableTransitivelyFreezeFunctionExpressions: z.boolean().default(true),
235
236
/*
237
* When enabled, removes *all* memoization from the function: this includes
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/conditional-early-return.expect.md
+6
-6
@@ -76,12 +76,12 @@ function ComponentA(props) {
76
let t0;
77
if ($[0] !== props) {
78
t0 = Symbol.for("react.early_return_sentinel");
79
- bb7: {
79
+ bb8: {
80
a_DEBUG = [];
81
a_DEBUG.push(props.a);
82
if (props.b) {
83
t0 = null;
84
- break bb7;
84
+ break bb8;
85
}
86
87
a_DEBUG.push(props.d);
@@ -130,13 +130,13 @@ function ComponentC(props) {
130
let t0;
131
if ($[0] !== props) {
132
t0 = Symbol.for("react.early_return_sentinel");
133
- bb7: {
133
+ bb8: {
134
a = [];
135
a.push(props.a);
136
if (props.b) {
137
a.push(props.c);
138
t0 = null;
139
- break bb7;
139
+ break bb8;
140
}
141
142
a.push(props.d);
@@ -163,13 +163,13 @@ function ComponentD(props) {
163
let t0;
164
if ($[0] !== props) {
165
t0 = Symbol.for("react.early_return_sentinel");
166
- bb7: {
166
+ bb8: {
167
a = [];
168
a.push(props.a);
169
if (props.b) {
170
a.push(props.c);
171
t0 = a;
172
- break bb7;
172
+ break bb8;
173
}
174
175
a.push(props.d);
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/early-return-nested-early-return-within-reactive-scope.expect.md
+4
-4
@@ -35,7 +35,7 @@ function Component(props) {
35
let t0;
36
if ($[0] !== props) {
37
t0 = Symbol.for("react.early_return_sentinel");
38
- bb11: {
38
+ bb12: {
39
const x = [];
40
if (props.cond) {
41
x.push(props.a);
@@ -51,11 +51,11 @@ function Component(props) {
51
const y = t1;
52
x.push(y);
53
t0 = x;
54
- break bb11;
54
+ break bb12;
55
}
56
57
t0 = x;
58
- break bb11;
58
+ break bb12;
59
} else {
60
let t1;
61
if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
@@ -65,7 +65,7 @@ function Component(props) {
65
t1 = $[4];
66
}
67
t0 = t1;
68
- break bb11;
68
+ break bb12;
69
}
70
}
71
$[0] = props;
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/early-return-no-declarations-reassignments-dependencies.expect.md
+2
-2
@@ -73,12 +73,12 @@ function Component(props) {
73
let t0;
74
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
75
t0 = Symbol.for("react.early_return_sentinel");
76
- bb8: {
76
+ bb9: {
77
const x = [];
78
if (ENABLE_FEATURE) {
79
x.push(42);
80
t0 = x;
81
- break bb8;
81
+ break bb9;
82
} else {
83
console.log("fallthrough");
84
}
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/early-return-within-reactive-scope.expect.md
+3
-3
@@ -49,12 +49,12 @@ function Component(props) {
49
let t0;
50
if ($[0] !== props) {
51
t0 = Symbol.for("react.early_return_sentinel");
52
- bb8: {
52
+ bb9: {
53
const x = [];
54
if (props.cond) {
55
x.push(props.a);
56
t0 = x;
57
- break bb8;
57
+ break bb9;
58
} else {
59
let t1;
60
if ($[2] !== props.b) {
@@ -65,7 +65,7 @@ function Component(props) {
65
t1 = $[3];
66
}
67
t0 = t1;
68
- break bb8;
68
+ break bb9;
69
}
70
}
71
$[0] = props;
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/for-of-mutate.expect.md
+5
-15
@@ -2,19 +2,13 @@
2
## Input
3
4
```javascript
5
-import {
6
- makeObject_Primitives,
7
- mutateAndReturn,
8
- Stringify,
9
-} from "shared-runtime";
5
+import { makeObject_Primitives, mutateAndReturn, toJSON } from "shared-runtime";
6
7
function Component(_props) {
8
const collection = [makeObject_Primitives()];
9
const results = [];
10
for (const item of collection) {
15
- results.push(
16
- <div key={Stringify(item)}>{Stringify(mutateAndReturn(item))}</div>
17
- );
11
+ results.push(<div key={toJSON(item)}>{toJSON(mutateAndReturn(item))}</div>);
12
}
13
return <div>{results}</div>;
14
}
@@ -31,11 +25,7 @@ export const FIXTURE_ENTRYPOINT = {
25
26
```javascript
27
import { unstable_useMemoCache as useMemoCache } from "react";
34
-import {
35
- makeObject_Primitives,
36
- mutateAndReturn,
37
- Stringify,
38
-} from "shared-runtime";
28
+import { makeObject_Primitives, mutateAndReturn, toJSON } from "shared-runtime";
29
30
function Component(_props) {
31
const $ = useMemoCache(1);
@@ -45,7 +35,7 @@ function Component(_props) {
35
const results = [];
36
for (const item of collection) {
37
results.push(
48
- <div key={Stringify(item)}>{Stringify(mutateAndReturn(item))}</div>
38
+ <div key={toJSON(item)}>{toJSON(mutateAndReturn(item))}</div>
39
);
40
}
41
@@ -66,4 +56,4 @@ export const FIXTURE_ENTRYPOINT = {
56
```
57
58
### Eval output
69
-(kind: ok) <div><div><div>{"a":0,"b":"value1","c":true,"wat0":"joe"}</div></div></div>
\ No newline at end of file
59
+(kind: ok) <div><div>{"a":0,"b":"value1","c":true,"wat0":"joe"}</div></div>
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/for-of-mutate.tsx
+2
-8
@@ -1,16 +1,10 @@
1
-import {
2
- makeObject_Primitives,
3
- mutateAndReturn,
4
- Stringify,
5
-} from "shared-runtime";
1
+import { makeObject_Primitives, mutateAndReturn, toJSON } from "shared-runtime";
2
3
function Component(_props) {
4
const collection = [makeObject_Primitives()];
5
const results = [];
6
for (const item of collection) {
11
- results.push(
12
- <div key={Stringify(item)}>{Stringify(mutateAndReturn(item))}</div>
13
- );
7
+ results.push(<div key={toJSON(item)}>{toJSON(mutateAndReturn(item))}</div>);
8
}
9
return <div>{results}</div>;
10
}
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/hooks-with-prefix.expect.md
+27
-19
@@ -46,39 +46,47 @@ const React$useMemo = React.useMemo;
46
const Internal$Reassigned$useHook = useHook;
47
48
function Component() {
49
- const $ = useMemoCache(6);
49
+ const $ = useMemoCache(8);
50
const [state] = React$useState(0);
51
const object = Internal$Reassigned$useHook();
52
- const json = JSON.stringify(object);
52
let t0;
53
+ if ($[0] !== object) {
54
+ t0 = JSON.stringify(object);
55
+ $[0] = object;
56
+ $[1] = t0;
57
+ } else {
58
+ t0 = $[1];
59
+ }
60
+ const json = t0;
61
let t1;
55
- if ($[0] !== state) {
56
- t0 = makeArray(state);
57
- const doubledArray = t0;
62
+ let t2;
63
+ if ($[2] !== state) {
64
+ t1 = makeArray(state);
65
+ const doubledArray = t1;
66
59
- t1 = doubledArray.join("");
60
- $[0] = state;
61
- $[1] = t1;
62
- $[2] = t0;
67
+ t2 = doubledArray.join("");
68
+ $[2] = state;
69
+ $[3] = t2;
70
+ $[4] = t1;
71
} else {
64
- t1 = $[1];
65
- t0 = $[2];
72
+ t2 = $[3];
73
+ t1 = $[4];
74
}
67
- let t2;
68
- if ($[3] !== t1 || $[4] !== json) {
69
- t2 = (
75
+ let t3;
76
+ if ($[5] !== t2 || $[6] !== json) {
77
+ t3 = (
78
<div>
71
- {t1}
79
+ {t2}
80
{json}
81
</div>
82
);
75
- $[3] = t1;
76
- $[4] = json;
83
$[5] = t2;
84
+ $[6] = json;
85
+ $[7] = t3;
86
} else {
79
- t2 = $[5];
87
+ t3 = $[7];
88
}
81
- return t2;
89
+ return t3;
90
}
91
92
export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/optional-member-expression.expect.md
+11
-1
@@ -15,8 +15,18 @@ function Foo(props) {
15
## Code
16
17
```javascript
18
+import { unstable_useMemoCache as useMemoCache } from "react";
19
function Foo(props) {
19
- const x = bar(props.a);
20
+ const $ = useMemoCache(2);
21
+ let t0;
22
+ if ($[0] !== props.a) {
23
+ t0 = bar(props.a);
24
+ $[0] = props.a;
25
+ $[1] = t0;
26
+ } else {
27
+ t0 = $[1];
28
+ }
29
+ const x = t0;
30
const y = x?.b;
31
32
const z = useBar(y);
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/partial-early-return-within-reactive-scope.expect.md
+3
-3
@@ -35,12 +35,12 @@ function Component(props) {
35
let t0;
36
if ($[0] !== props) {
37
t0 = Symbol.for("react.early_return_sentinel");
38
- bb11: {
38
+ bb12: {
39
const x = [];
40
if (props.cond) {
41
x.push(props.a);
42
t0 = x;
43
- break bb11;
43
+ break bb12;
44
} else {
45
let t1;
46
if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
@@ -52,7 +52,7 @@ function Component(props) {
52
y = t1;
53
if (props.b) {
54
t0 = undefined;
55
- break bb11;
55
+ break bb12;
56
}
57
}
58
}
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/reduce-reactive-cond-deps-return-in-scope.expect.md
+2
-2
@@ -35,11 +35,11 @@ function useFoo(t0) {
35
let t1;
36
if ($[0] !== objIsNull || $[1] !== obj) {
37
t1 = Symbol.for("react.early_return_sentinel");
38
- bb8: {
38
+ bb9: {
39
x = [];
40
if (objIsNull) {
41
t1 = undefined;
42
- break bb8;
42
+ break bb9;
43
} else {
44
x.push(obj.a);
45
}
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/reduce-reactive-deps/jump-poisoned/reduce-if-nonexhaustive-poisoned-deps.expect.md
+2
-2
@@ -46,12 +46,12 @@ function useFoo(t0) {
46
let t1;
47
if ($[0] !== cond || $[1] !== hasAB || $[2] !== input) {
48
t1 = Symbol.for("react.early_return_sentinel");
49
- bb10: {
49
+ bb11: {
50
x = [];
51
if (cond) {
52
if (!hasAB) {
53
t1 = null;
54
- break bb10;
54
+ break bb11;
55
}
56
let t2;
57
if ($[5] !== input.a.b) {
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/reduce-reactive-deps/jump-poisoned/reduce-if-nonexhaustive-poisoned-deps1.expect.md
+2
-2
@@ -47,12 +47,12 @@ function useFoo(t0) {
47
let t1;
48
if ($[0] !== cond || $[1] !== hasAB || $[2] !== input) {
49
t1 = Symbol.for("react.early_return_sentinel");
50
- bb11: {
50
+ bb12: {
51
x = [];
52
if (cond) {
53
if (!hasAB) {
54
t1 = null;
55
- break bb11;
55
+ break bb12;
56
} else {
57
let t2;
58
if ($[5] !== input.a.b) {
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/reduce-reactive-deps/jump-poisoned/return-in-scope.expect.md
+2
-2
@@ -37,11 +37,11 @@ function useFoo(t0) {
37
let t1;
38
if ($[0] !== objIsNull || $[1] !== obj) {
39
t1 = Symbol.for("react.early_return_sentinel");
40
- bb7: {
40
+ bb8: {
41
x = [];
42
if (objIsNull) {
43
t1 = undefined;
44
- break bb7;
44
+ break bb8;
45
}
46
47
x.push(obj.b);
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/reduce-reactive-deps/jump-poisoned/return-poisons-outer-scope.expect.md
+2
-2
@@ -43,11 +43,11 @@ function useFoo(t0) {
43
let t1;
44
if ($[0] !== cond || $[1] !== input) {
45
t1 = Symbol.for("react.early_return_sentinel");
46
- bb7: {
46
+ bb8: {
47
x = [];
48
if (cond) {
49
t1 = null;
50
- break bb7;
50
+ break bb8;
51
}
52
let t2;
53
if ($[4] !== input.a.b) {
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/reduce-reactive-deps/jump-unpoisoned/reduce-if-exhaustive-nonpoisoned-deps.expect.md
+2
-2
@@ -37,7 +37,7 @@ function useFoo(t0) {
37
let t1;
38
if ($[0] !== hasAB || $[1] !== input.a || $[2] !== returnNull) {
39
t1 = Symbol.for("react.early_return_sentinel");
40
- bb10: {
40
+ bb11: {
41
x = [];
42
if (!hasAB) {
43
let t2;
@@ -51,7 +51,7 @@ function useFoo(t0) {
51
x.push(t2);
52
if (!returnNull) {
53
t1 = null;
54
- break bb10;
54
+ break bb11;
55
}
56
} else {
57
let t2;
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/reduce-reactive-deps/jump-unpoisoned/reduce-if-exhaustive-nonpoisoned-deps1.expect.md
+2
-2
@@ -47,7 +47,7 @@ function useFoo(t0) {
47
let t1;
48
if ($[0] !== cond1 || $[1] !== cond2 || $[2] !== input.a.b) {
49
t1 = Symbol.for("react.early_return_sentinel");
50
- bb11: {
50
+ bb12: {
51
x = [];
52
if (cond1) {
53
if (!cond2) {
@@ -61,7 +61,7 @@ function useFoo(t0) {
61
}
62
x.push(t2);
63
t1 = null;
64
- break bb11;
64
+ break bb12;
65
} else {
66
let t2;
67
if ($[7] !== input.a.b) {
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/reduce-reactive-deps/reduce-if-exhaustive-poisoned-deps.expect.md
+2
-2
@@ -38,7 +38,7 @@ function useFoo(t0) {
38
let t1;
39
if ($[0] !== inputHasABC || $[1] !== input.a || $[2] !== inputHasAB) {
40
t1 = Symbol.for("react.early_return_sentinel");
41
- bb10: {
41
+ bb11: {
42
x = [];
43
if (!inputHasABC) {
44
let t2;
@@ -52,7 +52,7 @@ function useFoo(t0) {
52
x.push(t2);
53
if (!inputHasAB) {
54
t1 = null;
55
- break bb10;
55
+ break bb11;
56
}
57
let t3;
58
if ($[7] !== input.a.b) {
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/repro-no-declarations-in-reactive-scope-with-early-return.expect.md
+2
-2
@@ -46,7 +46,7 @@ function Component() {
46
let t2;
47
if ($[0] !== items) {
48
t2 = Symbol.for("react.early_return_sentinel");
49
- bb14: {
49
+ bb15: {
50
let t3;
51
if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
52
t3 = (t4) => {
@@ -72,7 +72,7 @@ function Component() {
72
t4 = $[5];
73
}
74
t2 = t4;
75
- break bb14;
75
+ break bb15;
76
}
77
let t4;
78
if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/repro-no-value-for-temporary-reactive-scope-with-early-return.expect.md
+2
-2
@@ -43,12 +43,12 @@ function Component(props) {
43
let t1;
44
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
45
t1 = Symbol.for("react.early_return_sentinel");
46
- bb7: {
46
+ bb8: {
47
const object = makeObject_Primitives();
48
const cond = makeObject_Primitives();
49
if (!cond) {
50
t1 = null;
51
- break bb7;
51
+ break bb8;
52
}
53
54
t0 = (
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/repro-renaming-conflicting-decls.expect.md
+2
-2
@@ -51,12 +51,12 @@ function Component(props) {
51
let t2;
52
if ($[0] !== props) {
53
t2 = Symbol.for("react.early_return_sentinel");
54
- bb10: {
54
+ bb11: {
55
t0 = toJSON(props);
56
const propsString = t0;
57
if (propsString.length <= 2) {
58
t2 = null;
59
- break bb10;
59
+ break bb11;
60
}
61
62
t1 = identity(propsString);
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-try-value-modified-in-catch.expect.md
+3
-3
@@ -34,7 +34,7 @@ function Component(props) {
34
let t0;
35
if ($[0] !== props.y || $[1] !== props.e) {
36
t0 = Symbol.for("react.early_return_sentinel");
37
- bb18: {
37
+ bb19: {
38
try {
39
const y = [];
40
y.push(props.y);
@@ -43,11 +43,11 @@ function Component(props) {
43
const e = t1;
44
e.push(props.e);
45
t0 = e;
46
- break bb18;
46
+ break bb19;
47
}
48
49
t0 = null;
50
- break bb18;
50
+ break bb19;
51
}
52
$[0] = props.y;
53
$[1] = props.e;
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-with-catch-param.expect.md
+3
-3
@@ -35,7 +35,7 @@ function Component(props) {
35
let t0;
36
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
37
t0 = Symbol.for("react.early_return_sentinel");
38
- bb11: {
38
+ bb12: {
39
const x = [];
40
try {
41
throwInput(x);
@@ -43,11 +43,11 @@ function Component(props) {
43
const e = t1;
44
e.push(null);
45
t0 = e;
46
- break bb11;
46
+ break bb12;
47
}
48
49
t0 = x;
50
- break bb11;
50
+ break bb12;
51
}
52
$[0] = t0;
53
} else {
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-with-return.expect.md
+3
-3
@@ -37,19 +37,19 @@ function Component(props) {
37
let t0;
38
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
39
t0 = Symbol.for("react.early_return_sentinel");
40
- bb25: {
40
+ bb26: {
41
x = [];
42
try {
43
const y = shallowCopy({});
44
if (y == null) {
45
t0 = undefined;
46
- break bb25;
46
+ break bb26;
47
}
48
49
x.push(throwInput(y));
50
} catch {
51
t0 = null;
52
- break bb25;
52
+ break bb26;
53
}
54
}
55
$[0] = x;
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-call-second-function-which-captures-maybe-mutable-value-dont-preserve-memoization.expect.md
+2
-2
@@ -2,7 +2,7 @@
2
## Input
3
4
```javascript
5
-// @enablePreserveExistingMemoizationGuarantees:false
5
+// @enablePreserveExistingMemoizationGuarantees:false @enableTransitivelyFreezeFunctionExpressions:false
6
import { useCallback } from "react";
7
import {
8
identity,
@@ -39,7 +39,7 @@ export const FIXTURE_ENTRYPOINT = {
39
## Code
40
41
```javascript
42
-// @enablePreserveExistingMemoizationGuarantees:false
42
+// @enablePreserveExistingMemoizationGuarantees:false @enableTransitivelyFreezeFunctionExpressions:false
43
import { useCallback, unstable_useMemoCache as useMemoCache } from "react";
44
import {
45
identity,
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-call-second-function-which-captures-maybe-mutable-value-dont-preserve-memoization.js
+1
-1
@@ -1,4 +1,4 @@
1
-// @enablePreserveExistingMemoizationGuarantees:false
1
+// @enablePreserveExistingMemoizationGuarantees:false @enableTransitivelyFreezeFunctionExpressions:false
2
import { useCallback } from "react";
3
import {
4
identity,
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useEffect-nested-lambdas.expect.md
+37
-17
@@ -2,6 +2,8 @@
2
## Input
3
4
```javascript
5
+// @enableTransitivelyFreezeFunctionExpressions:false
6
+
7
function Component(props) {
8
const item = useMutable(props.itemId);
9
const dispatch = useDispatch();
@@ -30,9 +32,10 @@ function Component(props) {
32
## Code
33
34
```javascript
33
-import { unstable_useMemoCache as useMemoCache } from "react";
35
+import { unstable_useMemoCache as useMemoCache } from "react"; // @enableTransitivelyFreezeFunctionExpressions:false
36
+
37
function Component(props) {
35
- const $ = useMemoCache(3);
38
+ const $ = useMemoCache(9);
39
const item = useMutable(props.itemId);
40
const dispatch = useDispatch();
41
useFreeze(dispatch);
@@ -47,25 +50,42 @@ function Component(props) {
50
t0 = $[1];
51
}
52
const exit = t0;
50
-
51
- useEffect(() => {
52
- const cleanup = GlobalEventEmitter.addListener("onInput", () => {
53
- if (item.value) {
54
- exit();
55
- }
56
- });
57
- return () => cleanup.remove();
58
- }, [exit, item]);
53
+ let t1;
54
+ if ($[2] !== item.value || $[3] !== exit) {
55
+ t1 = () => {
56
+ const cleanup = GlobalEventEmitter.addListener("onInput", () => {
57
+ if (item.value) {
58
+ exit();
59
+ }
60
+ });
61
+ return () => cleanup.remove();
62
+ };
63
+ $[2] = item.value;
64
+ $[3] = exit;
65
+ $[4] = t1;
66
+ } else {
67
+ t1 = $[4];
68
+ }
69
+ let t2;
70
+ if ($[5] !== exit || $[6] !== item) {
71
+ t2 = [exit, item];
72
+ $[5] = exit;
73
+ $[6] = item;
74
+ $[7] = t2;
75
+ } else {
76
+ t2 = $[7];
77
+ }
78
+ useEffect(t1, t2);
79
80
maybeMutate(item);
61
- let t1;
62
- if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
63
- t1 = <div />;
64
- $[2] = t1;
81
+ let t3;
82
+ if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
83
+ t3 = <div />;
84
+ $[8] = t3;
85
} else {
66
- t1 = $[2];
86
+ t3 = $[8];
87
}
68
- return t1;
88
+ return t3;
89
}
90
91
```
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useEffect-nested-lambdas.js
+2
@@ -1,3 +1,5 @@
1
+// @enableTransitivelyFreezeFunctionExpressions:false
2
+
3
function Component(props) {
4
const item = useMutable(props.itemId);
5
const dispatch = useDispatch();
compiler/packages/snap/src/compiler.ts
+20
-13
@@ -41,6 +41,8 @@ function makePluginOptions(
41
let enableUseMemoCachePolyfill = false;
42
let panicThreshold: PanicThresholdOptions = "ALL_ERRORS";
43
let hookPattern: string | null = null;
44
+ // TODO(@mofeiZ) rewrite snap fixtures to @validatePreserveExistingMemo:false
45
+ let validatePreserveExistingMemoizationGuarantees = false;
46
47
if (firstLine.indexOf("@compilationMode(annotation)") !== -1) {
48
assert(
@@ -113,6 +115,10 @@ function makePluginOptions(
115
ignoreUseNoForget = true;
116
}
117
118
+ if (firstLine.includes("@validatePreserveExistingMemoizationGuarantees")) {
119
+ validatePreserveExistingMemoizationGuarantees = true;
120
+ }
121
+
122
const hookPatternMatch = /@hookPattern:"([^"]+)"/.exec(firstLine);
123
if (
124
hookPatternMatch &&
@@ -164,6 +170,7 @@ function makePluginOptions(
170
enableEmitHookGuards,
171
assertValidMutableRanges: true,
172
hookPattern,
173
+ validatePreserveExistingMemoizationGuarantees,
174
},
175
compilationMode,
176
logger: null,
@@ -173,7 +180,7 @@ function makePluginOptions(
180
enableUseMemoCachePolyfill,
181
eslintSuppressionRules,
182
flowSuppressions,
176
- ignoreUseNoForget
183
+ ignoreUseNoForget,
184
};
185
}
186
@@ -211,18 +218,18 @@ function getEvaluatorPresets(
218
presets.push(
219
language === "typescript"
220
? [
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
- ]
221
+ "@babel/preset-typescript",
222
+ {
223
+ /**
224
+ * onlyRemoveTypeImports needs to be set as fbt imports
225
+ * would otherwise be removed by this pass.
226
+ * https://github.com/facebook/fbt/issues/49
227
+ * https://github.com/facebook/sfbt/issues/72
228
+ * https://dev.to/retyui/how-to-add-support-typescript-for-fbt-an-internationalization-framework-3lo0
229
+ */
230
+ onlyRemoveTypeImports: true,
231
+ },
232
+ ]
233
: "@babel/preset-flow"
234
);
235