mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Support spread patterns in object literals
Support ObjectExpression with spread items, eg `const x = {...y}`.
This commit is contained in:
@@ -33,6 +33,7 @@ import {
|
||||
Place,
|
||||
ReturnTerminal,
|
||||
SourceLocation,
|
||||
SpreadPattern,
|
||||
ThrowTerminal,
|
||||
} from "./HIR";
|
||||
import HIRBuilder from "./HIRBuilder";
|
||||
@@ -799,9 +800,48 @@ function lowerExpression(
|
||||
case "ObjectExpression": {
|
||||
const expr = exprPath as NodePath<t.ObjectExpression>;
|
||||
const propertyPaths = expr.get("properties");
|
||||
const properties: Array<ObjectProperty> = [];
|
||||
const properties: Array<ObjectProperty | SpreadPattern> = [];
|
||||
for (const propertyPath of propertyPaths) {
|
||||
if (!propertyPath.isObjectProperty()) {
|
||||
if (propertyPath.isObjectProperty()) {
|
||||
const key = propertyPath.node.key;
|
||||
let keyName: string;
|
||||
if (key.type === "Identifier") {
|
||||
keyName = key.name;
|
||||
} else if (key.type === "StringLiteral") {
|
||||
keyName = key.value;
|
||||
} else {
|
||||
builder.errors.push({
|
||||
reason: `(BuildHIR::lowerExpression) Expected Identifier, got ${key.type} key in ObjectExpression`,
|
||||
severity: ErrorSeverity.InvalidInput,
|
||||
nodePath: propertyPath,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
const valuePath = propertyPath.get("value");
|
||||
if (!valuePath.isExpression()) {
|
||||
builder.errors.push({
|
||||
reason: `(BuildHIR::lowerExpression) Handle ${valuePath.type} values in ObjectExpression`,
|
||||
severity: ErrorSeverity.Todo,
|
||||
nodePath: valuePath,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
const value = lowerExpressionToTemporary(builder, valuePath);
|
||||
properties.push({
|
||||
kind: "ObjectProperty",
|
||||
name: keyName,
|
||||
place: value,
|
||||
});
|
||||
} else if (propertyPath.isSpreadElement()) {
|
||||
const place = lowerExpressionToTemporary(
|
||||
builder,
|
||||
propertyPath.get("argument")
|
||||
);
|
||||
properties.push({
|
||||
kind: "Spread",
|
||||
place,
|
||||
});
|
||||
} else {
|
||||
builder.errors.push({
|
||||
reason: `(BuildHIR::lowerExpression) Handle ${propertyPath.type} properties in ObjectExpression`,
|
||||
severity: ErrorSeverity.Todo,
|
||||
@@ -809,35 +849,6 @@ function lowerExpression(
|
||||
});
|
||||
continue;
|
||||
}
|
||||
const key = propertyPath.node.key;
|
||||
let keyName: string;
|
||||
if (key.type === "Identifier") {
|
||||
keyName = key.name;
|
||||
} else if (key.type === "StringLiteral") {
|
||||
keyName = key.value;
|
||||
} else {
|
||||
builder.errors.push({
|
||||
reason: `(BuildHIR::lowerExpression) Expected Identifier, got ${key.type} key in ObjectExpression`,
|
||||
severity: ErrorSeverity.InvalidInput,
|
||||
nodePath: propertyPath,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
const valuePath = propertyPath.get("value");
|
||||
if (!valuePath.isExpression()) {
|
||||
builder.errors.push({
|
||||
reason: `(BuildHIR::lowerExpression) Handle ${valuePath.type} values in ObjectExpression`,
|
||||
severity: ErrorSeverity.Todo,
|
||||
nodePath: valuePath,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
const value = lowerExpressionToTemporary(builder, valuePath);
|
||||
properties.push({
|
||||
kind: "ObjectProperty",
|
||||
name: keyName,
|
||||
place: value,
|
||||
});
|
||||
}
|
||||
return {
|
||||
kind: "ObjectExpression",
|
||||
|
||||
@@ -518,7 +518,7 @@ export type InstructionValue =
|
||||
}
|
||||
| {
|
||||
kind: "ObjectExpression";
|
||||
properties: Array<ObjectProperty>; // null === empty object
|
||||
properties: Array<ObjectProperty | SpreadPattern>;
|
||||
loc: SourceLocation;
|
||||
}
|
||||
| { kind: "ArrayExpression"; elements: Array<Place>; loc: SourceLocation }
|
||||
|
||||
@@ -230,7 +230,11 @@ export function printInstructionValue(instrValue: ReactiveValue): string {
|
||||
const properties = [];
|
||||
if (instrValue.properties !== null) {
|
||||
for (const property of instrValue.properties) {
|
||||
properties.push(`${property.name}: ${printPlace(property.place)}`);
|
||||
if (property.kind === "ObjectProperty") {
|
||||
properties.push(`${property.name}: ${printPlace(property.place)}`);
|
||||
} else {
|
||||
properties.push(`...${printPlace(property.place)}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
value = `Object { ${properties.join(", ")} }`;
|
||||
|
||||
@@ -586,12 +586,16 @@ function codegenInstructionValue(
|
||||
case "ObjectExpression": {
|
||||
const properties = [];
|
||||
for (const property of instrValue.properties) {
|
||||
properties.push(
|
||||
t.objectProperty(
|
||||
t.stringLiteral(property.name),
|
||||
codegenPlace(cx, property.place)
|
||||
)
|
||||
);
|
||||
if (property.kind === "ObjectProperty") {
|
||||
properties.push(
|
||||
t.objectProperty(
|
||||
t.stringLiteral(property.name),
|
||||
codegenPlace(cx, property.place)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
properties.push(t.spreadElement(codegenPlace(cx, property.place)));
|
||||
}
|
||||
}
|
||||
value = t.objectExpression(properties);
|
||||
break;
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
function Component(props) {
|
||||
const x = { ...props.foo };
|
||||
return x;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
function Component(props) {
|
||||
const $ = React.unstable_useMemoCache(2);
|
||||
const c_0 = $[0] !== props.foo;
|
||||
let t0;
|
||||
if (c_0) {
|
||||
t0 = { ...props.foo };
|
||||
$[0] = props.foo;
|
||||
$[1] = t0;
|
||||
} else {
|
||||
t0 = $[1];
|
||||
}
|
||||
const x = t0;
|
||||
return x;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
function Component(props) {
|
||||
const x = { ...props.foo };
|
||||
return x;
|
||||
}
|
||||
Reference in New Issue
Block a user