From c70e87f53501f329b25c4e78e2eafc0aab270292 Mon Sep 17 00:00:00 2001 From: Joe Savona Date: Thu, 14 Sep 2023 21:48:04 -0700 Subject: [PATCH] Wrap JSXElement in expr container (for JSXAttribute) --- .../ReactiveScopes/CodegenReactiveFunction.ts | 3 +- ...attribute-with-jsx-element-value.expect.md | 113 ++++++++++++++++++ .../jsx-attribute-with-jsx-element-value.js | 34 ++++++ 3 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/jsx-attribute-with-jsx-element-value.expect.md create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/jsx-attribute-with-jsx-element-value.js diff --git a/compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/CodegenReactiveFunction.ts b/compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/CodegenReactiveFunction.ts index 67cc064a67..9add710317 100644 --- a/compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/CodegenReactiveFunction.ts +++ b/compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/CodegenReactiveFunction.ts @@ -1279,8 +1279,7 @@ function codegenJsxAttribute( const innerValue = codegenPlace(cx, attribute.place); let value; switch (innerValue.type) { - case "StringLiteral": - case "JSXElement": { + case "StringLiteral": { value = innerValue; break; } diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/jsx-attribute-with-jsx-element-value.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/jsx-attribute-with-jsx-element-value.expect.md new file mode 100644 index 0000000000..ffda50685d --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/jsx-attribute-with-jsx-element-value.expect.md @@ -0,0 +1,113 @@ + +## Input + +```javascript +// @flow +function Component({ items }) { + // Per the spec, {...} /> is valid. + // But many tools don't allow fragments as jsx attribute values, + // so we ensure not to emit them wrapped in an expression container + return items.length > 0 ? ( + + {items.map((item) => ( + + ))} + + } + > + ) : null; +} + +function Foo({ value }) { + return value; +} + +function Bar({ children }) { + return
{children}
; +} + +function Item({ item }) { + return
{item.name}
; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ items: [{ id: 1, name: "One!" }] }], +}; + +``` + +## Code + +```javascript +import { unstable_useMemoCache as useMemoCache } from "react"; +function Component(t29) { + const $ = useMemoCache(2); + const { items } = t29; + const c_0 = $[0] !== items; + let t0; + if (c_0) { + t0 = + items.length > 0 ? ( + + {items.map((item) => ( + + ))} + + } + /> + ) : null; + $[0] = items; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; +} + +function Foo(t5) { + const { value } = t5; + return value; +} + +function Bar(t6) { + const $ = useMemoCache(2); + const { children } = t6; + const c_0 = $[0] !== children; + let t0; + if (c_0) { + t0 =
{children}
; + $[0] = children; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; +} + +function Item(t7) { + const $ = useMemoCache(2); + const { item } = t7; + const c_0 = $[0] !== item.name; + let t0; + if (c_0) { + t0 =
{item.name}
; + $[0] = item.name; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ items: [{ id: 1, name: "One!" }] }], +}; + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/jsx-attribute-with-jsx-element-value.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/jsx-attribute-with-jsx-element-value.js new file mode 100644 index 0000000000..f54d20af9f --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/jsx-attribute-with-jsx-element-value.js @@ -0,0 +1,34 @@ +// @flow +function Component({ items }) { + // Per the spec, {...} /> is valid. + // But many tools don't allow fragments as jsx attribute values, + // so we ensure not to emit them wrapped in an expression container + return items.length > 0 ? ( + + {items.map((item) => ( + + ))} + + } + > + ) : null; +} + +function Foo({ value }) { + return value; +} + +function Bar({ children }) { + return
{children}
; +} + +function Item({ item }) { + return
{item.name}
; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ items: [{ id: 1, name: "One!" }] }], +};