mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Support spread elements in ArrayExpression
Similar to the previous, but for array expression: `const x = [...y]`
This commit is contained in:
@@ -858,9 +858,24 @@ function lowerExpression(
|
||||
}
|
||||
case "ArrayExpression": {
|
||||
const expr = exprPath as NodePath<t.ArrayExpression>;
|
||||
let elements: Place[] = [];
|
||||
let elements: Array<Place | SpreadPattern> = [];
|
||||
for (const element of expr.get("elements")) {
|
||||
if (element.node == null || !element.isExpression()) {
|
||||
if (element.node == null) {
|
||||
builder.errors.push({
|
||||
reason: `(BuildHIR::lowerExpression) Handle ${element.type} elements in ArrayExpression`,
|
||||
severity: ErrorSeverity.Todo,
|
||||
nodePath: element,
|
||||
});
|
||||
continue;
|
||||
} else if (element.isExpression()) {
|
||||
elements.push(lowerExpressionToTemporary(builder, element));
|
||||
} else if (element.isSpreadElement()) {
|
||||
const place = lowerExpressionToTemporary(
|
||||
builder,
|
||||
element.get("argument")
|
||||
);
|
||||
elements.push({ kind: "Spread", place });
|
||||
} else {
|
||||
builder.errors.push({
|
||||
reason: `(BuildHIR::lowerExpression) Handle ${element.type} elements in ArrayExpression`,
|
||||
severity: ErrorSeverity.Todo,
|
||||
@@ -868,9 +883,6 @@ function lowerExpression(
|
||||
});
|
||||
continue;
|
||||
}
|
||||
elements.push(
|
||||
lowerExpressionToTemporary(builder, element as NodePath<t.Expression>)
|
||||
);
|
||||
}
|
||||
return {
|
||||
kind: "ArrayExpression",
|
||||
|
||||
@@ -521,7 +521,11 @@ export type InstructionValue =
|
||||
properties: Array<ObjectProperty | SpreadPattern>;
|
||||
loc: SourceLocation;
|
||||
}
|
||||
| { kind: "ArrayExpression"; elements: Array<Place>; loc: SourceLocation }
|
||||
| {
|
||||
kind: "ArrayExpression";
|
||||
elements: Array<Place | SpreadPattern>;
|
||||
loc: SourceLocation;
|
||||
}
|
||||
| { kind: "JsxFragment"; children: Array<Place>; loc: SourceLocation }
|
||||
|
||||
// store `object.property = value`
|
||||
|
||||
@@ -222,7 +222,13 @@ export function printInstructionValue(instrValue: ReactiveValue): string {
|
||||
switch (instrValue.kind) {
|
||||
case "ArrayExpression": {
|
||||
value = `Array [${instrValue.elements
|
||||
.map((element) => printPlace(element))
|
||||
.map((element) => {
|
||||
if (element.kind === "Identifier") {
|
||||
return printPlace(element);
|
||||
} else {
|
||||
return `...${printPlace(element.place)}`;
|
||||
}
|
||||
})
|
||||
.join(", ")}]`;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -136,7 +136,13 @@ export function* eachInstructionValueOperand(
|
||||
break;
|
||||
}
|
||||
case "ArrayExpression": {
|
||||
yield* instrValue.elements;
|
||||
for (const element of instrValue.elements) {
|
||||
if (element.kind === "Identifier") {
|
||||
yield element;
|
||||
} else {
|
||||
yield element.place;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "FunctionExpression": {
|
||||
@@ -331,7 +337,14 @@ export function mapInstructionOperands(
|
||||
break;
|
||||
}
|
||||
case "ArrayExpression": {
|
||||
instrValue.elements = instrValue.elements.map((e) => fn(e));
|
||||
instrValue.elements = instrValue.elements.map((element) => {
|
||||
if (element.kind === "Identifier") {
|
||||
return fn(element);
|
||||
} else {
|
||||
element.place = fn(element.place);
|
||||
return element;
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "JsxFragment": {
|
||||
|
||||
@@ -525,9 +525,13 @@ function codegenInstructionValue(
|
||||
let value: t.Expression;
|
||||
switch (instrValue.kind) {
|
||||
case "ArrayExpression": {
|
||||
const elements = instrValue.elements.map((element) =>
|
||||
codegenPlace(cx, element)
|
||||
);
|
||||
const elements = instrValue.elements.map((element) => {
|
||||
if (element.kind === "Identifier") {
|
||||
return codegenPlace(cx, element);
|
||||
} else {
|
||||
return t.spreadElement(codegenPlace(cx, element.place));
|
||||
}
|
||||
});
|
||||
value = t.arrayExpression(elements);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
function Component(props) {
|
||||
const x = [0, ...props.foo, null, ...props.bar, "z"];
|
||||
return x;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
function Component(props) {
|
||||
const $ = React.unstable_useMemoCache(3);
|
||||
const c_0 = $[0] !== props.foo;
|
||||
const c_1 = $[1] !== props.bar;
|
||||
let t0;
|
||||
if (c_0 || c_1) {
|
||||
t0 = [0, ...props.foo, null, ...props.bar, "z"];
|
||||
$[0] = props.foo;
|
||||
$[1] = props.bar;
|
||||
$[2] = t0;
|
||||
} else {
|
||||
t0 = $[2];
|
||||
}
|
||||
const x = t0;
|
||||
return x;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
function Component(props) {
|
||||
const x = [0, ...props.foo, null, ...props.bar, "z"];
|
||||
return x;
|
||||
}
|
||||
Reference in New Issue
Block a user