From 0052f2e591622fec493752b37af54e82a5752dac Mon Sep 17 00:00:00 2001 From: Joe Savona Date: Thu, 7 Sep 2023 16:50:24 -0700 Subject: [PATCH] TryStatement: enable sprout on new tests Enables sprout for all the new try/catch fixtures in this stack. I added new helpers and tried to make sure we're testing the most interesting codepath of each fixture. This is where property testing would help, since we could test multiple paths with a single block of code, but for now this seems like a good balance of coverage. --- .../try-catch-mutate-outer-value.expect.md | 46 +++++++++++++------ .../compiler/try-catch-mutate-outer-value.js | 11 ++++- .../try-catch-with-catch-param.expect.md | 18 +++++++- .../compiler/try-catch-with-catch-param.js | 9 +++- .../compiler/try-catch-with-return.expect.md | 25 ++++++++-- .../compiler/try-catch-with-return.js | 11 ++++- .../try-catch-within-mutable-range.expect.md | 22 +++++++-- .../try-catch-within-mutable-range.js | 11 ++++- .../fixtures/compiler/try-catch.expect.md | 18 +++++++- .../__tests__/fixtures/compiler/try-catch.js | 9 +++- .../packages/sprout/src/SproutTodoFilter.ts | 5 -- .../packages/sprout/src/shared-runtime.ts | 8 ++++ 12 files changed, 153 insertions(+), 40 deletions(-) diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-mutate-outer-value.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-mutate-outer-value.expect.md index 0feb08976e..cb9823c3a2 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-mutate-outer-value.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-mutate-outer-value.expect.md @@ -2,52 +2,70 @@ ## Input ```javascript +const { shallowCopy, throwErrorWithMessage } = require("shared-runtime"); + function Component(props) { const x = []; try { - x.push(foo()); + x.push(throwErrorWithMessage("oops")); } catch { - x.push(bar()); + x.push(shallowCopy({ a: props.a })); } return x; } +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ a: 1 }], +}; + ``` ## Code ```javascript import { unstable_useMemoCache as useMemoCache } from "react"; +const { shallowCopy, throwErrorWithMessage } = require("shared-runtime"); + function Component(props) { - const $ = useMemoCache(3); + const $ = useMemoCache(5); + const c_0 = $[0] !== props.a; let x; - if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + if (c_0) { x = []; try { let t0; - if ($[1] === Symbol.for("react.memo_cache_sentinel")) { - t0 = foo(); - $[1] = t0; + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { + t0 = throwErrorWithMessage("oops"); + $[2] = t0; } else { - t0 = $[1]; + t0 = $[2]; } x.push(t0); } catch { + const c_3 = $[3] !== props.a; let t1; - if ($[2] === Symbol.for("react.memo_cache_sentinel")) { - t1 = bar(); - $[2] = t1; + if (c_3) { + t1 = shallowCopy({ a: props.a }); + $[3] = props.a; + $[4] = t1; } else { - t1 = $[2]; + t1 = $[4]; } x.push(t1); } - $[0] = x; + $[0] = props.a; + $[1] = x; } else { - x = $[0]; + x = $[1]; } return x; } +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ a: 1 }], +}; + ``` \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-mutate-outer-value.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-mutate-outer-value.js index 813dea5736..984042470d 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-mutate-outer-value.js +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-mutate-outer-value.js @@ -1,9 +1,16 @@ +const { shallowCopy, throwErrorWithMessage } = require("shared-runtime"); + function Component(props) { const x = []; try { - x.push(foo()); + x.push(throwErrorWithMessage("oops")); } catch { - x.push(bar()); + x.push(shallowCopy({ a: props.a })); } return x; } + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ a: 1 }], +}; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-with-catch-param.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-with-catch-param.expect.md index cc881c39b1..033bf885ce 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-with-catch-param.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-with-catch-param.expect.md @@ -2,11 +2,13 @@ ## Input ```javascript +const { throwInput } = require("shared-runtime"); + function Component(props) { let x = []; try { // foo could throw its argument... - foo(x); + throwInput(x); } catch (e) { // ... in which case this could be mutating `x`! e.push(null); @@ -15,19 +17,26 @@ function Component(props) { return x; } +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; + ``` ## Code ```javascript import { unstable_useMemoCache as useMemoCache } from "react"; +const { throwInput } = require("shared-runtime"); + function Component(props) { const $ = useMemoCache(1); let x; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { x = []; try { - foo(x); + throwInput(x); } catch (t22) { const e = t22; @@ -41,5 +50,10 @@ function Component(props) { return x; } +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; + ``` \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-with-catch-param.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-with-catch-param.js index cdaf1fe0fb..9508694f96 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-with-catch-param.js +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-with-catch-param.js @@ -1,8 +1,10 @@ +const { throwInput } = require("shared-runtime"); + function Component(props) { let x = []; try { // foo could throw its argument... - foo(x); + throwInput(x); } catch (e) { // ... in which case this could be mutating `x`! e.push(null); @@ -10,3 +12,8 @@ function Component(props) { } return x; } + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-with-return.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-with-return.expect.md index c4efbbd002..b8ec724418 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-with-return.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-with-return.expect.md @@ -2,39 +2,49 @@ ## Input ```javascript +const { shallowCopy, throwInput } = require("shared-runtime"); + // @debug function Component(props) { let x = []; try { - const y = foo(); + const y = shallowCopy({}); if (y == null) { return; } - x.push(bar(y)); + x.push(throwInput(y)); } catch { return null; } return x; } +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; + ``` ## Code ```javascript -import { unstable_useMemoCache as useMemoCache } from "react"; // @debug +import { unstable_useMemoCache as useMemoCache } from "react"; +const { shallowCopy, throwInput } = require("shared-runtime"); + +// @debug function Component(props) { const $ = useMemoCache(1); let x; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { x = []; try { - const y = foo(); + const y = shallowCopy({}); if (y == null) { return; } - x.push(bar(y)); + x.push(throwInput(y)); } catch { return null; } @@ -45,5 +55,10 @@ function Component(props) { return x; } +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; + ``` \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-with-return.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-with-return.js index 5014f6fefa..056a770e7c 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-with-return.js +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-with-return.js @@ -1,14 +1,21 @@ +const { shallowCopy, throwInput } = require("shared-runtime"); + // @debug function Component(props) { let x = []; try { - const y = foo(); + const y = shallowCopy({}); if (y == null) { return; } - x.push(bar(y)); + x.push(throwInput(y)); } catch { return null; } return x; } + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-within-mutable-range.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-within-mutable-range.expect.md index d6cf282c57..531b782f72 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-within-mutable-range.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-within-mutable-range.expect.md @@ -2,23 +2,32 @@ ## Input ```javascript +const { throwErrorWithMessage, shallowCopy } = require("shared-runtime"); + function Component(props) { const x = []; try { - x.push(foo()); + x.push(throwErrorWithMessage("oops")); } catch { - x.push(bar()); + x.push(shallowCopy({})); } x.push(props.value); // extend the mutable range to include the try/catch return x; } +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; + ``` ## Code ```javascript import { unstable_useMemoCache as useMemoCache } from "react"; +const { throwErrorWithMessage, shallowCopy } = require("shared-runtime"); + function Component(props) { const $ = useMemoCache(4); const c_0 = $[0] !== props.value; @@ -28,7 +37,7 @@ function Component(props) { try { let t0; if ($[2] === Symbol.for("react.memo_cache_sentinel")) { - t0 = foo(); + t0 = throwErrorWithMessage("oops"); $[2] = t0; } else { t0 = $[2]; @@ -37,7 +46,7 @@ function Component(props) { } catch { let t1; if ($[3] === Symbol.for("react.memo_cache_sentinel")) { - t1 = bar(); + t1 = shallowCopy({}); $[3] = t1; } else { t1 = $[3]; @@ -54,5 +63,10 @@ function Component(props) { return x; } +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; + ``` \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-within-mutable-range.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-within-mutable-range.js index 665d395a94..f6b971b75d 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-within-mutable-range.js +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch-within-mutable-range.js @@ -1,10 +1,17 @@ +const { throwErrorWithMessage, shallowCopy } = require("shared-runtime"); + function Component(props) { const x = []; try { - x.push(foo()); + x.push(throwErrorWithMessage("oops")); } catch { - x.push(bar()); + x.push(shallowCopy({})); } x.push(props.value); // extend the mutable range to include the try/catch return x; } + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch.expect.md index c22421c742..8be44e9a7c 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch.expect.md @@ -2,29 +2,38 @@ ## Input ```javascript +const { throwErrorWithMessage } = require("shared-runtime"); + function Component(props) { let x; try { - x = foo(); + x = throwErrorWithMessage("oops"); } catch { x = null; } return x; } +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; + ``` ## Code ```javascript import { unstable_useMemoCache as useMemoCache } from "react"; +const { throwErrorWithMessage } = require("shared-runtime"); + function Component(props) { const $ = useMemoCache(1); let x = undefined; try { let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t0 = foo(); + t0 = throwErrorWithMessage("oops"); $[0] = t0; } else { t0 = $[0]; @@ -36,5 +45,10 @@ function Component(props) { return x; } +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; + ``` \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch.js index d729c28bf9..89af9ee95f 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch.js +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/try-catch.js @@ -1,9 +1,16 @@ +const { throwErrorWithMessage } = require("shared-runtime"); + function Component(props) { let x; try { - x = foo(); + x = throwErrorWithMessage("oops"); } catch { x = null; } return x; } + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; diff --git a/compiler/packages/sprout/src/SproutTodoFilter.ts b/compiler/packages/sprout/src/SproutTodoFilter.ts index 5206dd62cb..1f4d4fb2d4 100644 --- a/compiler/packages/sprout/src/SproutTodoFilter.ts +++ b/compiler/packages/sprout/src/SproutTodoFilter.ts @@ -412,11 +412,6 @@ const skipFilter = new Set([ "fbt-call-complex-param-value", "fbt-template-string-same-scope", "component-declaration-basic.flow", - "try-catch-mutate-outer-value", - "try-catch-within-mutable-range", - "try-catch", - "try-catch-with-return", - "try-catch-with-catch-param", // TODO: 🌲 "forest-basic", diff --git a/compiler/packages/sprout/src/shared-runtime.ts b/compiler/packages/sprout/src/shared-runtime.ts index c62335a454..57a092d16c 100644 --- a/compiler/packages/sprout/src/shared-runtime.ts +++ b/compiler/packages/sprout/src/shared-runtime.ts @@ -73,6 +73,14 @@ export function sum(...args: Array): number { return args.reduce((result, arg) => result + arg, 0); } +export function throwErrorWithMessage(message: string): never { + throw new Error(message); +} + +export function throwInput(x: Object): never { + throw x; +} + /** * React Components */