mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Test cases for optional call
Tests, focusing on two key behaviors: * Dependencies of the args are treated as conditional, since the call may not happen * Args cannot be memoized independently, even when that would be valid for a non-optional call.
This commit is contained in:
@@ -960,8 +960,13 @@ function lowerExpression(
|
||||
const place = buildTemporaryPlace(builder, loc);
|
||||
const continuationBlock = builder.reserve(builder.currentBlockKind());
|
||||
|
||||
// Lower the callee in the current block: the callee is always unconditionally evaluated
|
||||
// The test block's branch will test on this value to determine whether to evaluate the call (consequent)
|
||||
// or evaluate to undefined (alternate)
|
||||
const callee = lowerExpressionToTemporary(builder, calleePath);
|
||||
|
||||
// block to evaluate if the callee is non-null/undefined. arguments are lowered in this block to preserve
|
||||
// the semantic of conditional evaluation depending on the callee
|
||||
const consequent = builder.enter("value", () => {
|
||||
const args = lowerArguments(builder, expr.get("arguments"));
|
||||
const temp = buildTemporaryPlace(builder, loc);
|
||||
@@ -994,6 +999,8 @@ function lowerExpression(
|
||||
id: makeInstructionId(0),
|
||||
};
|
||||
});
|
||||
|
||||
// block to evaluate if the callee is null/undefined, this sets the result of the call to undefined.
|
||||
const alternate = builder.enter("value", () => {
|
||||
const temp = buildTemporaryPlace(builder, loc);
|
||||
builder.push({
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
function Component(props) {
|
||||
const x = makeFunction(props);
|
||||
const y = x(
|
||||
<div>
|
||||
<span>{props.text}</span>
|
||||
</div>
|
||||
);
|
||||
return y;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
function Component(props) {
|
||||
const $ = React.unstable_useMemoCache(6);
|
||||
const c_0 = $[0] !== props;
|
||||
let t2;
|
||||
if (c_0) {
|
||||
const x = makeFunction(props);
|
||||
const c_2 = $[2] !== props.text;
|
||||
let t0;
|
||||
if (c_2) {
|
||||
t0 = <span>{props.text}</span>;
|
||||
$[2] = props.text;
|
||||
$[3] = t0;
|
||||
} else {
|
||||
t0 = $[3];
|
||||
}
|
||||
const c_4 = $[4] !== t0;
|
||||
let t1;
|
||||
if (c_4) {
|
||||
t1 = <div>{t0}</div>;
|
||||
$[4] = t0;
|
||||
$[5] = t1;
|
||||
} else {
|
||||
t1 = $[5];
|
||||
}
|
||||
t2 = x(t1);
|
||||
$[0] = props;
|
||||
$[1] = t2;
|
||||
} else {
|
||||
t2 = $[1];
|
||||
}
|
||||
const y = t2;
|
||||
return y;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
function Component(props) {
|
||||
const x = makeFunction(props);
|
||||
const y = x(
|
||||
<div>
|
||||
<span>{props.text}</span>
|
||||
</div>
|
||||
);
|
||||
return y;
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
function Component(props) {
|
||||
const x = makeOptionalFunction(props);
|
||||
// for a regular call, the JSX element could be independently memoized
|
||||
// since it is an immutable value. however, because the call is optional,
|
||||
// we can't extract out independent memoization for the element w/o
|
||||
// forcing that argument to evaluate unconditionally
|
||||
const y = x?.(
|
||||
<div>
|
||||
<span>{props.text}</span>
|
||||
</div>
|
||||
);
|
||||
return y;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
function Component(props) {
|
||||
const $ = React.unstable_useMemoCache(2);
|
||||
const c_0 = $[0] !== props;
|
||||
let t0;
|
||||
if (c_0) {
|
||||
const x = makeOptionalFunction(props);
|
||||
|
||||
t0 = x?.(<div>{<span>{props.text}</span>}</div>);
|
||||
$[0] = props;
|
||||
$[1] = t0;
|
||||
} else {
|
||||
t0 = $[1];
|
||||
}
|
||||
const y = t0;
|
||||
return y;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
function Component(props) {
|
||||
const x = makeOptionalFunction(props);
|
||||
// for a regular call, the JSX element could be independently memoized
|
||||
// since it is an immutable value. however, because the call is optional,
|
||||
// we can't extract out independent memoization for the element w/o
|
||||
// forcing that argument to evaluate unconditionally
|
||||
const y = x?.(
|
||||
<div>
|
||||
<span>{props.text}</span>
|
||||
</div>
|
||||
);
|
||||
return y;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
function Component(props) {
|
||||
const x = makeOptionalFunction(props);
|
||||
const y = makeObject(props);
|
||||
const z = x?.(y.a, props.a, foo(y.b), bar(props.b));
|
||||
return z;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
function Component(props) {
|
||||
const $ = React.unstable_useMemoCache(2);
|
||||
const c_0 = $[0] !== props;
|
||||
let t0;
|
||||
if (c_0) {
|
||||
const x = makeOptionalFunction(props);
|
||||
const y = makeObject(props);
|
||||
t0 = x?.(y.a, props.a, foo(y.b), bar(props.b));
|
||||
$[0] = props;
|
||||
$[1] = t0;
|
||||
} else {
|
||||
t0 = $[1];
|
||||
}
|
||||
const z = t0;
|
||||
return z;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
function Component(props) {
|
||||
const x = makeOptionalFunction(props);
|
||||
const y = makeObject(props);
|
||||
const z = x?.(y.a, props.a, foo(y.b), bar(props.b));
|
||||
return z;
|
||||
}
|
||||
Reference in New Issue
Block a user