@samitouri / QOS-React-2 / commits / 8192cd253d

Fix missing memoization of scope-less variable being reassigned

Joe Savona committed Jun 7, 2023 at 22:15 UTC 8192cd253d340554d151f853ed80626ce63dbca2
4 files changed +98 -7
compiler/forget/packages/babel-plugin-react-forget/src/ReactiveScopes/PropagateScopeDependencies.ts
+3 -6
@@ -419,15 +419,12 @@ class Context {
419 * current one as a {@link ReactiveScope.reassignments}
420 */
421 visitReassignment(place: Place): void {
422 - const declaration = this.#declarations.get(place.identifier.id);
422 if (
423 this.currentScope.value != null &&
425 - place.identifier.scope != null &&
426 - declaration !== undefined &&
427 - declaration.scope.value !== place.identifier.scope &&
424 !Array.from(this.currentScope.value.reassignments).some(
429 - (ident) => ident.id === place.identifier.id
430 - )
425 + (identifier) => identifier.id === place.identifier.id
426 + ) &&
427 + this.#checkValidDependency({ identifier: place.identifier, path: [] })
428 ) {
429 this.currentScope.value.reassignments.add(place.identifier);
430 }
compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/repro-reassign-to-variable-without-mutable-range.expect.md new
+81
@@ -0,0 +1,81 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +// @debug
6 +function Component(a, b) {
7 + let x = [];
8 + let y = [];
9 + let z = foo(a);
10 + if (FLAG) {
11 + x = bar(z);
12 + y = baz(b);
13 + }
14 + return [x, y];
15 +}
16 +
17 +```
18 +
19 +## Code
20 +
21 +```javascript
22 +import { unstable_useMemoCache as useMemoCache } from "react"; // @debug
23 +function Component(a, b) {
24 + const $ = useMemoCache(11);
25 + let t0;
26 + if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
27 + t0 = [];
28 + $[0] = t0;
29 + } else {
30 + t0 = $[0];
31 + }
32 + let x = t0;
33 + let t1;
34 + if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
35 + t1 = [];
36 + $[1] = t1;
37 + } else {
38 + t1 = $[1];
39 + }
40 + let y = t1;
41 + const c_2 = $[2] !== a;
42 + const c_3 = $[3] !== b;
43 + if (c_2 || c_3) {
44 + const z = foo(a);
45 + if (FLAG) {
46 + x = bar(z);
47 + const c_6 = $[6] !== b;
48 + let t2;
49 + if (c_6) {
50 + t2 = baz(b);
51 + $[6] = b;
52 + $[7] = t2;
53 + } else {
54 + t2 = $[7];
55 + }
56 + y = t2;
57 + }
58 + $[2] = a;
59 + $[3] = b;
60 + $[4] = x;
61 + $[5] = y;
62 + } else {
63 + x = $[4];
64 + y = $[5];
65 + }
66 + const c_8 = $[8] !== x;
67 + const c_9 = $[9] !== y;
68 + let t3;
69 + if (c_8 || c_9) {
70 + t3 = [x, y];
71 + $[8] = x;
72 + $[9] = y;
73 + $[10] = t3;
74 + } else {
75 + t3 = $[10];
76 + }
77 + return t3;
78 +}
79 +
80 +```
81 +
\ No newline at end of file
compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/repro-reassign-to-variable-without-mutable-range.js new
+11
@@ -0,0 +1,11 @@
1 +// @debug
2 +function Component(a, b) {
3 + let x = [];
4 + let y = [];
5 + let z = foo(a);
6 + if (FLAG) {
7 + x = bar(z);
8 + y = baz(b);
9 + }
10 + return [x, y];
11 +}
compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/ssa-cascading-eliminated-phis.expect.md
+3 -1
@@ -25,7 +25,7 @@ function Component(props) {
25 ```javascript
26 import { unstable_useMemoCache as useMemoCache } from "react";
27 function Component(props) {
28 - const $ = useMemoCache(2);
28 + const $ = useMemoCache(3);
29 let x = 0;
30 const c_0 = $[0] !== props;
31 let values;
@@ -45,8 +45,10 @@ function Component(props) {
45 values.push(x);
46 $[0] = props;
47 $[1] = values;
48 + $[2] = x;
49 } else {
50 values = $[1];
51 + x = $[2];
52 }
53 return values;
54 }