mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Support JSX fragments (#736)
* handle jsx fragments * update effects for jsx fragments
This commit is contained in:
@@ -957,6 +957,17 @@ function lowerExpression(
|
||||
loc: exprLoc,
|
||||
};
|
||||
}
|
||||
case "JSXFragment": {
|
||||
const expr = exprPath as NodePath<t.JSXFragment>;
|
||||
const children = expr
|
||||
.get("children")
|
||||
.map((child) => lowerJsxElement(builder, child));
|
||||
return {
|
||||
kind: "JsxFragment",
|
||||
children,
|
||||
loc: exprLoc,
|
||||
};
|
||||
}
|
||||
default: {
|
||||
todo(`lowerExpression(${exprNode.type})`);
|
||||
// assertExhaustive(
|
||||
@@ -1082,7 +1093,7 @@ function lowerJsxElement(
|
||||
): Place {
|
||||
const exprNode = exprPath.node;
|
||||
const exprLoc = exprNode.loc ?? GeneratedSource;
|
||||
if (exprPath.isJSXElement()) {
|
||||
if (exprPath.isJSXElement() || exprPath.isJSXFragment()) {
|
||||
return lowerExpressionToPlace(builder, exprPath);
|
||||
} else if (exprPath.isJSXExpressionContainer()) {
|
||||
const expression = exprPath.get("expression");
|
||||
|
||||
@@ -247,6 +247,14 @@ function writeInstr(cx: Context, instr: Instruction, body: Array<t.Statement>) {
|
||||
);
|
||||
break;
|
||||
}
|
||||
case "JsxFragment": {
|
||||
value = t.jsxFragment(
|
||||
t.jsxOpeningFragment(),
|
||||
t.jsxClosingFragment(),
|
||||
instrValue.children.map((child) => codegenJsxElement(cx, child))
|
||||
);
|
||||
break;
|
||||
}
|
||||
case "OtherStatement": {
|
||||
const node = instrValue.node;
|
||||
if (t.isStatement(node)) {
|
||||
|
||||
@@ -207,6 +207,7 @@ export type InstructionData =
|
||||
properties: Map<string, Place> | null; // null === empty object
|
||||
}
|
||||
| { kind: "ArrayExpression"; elements: Array<Place> }
|
||||
| { kind: "JsxFragment"; children: Array<Place> }
|
||||
|
||||
/**
|
||||
* Catch-all for statements such as type imports, nested class declarations, etc
|
||||
|
||||
@@ -574,6 +574,13 @@ function inferBlock(env: Environment, block: BasicBlock) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "JsxFragment": {
|
||||
valueKind = ValueKind.Frozen;
|
||||
for (const child of instrValue.children) {
|
||||
env.reference(child, Effect.Freeze);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "JSXText":
|
||||
case "Primitive": {
|
||||
valueKind = ValueKind.Immutable;
|
||||
|
||||
@@ -215,6 +215,12 @@ function printInstructionValue(instrValue: InstructionValue): string {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "JsxFragment": {
|
||||
value = `JsxFragment [${instrValue.children
|
||||
.map((child) => printPlace(child))
|
||||
.join(", ")}]`;
|
||||
break;
|
||||
}
|
||||
case "NewExpression": {
|
||||
value = `New ${printPlace(instrValue.callee)}(${instrValue.args
|
||||
.map((arg) => printPlace(arg))
|
||||
|
||||
@@ -344,6 +344,10 @@ function rewriteUses(instr: Instruction, builder: SSABuilder) {
|
||||
instrValue.elements = instrValue.elements.map((e) => builder.getPlace(e));
|
||||
break;
|
||||
}
|
||||
case "JsxFragment": {
|
||||
instrValue.children = instrValue.children.map((e) => builder.getPlace(e));
|
||||
break;
|
||||
}
|
||||
case "OtherStatement":
|
||||
case "Primitive":
|
||||
case "JSXText": {
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
function Foo(props) {
|
||||
return (
|
||||
<>
|
||||
Hello {props.greeting}{" "}
|
||||
<div>
|
||||
<>Text</>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## HIR
|
||||
|
||||
```
|
||||
bb0:
|
||||
Const mutate $14 = "\n Hello "
|
||||
Const mutate $15 = " "
|
||||
Const mutate $16 = "\n "
|
||||
Const mutate $17 = "div"
|
||||
Const mutate $18 = "\n "
|
||||
Const mutate $19 = "Text"
|
||||
Const mutate $20 = JsxFragment [read $19]
|
||||
Const mutate $21 = "\n "
|
||||
Const mutate $22 = JSX <read $17>{read $18}{read $20}{read $21}</read $17>
|
||||
Const mutate $23 = "\n "
|
||||
Const mutate $24 = JsxFragment [read $14, read props$13.greeting, read $15, read $16, read $22, read $23]
|
||||
Return read $24
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
function Foo$0(props$13) {
|
||||
return (
|
||||
<>
|
||||
Hello {props$13.greeting}
|
||||
{<div>{<>Text</>}</div>}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
function Foo(props) {
|
||||
return (
|
||||
<>
|
||||
Hello {props.greeting}{" "}
|
||||
<div>
|
||||
<>Text</>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user