mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Partial support for update expressions
Adds limited support for UpdateExpressions (`x++`). We now support the postfix form (`x++` ok, `++x` is a todo) and only when the argument is an identifier. We can relax these restrictions with more work, but this PR should be sufficient for the examples we've seen so far.
This commit is contained in:
@@ -1405,6 +1405,55 @@ function lowerExpression(
|
||||
loc: exprLoc,
|
||||
};
|
||||
}
|
||||
case "UpdateExpression": {
|
||||
let expr = exprPath as NodePath<t.UpdateExpression>;
|
||||
const argument = expr.get("argument");
|
||||
if (!argument.isIdentifier()) {
|
||||
builder.errors.push({
|
||||
reason: `(BuildHIR::lowerExpression) Handle UpdateExpression with ${argument.type} argument`,
|
||||
severity: ErrorSeverity.Todo,
|
||||
nodePath: exprPath,
|
||||
});
|
||||
return { kind: "UnsupportedNode", node: exprNode, loc: exprLoc };
|
||||
}
|
||||
if (expr.node.prefix) {
|
||||
builder.errors.push({
|
||||
reason: `(BuildHIR::lowerExpression) Handle prefix UpdateExpression`,
|
||||
severity: ErrorSeverity.Todo,
|
||||
nodePath: exprPath,
|
||||
});
|
||||
return { kind: "UnsupportedNode", node: exprNode, loc: exprLoc };
|
||||
}
|
||||
const temp = buildTemporaryPlace(
|
||||
builder,
|
||||
expr.node.loc ?? GeneratedSource
|
||||
);
|
||||
builder.push({
|
||||
id: makeInstructionId(0),
|
||||
lvalue: { place: { ...temp }, kind: InstructionKind.Const },
|
||||
value: {
|
||||
kind: "Primitive",
|
||||
value: 1,
|
||||
loc: expr.node.loc ?? GeneratedSource,
|
||||
},
|
||||
loc: expr.node.loc ?? GeneratedSource,
|
||||
});
|
||||
const identifier = argument as NodePath<t.Identifier>;
|
||||
const place = lowerExpressionToPlace(builder, identifier);
|
||||
builder.push({
|
||||
id: makeInstructionId(0),
|
||||
lvalue: { place: { ...place }, kind: InstructionKind.Reassign },
|
||||
value: {
|
||||
kind: "BinaryExpression",
|
||||
operator: expr.node.operator === "++" ? "+" : "-",
|
||||
left: { ...place },
|
||||
right: { ...temp },
|
||||
loc: exprLoc,
|
||||
},
|
||||
loc: exprLoc,
|
||||
});
|
||||
return place;
|
||||
}
|
||||
default: {
|
||||
builder.errors.push({
|
||||
reason: `(BuildHIR::lowerExpression) Handle ${exprPath.type} expressions`,
|
||||
|
||||
@@ -52,6 +52,12 @@ function foo([a, b], { c, d, e = "e" }, f = "f", ...args) {
|
||||
}
|
||||
|
||||
do {} while (i < 3);
|
||||
|
||||
let updateIdentifier = 0;
|
||||
--updateIdentifier;
|
||||
++updateIdentifier;
|
||||
updateIdentifier.y++;
|
||||
updateIdentifier.y--;
|
||||
}
|
||||
|
||||
```
|
||||
@@ -327,8 +333,44 @@ function foo([a, b], { c, d, e = "e" }, f = "f", ...args) {
|
||||
49 |
|
||||
> 50 | do {} while (i < 3);
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
51 | }
|
||||
52 |
|
||||
51 |
|
||||
52 | let updateIdentifier = 0;
|
||||
53 | --updateIdentifier;
|
||||
|
||||
[ReactForget] TodoError: (BuildHIR::lowerExpression) Handle prefix UpdateExpression
|
||||
51 |
|
||||
52 | let updateIdentifier = 0;
|
||||
> 53 | --updateIdentifier;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
54 | ++updateIdentifier;
|
||||
55 | updateIdentifier.y++;
|
||||
56 | updateIdentifier.y--;
|
||||
|
||||
[ReactForget] TodoError: (BuildHIR::lowerExpression) Handle prefix UpdateExpression
|
||||
52 | let updateIdentifier = 0;
|
||||
53 | --updateIdentifier;
|
||||
> 54 | ++updateIdentifier;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
55 | updateIdentifier.y++;
|
||||
56 | updateIdentifier.y--;
|
||||
57 | }
|
||||
|
||||
[ReactForget] TodoError: (BuildHIR::lowerExpression) Handle UpdateExpression with MemberExpression argument
|
||||
53 | --updateIdentifier;
|
||||
54 | ++updateIdentifier;
|
||||
> 55 | updateIdentifier.y++;
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
56 | updateIdentifier.y--;
|
||||
57 | }
|
||||
58 |
|
||||
|
||||
[ReactForget] TodoError: (BuildHIR::lowerExpression) Handle UpdateExpression with MemberExpression argument
|
||||
54 | ++updateIdentifier;
|
||||
55 | updateIdentifier.y++;
|
||||
> 56 | updateIdentifier.y--;
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
57 | }
|
||||
58 |
|
||||
```
|
||||
|
||||
|
||||
@@ -48,4 +48,10 @@ function foo([a, b], { c, d, e = "e" }, f = "f", ...args) {
|
||||
}
|
||||
|
||||
do {} while (i < 3);
|
||||
|
||||
let updateIdentifier = 0;
|
||||
--updateIdentifier;
|
||||
++updateIdentifier;
|
||||
updateIdentifier.y++;
|
||||
updateIdentifier.y--;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
```javascript
|
||||
function foo() {
|
||||
let x = 1;
|
||||
for (let i = 0; i < 10; i += 1) {
|
||||
for (let i = 0; i < 10; i++) {
|
||||
x += 1;
|
||||
}
|
||||
return x;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
function foo() {
|
||||
let x = 1;
|
||||
for (let i = 0; i < 10; i += 1) {
|
||||
for (let i = 0; i < 10; i++) {
|
||||
x += 1;
|
||||
}
|
||||
return x;
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
function foo(props) {
|
||||
let x = props.x;
|
||||
let y = x++;
|
||||
let z = x--;
|
||||
return { x, y, z };
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
function foo(props) {
|
||||
const $ = React.useMemoCache();
|
||||
const x = props.x;
|
||||
const x$0 = x + 1;
|
||||
const y = x$0;
|
||||
const x$1 = x$0 - 1;
|
||||
const z = x$1;
|
||||
let t0;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t0 = { x: x$1, y: y, z: z };
|
||||
$[0] = t0;
|
||||
} else {
|
||||
t0 = $[0];
|
||||
}
|
||||
return t0;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
function foo(props) {
|
||||
let x = props.x;
|
||||
let y = x++;
|
||||
let z = x--;
|
||||
return { x, y, z };
|
||||
}
|
||||
Reference in New Issue
Block a user