From 7dc08d79be1bd7938757d03bd58fc662f647bbd7 Mon Sep 17 00:00:00 2001 From: Joe Savona Date: Fri, 22 Mar 2024 09:02:56 -0700 Subject: [PATCH] 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. --- .../PropagateScopeDependencies.ts | 9 +++ ...or.todo-switch-with-only-default.expect.md | 21 ------- .../error.todo-switch-with-only-default.js | 6 -- .../switch-with-only-default.expect.md | 63 +++++++++++++++++++ .../compiler/switch-with-only-default.js | 13 ++++ 5 files changed, 85 insertions(+), 27 deletions(-) delete mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-switch-with-only-default.expect.md delete mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-switch-with-only-default.js create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/switch-with-only-default.expect.md create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/switch-with-only-default.js diff --git a/compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/PropagateScopeDependencies.ts b/compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/PropagateScopeDependencies.ts index 062b4881b3..81815d8da8 100644 --- a/compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/PropagateScopeDependencies.ts +++ b/compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/PropagateScopeDependencies.ts @@ -732,6 +732,15 @@ class PropagationVisitor extends ReactiveFunctionVisitor { } 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; /* diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-switch-with-only-default.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-switch-with-only-default.expect.md deleted file mode 100644 index a0c950647b..0000000000 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-switch-with-only-default.expect.md +++ /dev/null @@ -1,21 +0,0 @@ - -## Input - -```javascript -function Component({ kind, ...props }) { - switch (kind) { - default: - return ; - } -} - -``` - - -## Error - -``` -[ReactForget] Invariant: Expected trees to be at least 2 elements long. -``` - - \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-switch-with-only-default.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-switch-with-only-default.js deleted file mode 100644 index 4b6cc8b258..0000000000 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-switch-with-only-default.js +++ /dev/null @@ -1,6 +0,0 @@ -function Component({ kind, ...props }) { - switch (kind) { - default: - return ; - } -} diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/switch-with-only-default.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/switch-with-only-default.expect.md new file mode 100644 index 0000000000..f0a6740e57 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/switch-with-only-default.expect.md @@ -0,0 +1,63 @@ + +## Input + +```javascript +import { Stringify } from "shared-runtime"; + +function Component({ kind, ...props }) { + switch (kind) { + default: + return ; + } +} + +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 = ; + $[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)
{"a":1,"b":true,"c":"sathya"}
\ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/switch-with-only-default.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/switch-with-only-default.js new file mode 100644 index 0000000000..50f71aec7d --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/switch-with-only-default.js @@ -0,0 +1,13 @@ +import { Stringify } from "shared-runtime"; + +function Component({ kind, ...props }) { + switch (kind) { + default: + return ; + } +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ kind: "foo", a: 1, b: true, c: "sathya" }], +};