@samitouri / QOS-React-2 / commits / 5656d5f078

[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