diff --git a/compiler/forget/src/HIR/BuildHIR.ts b/compiler/forget/src/HIR/BuildHIR.ts index fe33c5b62e..e150be4f09 100644 --- a/compiler/forget/src/HIR/BuildHIR.ts +++ b/compiler/forget/src/HIR/BuildHIR.ts @@ -1352,9 +1352,10 @@ function lowerExpression( const expr = exprPath as NodePath; const opening = expr.get("openingElement"); const tag = lowerJsxElementName(builder, opening.get("name")); - const children = expr + const children: Array = expr .get("children") - .map((child) => lowerJsxElement(builder, child)); + .map((child) => lowerJsxElement(builder, child)) + .filter(notNull); const props: Array = []; for (const attribute of opening.get("attributes")) { if (attribute.isJSXSpreadAttribute()) { @@ -1426,9 +1427,10 @@ function lowerExpression( } case "JSXFragment": { const expr = exprPath as NodePath; - const children = expr + const children: Array = expr .get("children") - .map((child) => lowerJsxElement(builder, child)); + .map((child) => lowerJsxElement(builder, child)) + .filter(notNull); return { kind: "JsxFragment", children, @@ -1950,27 +1952,22 @@ function lowerJsxElement( | t.JSXElement | t.JSXFragment > -): Place { +): Place | null { const exprNode = exprPath.node; const exprLoc = exprNode.loc ?? GeneratedSource; if (exprPath.isJSXElement() || exprPath.isJSXFragment()) { return lowerExpressionToTemporary(builder, exprPath); } else if (exprPath.isJSXExpressionContainer()) { const expression = exprPath.get("expression"); - if (!expression.isExpression()) { - builder.errors.push({ - reason: `(BuildHIR::lowerJsxElement) Handle ${expression.type} expressions`, - severity: ErrorSeverity.Todo, - nodePath: expression, - }); - const place = lowerValueToTemporary(builder, { - kind: "UnsupportedNode", - node: exprNode, - loc: exprLoc, - }); - return { ...place }; + if (expression.isJSXEmptyExpression()) { + return null; + } else { + invariant( + expression.isExpression(), + `(BuildHIR::lowerJsxElement) Expected Expression but found ${expression.type}!` + ); + return lowerExpressionToTemporary(builder, expression); } - return lowerExpressionToTemporary(builder, expression); } else if (exprPath.isJSXText()) { const place = lowerValueToTemporary(builder, { kind: "JSXText", @@ -2465,3 +2462,7 @@ function gatherCapturedDeps( return { identifiers: [...capturedIds], refs: [...capturedRefs] }; } + +function notNull(value: T | null): value is T { + return value !== null; +} diff --git a/compiler/forget/src/__tests__/fixtures/compiler/error.todo-kitchensink.expect.md b/compiler/forget/src/__tests__/fixtures/compiler/error.todo-kitchensink.expect.md index de37287be2..133c7b8096 100644 --- a/compiler/forget/src/__tests__/fixtures/compiler/error.todo-kitchensink.expect.md +++ b/compiler/forget/src/__tests__/fixtures/compiler/error.todo-kitchensink.expect.md @@ -120,15 +120,6 @@ let moduleLocal = false; 14 | 15 | ; -[ReactForget] TodoError: (BuildHIR::lowerJsxElement) Handle JSXEmptyExpression expressions - 14 | - 15 | ; -> 16 | ; - | ^^^^^^^^^^^^ - 17 | - 18 | const j = function bar([quz, qux], ...args) {}; - 19 | - [ReactForget] TodoError: (BuildHIR::lower) Handle RestElement params 16 | ; 17 | diff --git a/compiler/forget/src/__tests__/fixtures/compiler/jsx-empty-expression.expect.md b/compiler/forget/src/__tests__/fixtures/compiler/jsx-empty-expression.expect.md new file mode 100644 index 0000000000..69fcea893c --- /dev/null +++ b/compiler/forget/src/__tests__/fixtures/compiler/jsx-empty-expression.expect.md @@ -0,0 +1,34 @@ + +## Input + +```javascript +export function Component(props) { + return ( +
+ {} + {props.a} +
+ ); +} + +``` + +## Code + +```javascript +export function Component(props) { + const $ = React.unstable_useMemoCache(2); + const c_0 = $[0] !== props.a; + let t0; + if (c_0) { + t0 =
{props.a}
; + $[0] = props.a; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; +} + +``` + \ No newline at end of file diff --git a/compiler/forget/src/__tests__/fixtures/compiler/jsx-empty-expression.js b/compiler/forget/src/__tests__/fixtures/compiler/jsx-empty-expression.js new file mode 100644 index 0000000000..357f27186e --- /dev/null +++ b/compiler/forget/src/__tests__/fixtures/compiler/jsx-empty-expression.js @@ -0,0 +1,8 @@ +export function Component(props) { + return ( +
+ {} + {props.a} +
+ ); +}