From 7b58600fb928dae935e85182c2142629af38dfe5 Mon Sep 17 00:00:00 2001 From: Mofei Zhang Date: Thu, 21 Sep 2023 22:38:40 -0400 Subject: [PATCH] [tests] Repros for bugs and todos --- ...-lambda-array-access-member-expr.expect.md | 30 ++++++++++++++ ...ror.bug-lambda-array-access-member-expr.ts | 15 +++++++ ...g-ternary-value-in-jsx-attribute.expect.md | 27 ++++++++++++ ...ror.bug-ternary-value-in-jsx-attribute.tsx | 12 ++++++ ...rror.const-propagation-phi-nodes.expect.md | 33 +++++++++++++++ .../error.const-propagation-phi-nodes.ts | 18 ++++++++ .../error.destructure-in-branch-ssa.expect.md | 41 +++++++++++++++++++ .../error.destructure-in-branch-ssa.ts | 26 ++++++++++++ .../error.empty-catch-statement.expect.md | 26 ++++++++++++ .../compiler/error.empty-catch-statement.ts | 11 +++++ ...ional-call-chain-in-logical-expr.expect.md | 26 ++++++++++++ ...ror.optional-call-chain-in-logical-expr.ts | 11 +++++ ...rsive-references-inner-functions.expect.md | 31 ++++++++++++++ ...do-recursive-references-inner-functions.ts | 16 ++++++++ .../packages/sprout/src/shared-runtime.ts | 18 ++++++++ 15 files changed, 341 insertions(+) create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.bug-lambda-array-access-member-expr.expect.md create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.bug-lambda-array-access-member-expr.ts create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.bug-ternary-value-in-jsx-attribute.expect.md create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.bug-ternary-value-in-jsx-attribute.tsx create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.const-propagation-phi-nodes.expect.md create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.const-propagation-phi-nodes.ts create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.destructure-in-branch-ssa.expect.md create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.destructure-in-branch-ssa.ts create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.empty-catch-statement.expect.md create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.empty-catch-statement.ts create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.optional-call-chain-in-logical-expr.expect.md create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.optional-call-chain-in-logical-expr.ts create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-recursive-references-inner-functions.expect.md create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-recursive-references-inner-functions.ts diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.bug-lambda-array-access-member-expr.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.bug-lambda-array-access-member-expr.expect.md new file mode 100644 index 0000000000..b817aa24fd --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.bug-lambda-array-access-member-expr.expect.md @@ -0,0 +1,30 @@ + +## Input + +```javascript +import { invoke } from "shared-runtime"; + +function Foo() { + const x = [{ value: 0 }, { value: 1 }, { value: 2 }]; + const foo = (param: number) => { + return x[param].value; + }; + + return invoke(foo, 1); +} + +export const FIXTURE_ENTRYPONT = { + fn: Foo, + params: [{}], +}; + +``` + + +## Error + +``` +[ReactForget] Todo: EnterSSA: Expected identifier to be defined before being used. Identifier param$10 is undefined (5:5) +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.bug-lambda-array-access-member-expr.ts b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.bug-lambda-array-access-member-expr.ts new file mode 100644 index 0000000000..0fc1dfa11e --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.bug-lambda-array-access-member-expr.ts @@ -0,0 +1,15 @@ +import { invoke } from "shared-runtime"; + +function Foo() { + const x = [{ value: 0 }, { value: 1 }, { value: 2 }]; + const foo = (param: number) => { + return x[param].value; + }; + + return invoke(foo, 1); +} + +export const FIXTURE_ENTRYPONT = { + fn: Foo, + params: [{}], +}; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.bug-ternary-value-in-jsx-attribute.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.bug-ternary-value-in-jsx-attribute.expect.md new file mode 100644 index 0000000000..b91274569f --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.bug-ternary-value-in-jsx-attribute.expect.md @@ -0,0 +1,27 @@ + +## Input + +```javascript +import { RenderPropAsChild, StaticText1, StaticText2 } from "shared-runtime"; + +function Component(props: { showText1: boolean }) { + const Foo = props.showText1 ? StaticText1 : StaticText2; + + return ]} />; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ showText1: false }], +}; + +``` + + +## Error + +``` +[ReactForget] Invariant: Expected value for identifier `28` to be initialized. (6:6) +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.bug-ternary-value-in-jsx-attribute.tsx b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.bug-ternary-value-in-jsx-attribute.tsx new file mode 100644 index 0000000000..5f8010efe5 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.bug-ternary-value-in-jsx-attribute.tsx @@ -0,0 +1,12 @@ +import { RenderPropAsChild, StaticText1, StaticText2 } from "shared-runtime"; + +function Component(props: { showText1: boolean }) { + const Foo = props.showText1 ? StaticText1 : StaticText2; + + return ]} />; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ showText1: false }], +}; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.const-propagation-phi-nodes.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.const-propagation-phi-nodes.expect.md new file mode 100644 index 0000000000..a7218ad162 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.const-propagation-phi-nodes.expect.md @@ -0,0 +1,33 @@ + +## Input + +```javascript +function useFoo(setOne: boolean) { + let x; + let y; + let z; + if (setOne) { + x = y = z = 1; + } else { + x = 2; + y = 3; + z = 5; + } + return { x, y, z }; +} + +export const FIXTURE_ENTRYPONT = { + fn: useFoo, + params: [true], +}; + +``` + + +## Error + +``` +[ReactForget] Invariant: Const declaration cannot be referenced as an expression (6:6) +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.const-propagation-phi-nodes.ts b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.const-propagation-phi-nodes.ts new file mode 100644 index 0000000000..42008b0d2e --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.const-propagation-phi-nodes.ts @@ -0,0 +1,18 @@ +function useFoo(setOne: boolean) { + let x; + let y; + let z; + if (setOne) { + x = y = z = 1; + } else { + x = 2; + y = 3; + z = 5; + } + return { x, y, z }; +} + +export const FIXTURE_ENTRYPONT = { + fn: useFoo, + params: [true], +}; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.destructure-in-branch-ssa.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.destructure-in-branch-ssa.expect.md new file mode 100644 index 0000000000..1eb1abb0d1 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.destructure-in-branch-ssa.expect.md @@ -0,0 +1,41 @@ + +## Input + +```javascript +function useFoo(props: { + x?: string; + y?: string; + z?: string; + doDestructure: boolean; +}) { + let x = null; + let y = null; + let z = null; + const myList = []; + if (props.doDestructure) { + ({ x, y, z } = props); + + myList.push(z); + } + return { + x, + y, + myList, + }; +} + +export const FIXTURE_ENTRYPONT = { + fn: useFoo, + params: [{ x: "hello", y: "world", doDestructure: true }], +}; + +``` + + +## Error + +``` +[ReactForget] Invariant: Expected consistent kind for destructuring. Other places were 'Reassign' but 'store z$44' is const (12:12) +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.destructure-in-branch-ssa.ts b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.destructure-in-branch-ssa.ts new file mode 100644 index 0000000000..a11e146491 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.destructure-in-branch-ssa.ts @@ -0,0 +1,26 @@ +function useFoo(props: { + x?: string; + y?: string; + z?: string; + doDestructure: boolean; +}) { + let x = null; + let y = null; + let z = null; + const myList = []; + if (props.doDestructure) { + ({ x, y, z } = props); + + myList.push(z); + } + return { + x, + y, + myList, + }; +} + +export const FIXTURE_ENTRYPONT = { + fn: useFoo, + params: [{ x: "hello", y: "world", doDestructure: true }], +}; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.empty-catch-statement.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.empty-catch-statement.expect.md new file mode 100644 index 0000000000..bafea79112 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.empty-catch-statement.expect.md @@ -0,0 +1,26 @@ + +## Input + +```javascript +import { getNumber } from "shared-runtime"; + +function useFoo() { + try { + return getNumber(); + } catch {} +} +export const FIXTURE_ENTRYPONT = { + fn: useFoo, + params: [], +}; + +``` + + +## Error + +``` +[ReactForget] Invariant: Cannot emit the same block twice: bb2 +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.empty-catch-statement.ts b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.empty-catch-statement.ts new file mode 100644 index 0000000000..ad636b5081 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.empty-catch-statement.ts @@ -0,0 +1,11 @@ +import { getNumber } from "shared-runtime"; + +function useFoo() { + try { + return getNumber(); + } catch {} +} +export const FIXTURE_ENTRYPONT = { + fn: useFoo, + params: [], +}; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.optional-call-chain-in-logical-expr.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.optional-call-chain-in-logical-expr.expect.md new file mode 100644 index 0000000000..8a37054d3f --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.optional-call-chain-in-logical-expr.expect.md @@ -0,0 +1,26 @@ + +## Input + +```javascript +import { useNoAlias } from "shared-runtime"; + +function useFoo(props: { value: { x: string; y: string } | null }) { + const value = props.value; + return useNoAlias(value?.x, value?.y) ?? {}; +} + +export const FIXTURE_ENTRYPONT = { + fn: useFoo, + props: [{ value: null }], +}; + +``` + + +## Error + +``` +[ReactForget] Invariant: Unexpected terminal kind 'optional' for logical test block (5:5) +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.optional-call-chain-in-logical-expr.ts b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.optional-call-chain-in-logical-expr.ts new file mode 100644 index 0000000000..8eec8977e9 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.optional-call-chain-in-logical-expr.ts @@ -0,0 +1,11 @@ +import { useNoAlias } from "shared-runtime"; + +function useFoo(props: { value: { x: string; y: string } | null }) { + const value = props.value; + return useNoAlias(value?.x, value?.y) ?? {}; +} + +export const FIXTURE_ENTRYPONT = { + fn: useFoo, + props: [{ value: null }], +}; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-recursive-references-inner-functions.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-recursive-references-inner-functions.expect.md new file mode 100644 index 0000000000..6e898fc6ff --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-recursive-references-inner-functions.expect.md @@ -0,0 +1,31 @@ + +## Input + +```javascript +function Foo({ value }: { value: number }) { + const factorial = (x: number) => { + if (x <= 1) { + return 1; + } else { + return x * factorial(x - 1); + } + }; + + return factorial(value); +} + +export const FIXTURE_ENTRYPONT = { + fn: Foo, + params: [{ value: 3 }], +}; + +``` + + +## Error + +``` +[ReactForget] Todo: EnterSSA: Expected identifier to be defined before being used. Identifier factorial$3 is undefined (2:8) +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-recursive-references-inner-functions.ts b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-recursive-references-inner-functions.ts new file mode 100644 index 0000000000..0383dd3a18 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-recursive-references-inner-functions.ts @@ -0,0 +1,16 @@ +function Foo({ value }: { value: number }) { + const factorial = (x: number) => { + if (x <= 1) { + return 1; + } else { + return x * factorial(x - 1); + } + }; + + return factorial(value); +} + +export const FIXTURE_ENTRYPONT = { + fn: Foo, + params: [{ value: 3 }], +}; diff --git a/compiler/packages/sprout/src/shared-runtime.ts b/compiler/packages/sprout/src/shared-runtime.ts index 36e5e2c163..e6e46f3c53 100644 --- a/compiler/packages/sprout/src/shared-runtime.ts +++ b/compiler/packages/sprout/src/shared-runtime.ts @@ -86,6 +86,13 @@ export function useNoAlias(...args: Array): object { return noAliasObject; } +export function invoke, ReturnType>( + fn: (...input: T) => ReturnType, + ...params: T +) { + return fn(...params); +} + /** * React Components */ @@ -104,6 +111,17 @@ export function StaticText2(props: { children?: Array }) { return React.createElement("div", null, "StaticText2", props.children); } +export function RenderPropAsChild(props: { + items: Array<() => React.ReactNode>; +}) { + return React.createElement( + "div", + null, + "HigherOrderComponent", + props.items.map((item) => item()) + ); +} + export function Stringify(props: any) { return toJSON(props); }