@samitouri / QOS-React / commits / bc516409a6

Repro of for loop with context variable iterator variable

`let` bindings of context variables are lowered to a DeclareContext + StoreContext, which breaks codegen for `for` loops which expect that all statements of the init block will lower to variable declarations. The two instructions produce a variable declaration and a reassignment.

Joe Savona committed Mar 22, 2024 at 09:15 UTC bc516409a6ab98a2179fc7628fe75a49827d85c7
2 files changed +45
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-for-loop-with-context-variable-iterator.expect.md new
+35
@@ -0,0 +1,35 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function Component() {
6 + const data = useData();
7 + const items = [];
8 + // NOTE: `i` is a context variable because it's reassigned and also referenced
9 + // within a closure, the `onClick` handler of each item
10 + for (let i = MIN; i <= MAX; i += INCREMENT) {
11 + items.push(<Stringify key={i} onClick={() => data.set(i)} />);
12 + }
13 + return items;
14 +}
15 +
16 +```
17 +
18 +
19 +## Error
20 +
21 +```
22 + 4 | // NOTE: `i` is a context variable because it's reassigned and also referenced
23 + 5 | // within a closure, the `onClick` handler of each item
24 +> 6 | for (let i = MIN; i <= MAX; i += INCREMENT) {
25 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
26 +> 7 | items.push(<Stringify key={i} onClick={() => data.set(i)} />);
27 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
28 +> 8 | }
29 + | ^^^^ [ReactForget] Invariant: Expected a variable declaration (6:8)
30 + 9 | return items;
31 + 10 | }
32 + 11 |
33 +```
34 +
35 +
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-for-loop-with-context-variable-iterator.js new
+10
@@ -0,0 +1,10 @@
1 +function Component() {
2 + const data = useData();
3 + const items = [];
4 + // NOTE: `i` is a context variable because it's reassigned and also referenced
5 + // within a closure, the `onClick` handler of each item
6 + for (let i = MIN; i <= MAX; i += INCREMENT) {
7 + items.push(<Stringify key={i} onClick={() => data.set(i)} />);
8 + }
9 + return items;
10 +}