PropagateScopeDeps treats switch w only default as unconditional

If we have a switch with only a default case, then that code will be executed 
unconditionally. PropagateScopeDeps can take advantage of this to record 
dependencies in these cases as unconditional, which avoids the issue seen in the 
previous PR.
This commit is contained in:
Joe Savona
2024-03-22 09:02:56 -07:00
parent 3229302222
commit 7dc08d79be
5 changed files with 85 additions and 27 deletions
@@ -732,6 +732,15 @@ class PropagationVisitor extends ReactiveFunctionVisitor<Context> {
}
case "switch": {
context.visitOperand(terminal.test);
const isDefaultOnly =
terminal.cases.length === 1 && terminal.cases[0].test == null;
if (isDefaultOnly) {
const case_ = terminal.cases[0];
if (case_.block != null) {
this.visitBlock(case_.block, context);
break;
}
}
const depsInCases = [];
let foundDefault = false;
/*
@@ -1,21 +0,0 @@
## Input
```javascript
function Component({ kind, ...props }) {
switch (kind) {
default:
return <Stringify {...props} />;
}
}
```
## Error
```
[ReactForget] Invariant: Expected trees to be at least 2 elements long.
```
@@ -1,6 +0,0 @@
function Component({ kind, ...props }) {
switch (kind) {
default:
return <Stringify {...props} />;
}
}
@@ -0,0 +1,63 @@
## Input
```javascript
import { Stringify } from "shared-runtime";
function Component({ kind, ...props }) {
switch (kind) {
default:
return <Stringify {...props} />;
}
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{ kind: "foo", a: 1, b: true, c: "sathya" }],
};
```
## Code
```javascript
import { unstable_useMemoCache as useMemoCache } from "react";
import { Stringify } from "shared-runtime";
function Component(t0) {
const $ = useMemoCache(5);
let kind;
let props;
if ($[0] !== t0) {
({ kind, ...props } = t0);
$[0] = t0;
$[1] = kind;
$[2] = props;
} else {
kind = $[1];
props = $[2];
}
switch (kind) {
default: {
let t1;
if ($[3] !== props) {
t1 = <Stringify {...props} />;
$[3] = props;
$[4] = t1;
} else {
t1 = $[4];
}
return t1;
}
}
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{ kind: "foo", a: 1, b: true, c: "sathya" }],
};
```
### Eval output
(kind: ok) <div>{"a":1,"b":true,"c":"sathya"}</div>
@@ -0,0 +1,13 @@
import { Stringify } from "shared-runtime";
function Component({ kind, ...props }) {
switch (kind) {
default:
return <Stringify {...props} />;
}
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{ kind: "foo", a: 1, b: true, c: "sathya" }],
};