@samitouri / QOS-React-1 / commits / a753a326ad

Fixture for only early return without decls/deps/reassigns

Joe Savona committed Dec 20, 2023 at 13:52 UTC a753a326ad77145e4d8eb6a44e40758d82869669
2 files changed +180
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/early-return-no-declarations-reassignments-dependencies.expect.md new
+135
@@ -0,0 +1,135 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +// @enableEarlyReturnInReactiveScopes
6 +import { makeArray } from "shared-runtime";
7 +
8 +/**
9 + * This fixture tests what happens when a reactive has no declarations (other than an early return),
10 + * no reassignments, and no dependencies. In this case the only thing we can use to decide if we
11 + * should take the if or else branch is the early return declaration. But if that uses the same
12 + * sentinel as the memo cache sentinel, then if the previous execution did not early return it will
13 + * look like we didn't execute the memo block yet, and we'll needlessly re-execute instead of skipping
14 + * to the else branch.
15 + *
16 + * We have to use a distinct sentinel for the early return value.
17 + *
18 + * Here the fixture will always take the "else" branch and never early return, and we should see that
19 + * "recreate x" is only logged once, the first time we execute.
20 + */
21 +let ENABLE_FEATURE = false;
22 +
23 +function Component(props) {
24 + let x = [];
25 + console.log("recreate x");
26 + if (ENABLE_FEATURE) {
27 + x.push(42);
28 + console.log("early return");
29 + return x;
30 + } else {
31 + console.log("fallthrough");
32 + }
33 + return makeArray(props.a);
34 +}
35 +
36 +export const FIXTURE_ENTRYPOINT = {
37 + fn: Component,
38 + params: [],
39 + sequentialRenders: [
40 + { a: 42 },
41 + { a: 42 },
42 + { a: 3.14 },
43 + { a: 3.14 },
44 + { a: 42 },
45 + { a: 3.14 },
46 + { a: 42 },
47 + { a: 3.14 },
48 + ],
49 +};
50 +
51 +```
52 +
53 +## Code
54 +
55 +```javascript
56 +import { unstable_useMemoCache as useMemoCache } from "react"; // @enableEarlyReturnInReactiveScopes
57 +import { makeArray } from "shared-runtime";
58 +
59 +/**
60 + * This fixture tests what happens when a reactive has no declarations (other than an early return),
61 + * no reassignments, and no dependencies. In this case the only thing we can use to decide if we
62 + * should take the if or else branch is the early return declaration. But if that uses the same
63 + * sentinel as the memo cache sentinel, then if the previous execution did not early return it will
64 + * look like we didn't execute the memo block yet, and we'll needlessly re-execute instead of skipping
65 + * to the else branch.
66 + *
67 + * We have to use a distinct sentinel for the early return value.
68 + *
69 + * Here the fixture will always take the "else" branch and never early return, and we should see that
70 + * "recreate x" is only logged once, the first time we execute.
71 + */
72 +let ENABLE_FEATURE = false;
73 +
74 +function Component(props) {
75 + const $ = useMemoCache(3);
76 + let t53;
77 + if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
78 + t53 = Symbol.for("react.memo_cache_sentinel");
79 + bb8: {
80 + const x = [];
81 + console.log("recreate x");
82 + if (ENABLE_FEATURE) {
83 + x.push(42);
84 + console.log("early return");
85 + t53 = x;
86 + break bb8;
87 + }
88 + }
89 + $[0] = t53;
90 + } else {
91 + t53 = $[0];
92 + }
93 + if (t53 !== Symbol.for("react.memo_cache_sentinel")) {
94 + return t53;
95 + }
96 +
97 + console.log("fallthrough");
98 + let t0;
99 + if ($[1] !== props.a) {
100 + t0 = makeArray(props.a);
101 + $[1] = props.a;
102 + $[2] = t0;
103 + } else {
104 + t0 = $[2];
105 + }
106 + return t0;
107 +}
108 +
109 +export const FIXTURE_ENTRYPOINT = {
110 + fn: Component,
111 + params: [],
112 + sequentialRenders: [
113 + { a: 42 },
114 + { a: 42 },
115 + { a: 3.14 },
116 + { a: 3.14 },
117 + { a: 42 },
118 + { a: 3.14 },
119 + { a: 42 },
120 + { a: 3.14 },
121 + ],
122 +};
123 +
124 +```
125 +
126 +### Eval output
127 +(kind: ok) [42]
128 +[42]
129 +[3.14]
130 +[3.14]
131 +[42]
132 +[3.14]
133 +[42]
134 +[3.14]
135 +logs: ['recreate x','fallthrough','recreate x','fallthrough','recreate x','fallthrough','recreate x','fallthrough','recreate x','fallthrough','recreate x','fallthrough','recreate x','fallthrough','recreate x','fallthrough']
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/early-return-no-declarations-reassignments-dependencies.js new
+45
@@ -0,0 +1,45 @@
1 +// @enableEarlyReturnInReactiveScopes
2 +import { makeArray } from "shared-runtime";
3 +
4 +/**
5 + * This fixture tests what happens when a reactive has no declarations (other than an early return),
6 + * no reassignments, and no dependencies. In this case the only thing we can use to decide if we
7 + * should take the if or else branch is the early return declaration. But if that uses the same
8 + * sentinel as the memo cache sentinel, then if the previous execution did not early return it will
9 + * look like we didn't execute the memo block yet, and we'll needlessly re-execute instead of skipping
10 + * to the else branch.
11 + *
12 + * We have to use a distinct sentinel for the early return value.
13 + *
14 + * Here the fixture will always take the "else" branch and never early return, and we should see that
15 + * "recreate x" is only logged once, the first time we execute.
16 + */
17 +let ENABLE_FEATURE = false;
18 +
19 +function Component(props) {
20 + let x = [];
21 + console.log("recreate x");
22 + if (ENABLE_FEATURE) {
23 + x.push(42);
24 + console.log("early return");
25 + return x;
26 + } else {
27 + console.log("fallthrough");
28 + }
29 + return makeArray(props.a);
30 +}
31 +
32 +export const FIXTURE_ENTRYPOINT = {
33 + fn: Component,
34 + params: [],
35 + sequentialRenders: [
36 + { a: 42 },
37 + { a: 42 },
38 + { a: 3.14 },
39 + { a: 3.14 },
40 + { a: 42 },
41 + { a: 3.14 },
42 + { a: 42 },
43 + { a: 3.14 },
44 + ],
45 +};