@samitouri / QOS-React-2 / commits / ee93b62f51

[ez] Patch BuildHIR to match unlabeled breaks to switch and loops

Mofei Zhang committed Mar 22, 2024 at 16:34 UTC ee93b62f510e28e4696ebea3ef0384d9db046b09
10 files changed +274 -4
compiler/packages/babel-plugin-react-forget/src/HIR/HIRBuilder.ts
+5 -1
@@ -517,7 +517,11 @@ export default class HIRBuilder {
517 lookupBreak(label: string | null): BlockId {
518 for (let ii = this.#scopes.length - 1; ii >= 0; ii--) {
519 const scope = this.#scopes[ii];
520 - if (label === null || label === scope.label) {
520 + if (
521 + (label === null &&
522 + (scope.kind === "loop" || scope.kind === "switch")) ||
523 + label === scope.label
524 + ) {
525 return scope.breakBlock;
526 }
527 }
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/labeled-break-within-label-loop.expect.md renamed
+4 -2
@@ -8,7 +8,7 @@ function useHook(end) {
8 log.push(`${i} @A`);
9 bb0: {
10 if (i === end) {
11 - break;
11 + break bb0;
12 }
13 log.push(`${i} @B`);
14 }
@@ -59,4 +59,6 @@ export const FIXTURE_ENTRYPOINT = {
59 };
60
61 ```
62 -
\ No newline at end of file
62 +
63 +### Eval output
64 +(kind: ok) ["0 @A","0 @B","0 @C","1 @A","1 @C"]
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/labeled-break-within-label-loop.ts new
+19
@@ -0,0 +1,19 @@
1 +function useHook(end) {
2 + const log = [];
3 + for (let i = 0; i < end + 1; i++) {
4 + log.push(`${i} @A`);
5 + bb0: {
6 + if (i === end) {
7 + break bb0;
8 + }
9 + log.push(`${i} @B`);
10 + }
11 + log.push(`${i} @C`);
12 + }
13 + return log;
14 +}
15 +
16 +export const FIXTURE_ENTRYPOINT = {
17 + fn: useHook,
18 + params: [1],
19 +};
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/labeled-break-within-label-switch.expect.md new
+71
@@ -0,0 +1,71 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +import { CONST_STRING0 } from "shared-runtime";
6 +
7 +function useHook(cond) {
8 + const log = [];
9 + switch (CONST_STRING0) {
10 + case CONST_STRING0:
11 + log.push(`@A`);
12 + bb0: {
13 + if (cond) {
14 + break bb0;
15 + }
16 + log.push(`@B`);
17 + }
18 + log.push(`@C`);
19 + }
20 + return log;
21 +}
22 +
23 +export const FIXTURE_ENTRYPOINT = {
24 + fn: useHook,
25 + params: [true],
26 +};
27 +
28 +```
29 +
30 +## Code
31 +
32 +```javascript
33 +import { unstable_useMemoCache as useMemoCache } from "react";
34 +import { CONST_STRING0 } from "shared-runtime";
35 +
36 +function useHook(cond) {
37 + const $ = useMemoCache(2);
38 + let log;
39 + if ($[0] !== cond) {
40 + log = [];
41 + switch (CONST_STRING0) {
42 + case CONST_STRING0: {
43 + log.push(`@A`);
44 + bb3: {
45 + if (cond) {
46 + break bb3;
47 + }
48 +
49 + log.push(`@B`);
50 + }
51 +
52 + log.push(`@C`);
53 + }
54 + }
55 + $[0] = cond;
56 + $[1] = log;
57 + } else {
58 + log = $[1];
59 + }
60 + return log;
61 +}
62 +
63 +export const FIXTURE_ENTRYPOINT = {
64 + fn: useHook,
65 + params: [true],
66 +};
67 +
68 +```
69 +
70 +### Eval output
71 +(kind: ok) ["@A","@C"]
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/labeled-break-within-label-switch.ts new
+22
@@ -0,0 +1,22 @@
1 +import { CONST_STRING0 } from "shared-runtime";
2 +
3 +function useHook(cond) {
4 + const log = [];
5 + switch (CONST_STRING0) {
6 + case CONST_STRING0:
7 + log.push(`@A`);
8 + bb0: {
9 + if (cond) {
10 + break bb0;
11 + }
12 + log.push(`@B`);
13 + }
14 + log.push(`@C`);
15 + }
16 + return log;
17 +}
18 +
19 +export const FIXTURE_ENTRYPOINT = {
20 + fn: useHook,
21 + params: [true],
22 +};
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/unlabeled-break-within-label-loop.expect.md new
+62
@@ -0,0 +1,62 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function useHook(end) {
6 + const log = [];
7 + for (let i = 0; i < end + 1; i++) {
8 + log.push(`${i} @A`);
9 + bb0: {
10 + if (i === end) {
11 + break;
12 + }
13 + log.push(`${i} @B`);
14 + }
15 + log.push(`${i} @C`);
16 + }
17 + return log;
18 +}
19 +
20 +export const FIXTURE_ENTRYPOINT = {
21 + fn: useHook,
22 + params: [1],
23 +};
24 +
25 +```
26 +
27 +## Code
28 +
29 +```javascript
30 +import { unstable_useMemoCache as useMemoCache } from "react";
31 +function useHook(end) {
32 + const $ = useMemoCache(2);
33 + let log;
34 + if ($[0] !== end) {
35 + log = [];
36 + for (let i = 0; i < end + 1; i++) {
37 + log.push(`${i} @A`);
38 + if (i === end) {
39 + break;
40 + }
41 +
42 + log.push(`${i} @B`);
43 +
44 + log.push(`${i} @C`);
45 + }
46 + $[0] = end;
47 + $[1] = log;
48 + } else {
49 + log = $[1];
50 + }
51 + return log;
52 +}
53 +
54 +export const FIXTURE_ENTRYPOINT = {
55 + fn: useHook,
56 + params: [1],
57 +};
58 +
59 +```
60 +
61 +### Eval output
62 +(kind: ok) ["0 @A","0 @B","0 @C","1 @A"]
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/unlabeled-break-within-label-loop.ts renamed
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/unlabeled-break-within-label-switch.expect.md new
+69
@@ -0,0 +1,69 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +import { CONST_STRING0 } from "shared-runtime";
6 +
7 +function useHook(cond) {
8 + const log = [];
9 + switch (CONST_STRING0) {
10 + case CONST_STRING0:
11 + log.push(`@A`);
12 + bb0: {
13 + if (cond) {
14 + break;
15 + }
16 + log.push(`@B`);
17 + }
18 + log.push(`@C`);
19 + }
20 + return log;
21 +}
22 +
23 +export const FIXTURE_ENTRYPOINT = {
24 + fn: useHook,
25 + params: [true],
26 +};
27 +
28 +```
29 +
30 +## Code
31 +
32 +```javascript
33 +import { unstable_useMemoCache as useMemoCache } from "react";
34 +import { CONST_STRING0 } from "shared-runtime";
35 +
36 +function useHook(cond) {
37 + const $ = useMemoCache(2);
38 + let log;
39 + if ($[0] !== cond) {
40 + log = [];
41 + bb1: switch (CONST_STRING0) {
42 + case CONST_STRING0: {
43 + log.push(`@A`);
44 + if (cond) {
45 + break bb1;
46 + }
47 +
48 + log.push(`@B`);
49 +
50 + log.push(`@C`);
51 + }
52 + }
53 + $[0] = cond;
54 + $[1] = log;
55 + } else {
56 + log = $[1];
57 + }
58 + return log;
59 +}
60 +
61 +export const FIXTURE_ENTRYPOINT = {
62 + fn: useHook,
63 + params: [true],
64 +};
65 +
66 +```
67 +
68 +### Eval output
69 +(kind: ok) ["@A"]
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/unlabeled-break-within-label-switch.ts new
+22
@@ -0,0 +1,22 @@
1 +import { CONST_STRING0 } from "shared-runtime";
2 +
3 +function useHook(cond) {
4 + const log = [];
5 + switch (CONST_STRING0) {
6 + case CONST_STRING0:
7 + log.push(`@A`);
8 + bb0: {
9 + if (cond) {
10 + break;
11 + }
12 + log.push(`@B`);
13 + }
14 + log.push(`@C`);
15 + }
16 + return log;
17 +}
18 +
19 +export const FIXTURE_ENTRYPOINT = {
20 + fn: useHook,
21 + params: [true],
22 +};
compiler/packages/snap/src/SproutTodoFilter.ts
-1
@@ -534,7 +534,6 @@ const skipFilter = new Set([
534 // bugs
535 "bug-reduce-reactive-deps-return-in-scope",
536 "bug-reduce-reactive-deps-break-in-scope",
537 - "bug-unlabeled-break-within-label-loop",
537
538 // 'react-forget-runtime' not yet supported
539 "flag-enable-emit-hook-guards",