[commit] Fix for nested optional chaining within other value blocks

Fixes a longstanding issue where we didn't support code like `useFoo(value?.bar(), value?.bar()) ?? {}` - we would attempt to construct a ReactiveFunction, recursively processing the blocks, but the inner optional `value?.bar()` wouldn't match with what the outer optional was expecting to find. It's a one-line fix!

Note: memoization in the examples is not ideal, but i've confirmed that it is not strictly related to the optional issue.
This commit is contained in:
Joe Savona
2026-01-23 11:07:42 -08:00
parent e9cca30b18
commit 26d580b79e
39 changed files with 1834 additions and 75 deletions

View File

@@ -1104,7 +1104,7 @@ class Driver {
loc,
};
return {
block: init.fallthrough,
block: final.block,
value: sequence,
place: final.place,
id: final.id,

View File

@@ -0,0 +1,109 @@
## Input
```javascript
import {Stringify} from 'shared-runtime';
// Test chained optional property access with nullish coalescing and method call
function Component(props: {obj: {a?: {b?: {getC(): string}}} | null}) {
'use memo';
const result = props.obj?.a?.b?.getC() ?? 'default';
return <Stringify value={result} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{obj: {a: {b: {getC: () => 'deep'}}}}],
sequentialRenders: [
{obj: {a: {b: {getC: () => 'deep'}}}},
{obj: null},
{obj: {a: null}},
{obj: {a: {b: null}}},
{obj: {a: {b: {getC: () => 'other'}}}},
],
};
```
## Code
```javascript
import { c as _c } from "react/compiler-runtime";
import { Stringify } from "shared-runtime";
// Test chained optional property access with nullish coalescing and method call
function Component(props) {
"use memo";
const $ = _c(4);
let t0;
if ($[0] !== props.obj?.a?.b) {
t0 = props.obj?.a?.b?.getC() ?? "default";
$[0] = props.obj?.a?.b;
$[1] = t0;
} else {
t0 = $[1];
}
const result = t0;
let t1;
if ($[2] !== result) {
t1 = <Stringify value={result} />;
$[2] = result;
$[3] = t1;
} else {
t1 = $[3];
}
return t1;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [
{
obj: {
a: {
b: {
getC: () => {
return "deep";
},
},
},
},
},
],
sequentialRenders: [
{
obj: {
a: {
b: {
getC: () => {
return "deep";
},
},
},
},
},
{ obj: null },
{ obj: { a: null } },
{ obj: { a: { b: null } } },
{
obj: {
a: {
b: {
getC: () => {
return "other";
},
},
},
},
},
],
};
```
### Eval output
(kind: ok) <div>{"value":"deep"}</div>
<div>{"value":"default"}</div>
<div>{"value":"default"}</div>
<div>{"value":"default"}</div>
<div>{"value":"other"}</div>

View File

@@ -0,0 +1,20 @@
import {Stringify} from 'shared-runtime';
// Test chained optional property access with nullish coalescing and method call
function Component(props: {obj: {a?: {b?: {getC(): string}}} | null}) {
'use memo';
const result = props.obj?.a?.b?.getC() ?? 'default';
return <Stringify value={result} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{obj: {a: {b: {getC: () => 'deep'}}}}],
sequentialRenders: [
{obj: {a: {b: {getC: () => 'deep'}}}},
{obj: null},
{obj: {a: null}},
{obj: {a: {b: null}}},
{obj: {a: {b: {getC: () => 'other'}}}},
],
};

View File

@@ -0,0 +1,53 @@
## Input
```javascript
// Test chained optional property access with nullish coalescing
function Component(props: {obj: {a?: {b?: {c: string}}} | null}) {
'use memo';
return props.obj?.a?.b?.c ?? 'default';
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{obj: {a: {b: {c: 'deep'}}}}],
sequentialRenders: [
{obj: {a: {b: {c: 'deep'}}}},
{obj: null},
{obj: {a: null}},
{obj: {a: {b: null}}},
{obj: {a: {b: {c: 'other'}}}},
],
};
```
## Code
```javascript
// Test chained optional property access with nullish coalescing
function Component(props) {
"use memo";
return props.obj?.a?.b?.c ?? "default";
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{ obj: { a: { b: { c: "deep" } } } }],
sequentialRenders: [
{ obj: { a: { b: { c: "deep" } } } },
{ obj: null },
{ obj: { a: null } },
{ obj: { a: { b: null } } },
{ obj: { a: { b: { c: "other" } } } },
],
};
```
### Eval output
(kind: ok) "deep"
"default"
"default"
"default"
"other"

View File

@@ -0,0 +1,17 @@
// Test chained optional property access with nullish coalescing
function Component(props: {obj: {a?: {b?: {c: string}}} | null}) {
'use memo';
return props.obj?.a?.b?.c ?? 'default';
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{obj: {a: {b: {c: 'deep'}}}}],
sequentialRenders: [
{obj: {a: {b: {c: 'deep'}}}},
{obj: null},
{obj: {a: null}},
{obj: {a: {b: null}}},
{obj: {a: {b: {c: 'other'}}}},
],
};

View File

@@ -0,0 +1,135 @@
## Input
```javascript
import {Stringify} from 'shared-runtime';
// Test deeply nested: optional in ternary condition with logical fallback using method calls
function Component(props: {
value: {getFlag(): boolean; getData(): string} | null;
fallback: string;
}) {
'use memo';
const value = props.value;
const result = (value?.getFlag() ? value?.getData() : null) ?? props.fallback;
return <Stringify value={result} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [
{
value: {getFlag: () => true, getData: () => 'success'},
fallback: 'default',
},
],
sequentialRenders: [
{
value: {getFlag: () => true, getData: () => 'success'},
fallback: 'default',
},
{
value: {getFlag: () => false, getData: () => 'success'},
fallback: 'default',
},
{value: null, fallback: 'default'},
{value: {getFlag: () => true, getData: () => 'other'}, fallback: 'default'},
],
};
```
## Code
```javascript
import { c as _c } from "react/compiler-runtime";
import { Stringify } from "shared-runtime";
// Test deeply nested: optional in ternary condition with logical fallback using method calls
function Component(props) {
"use memo";
const $ = _c(5);
const value = props.value;
let t0;
if ($[0] !== props.fallback || $[1] !== value) {
t0 = (value?.getFlag() ? value?.getData() : null) ?? props.fallback;
$[0] = props.fallback;
$[1] = value;
$[2] = t0;
} else {
t0 = $[2];
}
const result = t0;
let t1;
if ($[3] !== result) {
t1 = <Stringify value={result} />;
$[3] = result;
$[4] = t1;
} else {
t1 = $[4];
}
return t1;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [
{
value: {
getFlag: () => {
return true;
},
getData: () => {
return "success";
},
},
fallback: "default",
},
],
sequentialRenders: [
{
value: {
getFlag: () => {
return true;
},
getData: () => {
return "success";
},
},
fallback: "default",
},
{
value: {
getFlag: () => {
return false;
},
getData: () => {
return "success";
},
},
fallback: "default",
},
{ value: null, fallback: "default" },
{
value: {
getFlag: () => {
return true;
},
getData: () => {
return "other";
},
},
fallback: "default",
},
],
};
```
### Eval output
(kind: ok) <div>{"value":"success"}</div>
<div>{"value":"default"}</div>
<div>{"value":"default"}</div>
<div>{"value":"other"}</div>

View File

@@ -0,0 +1,34 @@
import {Stringify} from 'shared-runtime';
// Test deeply nested: optional in ternary condition with logical fallback using method calls
function Component(props: {
value: {getFlag(): boolean; getData(): string} | null;
fallback: string;
}) {
'use memo';
const value = props.value;
const result = (value?.getFlag() ? value?.getData() : null) ?? props.fallback;
return <Stringify value={result} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [
{
value: {getFlag: () => true, getData: () => 'success'},
fallback: 'default',
},
],
sequentialRenders: [
{
value: {getFlag: () => true, getData: () => 'success'},
fallback: 'default',
},
{
value: {getFlag: () => false, getData: () => 'success'},
fallback: 'default',
},
{value: null, fallback: 'default'},
{value: {getFlag: () => true, getData: () => 'other'}, fallback: 'default'},
],
};

View File

@@ -0,0 +1,64 @@
## Input
```javascript
// Test deeply nested: optional in ternary condition with logical fallback
function Component(props: {
value: {flag: boolean; data: string} | null;
fallback: string;
}) {
'use memo';
const value = props.value;
return (value?.flag ? value?.data : null) ?? props.fallback;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{value: {flag: true, data: 'success'}, fallback: 'default'}],
sequentialRenders: [
// flag true, returns data
{value: {flag: true, data: 'success'}, fallback: 'default'},
// flag false, ternary returns null, falls back
{value: {flag: false, data: 'success'}, fallback: 'default'},
// value is null, value?.flag is undefined/falsy, ternary returns null, falls back
{value: null, fallback: 'default'},
// different data value
{value: {flag: true, data: 'other'}, fallback: 'default'},
],
};
```
## Code
```javascript
// Test deeply nested: optional in ternary condition with logical fallback
function Component(props) {
"use memo";
const value = props.value;
return (value?.flag ? value?.data : null) ?? props.fallback;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{ value: { flag: true, data: "success" }, fallback: "default" }],
sequentialRenders: [
// flag true, returns data
{ value: { flag: true, data: "success" }, fallback: "default" },
// flag false, ternary returns null, falls back
{ value: { flag: false, data: "success" }, fallback: "default" },
// value is null, value?.flag is undefined/falsy, ternary returns null, falls back
{ value: null, fallback: "default" },
// different data value
{ value: { flag: true, data: "other" }, fallback: "default" },
],
};
```
### Eval output
(kind: ok) "success"
"default"
"default"
"other"

View File

@@ -0,0 +1,24 @@
// Test deeply nested: optional in ternary condition with logical fallback
function Component(props: {
value: {flag: boolean; data: string} | null;
fallback: string;
}) {
'use memo';
const value = props.value;
return (value?.flag ? value?.data : null) ?? props.fallback;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{value: {flag: true, data: 'success'}, fallback: 'default'}],
sequentialRenders: [
// flag true, returns data
{value: {flag: true, data: 'success'}, fallback: 'default'},
// flag false, ternary returns null, falls back
{value: {flag: false, data: 'success'}, fallback: 'default'},
// value is null, value?.flag is undefined/falsy, ternary returns null, falls back
{value: null, fallback: 'default'},
// different data value
{value: {flag: true, data: 'other'}, fallback: 'default'},
],
};

View File

@@ -1,37 +0,0 @@
## Input
```javascript
import {useNoAlias} from 'shared-runtime';
function useFoo(props: {value: {x: string; y: string} | null}) {
const value = props.value;
return useNoAlias(value?.x, value?.y) ?? {};
}
export const FIXTURE_ENTRYPONT = {
fn: useFoo,
props: [{value: null}],
};
```
## Error
```
Found 1 error:
Todo: Unexpected terminal kind `optional` for logical test block
error.todo-optional-call-chain-in-logical-expr.ts:5:30
3 | function useFoo(props: {value: {x: string; y: string} | null}) {
4 | const value = props.value;
> 5 | return useNoAlias(value?.x, value?.y) ?? {};
| ^^^^^^^^ Unexpected terminal kind `optional` for logical test block
6 | }
7 |
8 | export const FIXTURE_ENTRYPONT = {
```

View File

@@ -1,37 +0,0 @@
## Input
```javascript
import {useNoAlias} from 'shared-runtime';
function useFoo(props: {value: {x: string; y: string} | null}) {
const value = props.value;
return useNoAlias(value?.x, value?.y) ? {} : null;
}
export const FIXTURE_ENTRYPONT = {
fn: useFoo,
props: [{value: null}],
};
```
## Error
```
Found 1 error:
Todo: Unexpected terminal kind `optional` for ternary test block
error.todo-optional-call-chain-in-ternary.ts:5:30
3 | function useFoo(props: {value: {x: string; y: string} | null}) {
4 | const value = props.value;
> 5 | return useNoAlias(value?.x, value?.y) ? {} : null;
| ^^^^^^^^ Unexpected terminal kind `optional` for ternary test block
6 | }
7 |
8 | export const FIXTURE_ENTRYPONT = {
```

View File

@@ -0,0 +1,122 @@
## Input
```javascript
import {Stringify} from 'shared-runtime';
// Test logical expression as part of optional chain base with method call
function Component(props: {
a: {x: {getY(): string} | null} | null;
b: {x: {getY(): string}} | null;
}) {
'use memo';
const result = (props.a || props.b)?.x?.getY();
return <Stringify value={result} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{a: null, b: {x: {getY: () => 'found'}}}],
sequentialRenders: [
{a: null, b: {x: {getY: () => 'found'}}},
{a: {x: {getY: () => 'first'}}, b: {x: {getY: () => 'second'}}},
{a: null, b: null},
{a: {x: null}, b: {x: {getY: () => 'second'}}},
],
};
```
## Code
```javascript
import { c as _c } from "react/compiler-runtime";
import { Stringify } from "shared-runtime";
// Test logical expression as part of optional chain base with method call
function Component(props) {
"use memo";
const $ = _c(5);
let t0;
if ($[0] !== props.a || $[1] !== props.b) {
t0 = (props.a || props.b)?.x?.getY();
$[0] = props.a;
$[1] = props.b;
$[2] = t0;
} else {
t0 = $[2];
}
const result = t0;
let t1;
if ($[3] !== result) {
t1 = <Stringify value={result} />;
$[3] = result;
$[4] = t1;
} else {
t1 = $[4];
}
return t1;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [
{
a: null,
b: {
x: {
getY: () => {
return "found";
},
},
},
},
],
sequentialRenders: [
{
a: null,
b: {
x: {
getY: () => {
return "found";
},
},
},
},
{
a: {
x: {
getY: () => {
return "first";
},
},
},
b: {
x: {
getY: () => {
return "second";
},
},
},
},
{ a: null, b: null },
{
a: { x: null },
b: {
x: {
getY: () => {
return "second";
},
},
},
},
],
};
```
### Eval output
(kind: ok) <div>{"value":"found"}</div>
<div>{"value":"first"}</div>
<div>{}</div>
<div>{}</div>

View File

@@ -0,0 +1,22 @@
import {Stringify} from 'shared-runtime';
// Test logical expression as part of optional chain base with method call
function Component(props: {
a: {x: {getY(): string} | null} | null;
b: {x: {getY(): string}} | null;
}) {
'use memo';
const result = (props.a || props.b)?.x?.getY();
return <Stringify value={result} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{a: null, b: {x: {getY: () => 'found'}}}],
sequentialRenders: [
{a: null, b: {x: {getY: () => 'found'}}},
{a: {x: {getY: () => 'first'}}, b: {x: {getY: () => 'second'}}},
{a: null, b: null},
{a: {x: null}, b: {x: {getY: () => 'second'}}},
],
};

View File

@@ -0,0 +1,60 @@
## Input
```javascript
// Test logical expression as part of optional chain base
function Component(props: {
a: {x: {y: string} | null} | null;
b: {x: {y: string}} | null;
}) {
'use memo';
return (props.a || props.b)?.x?.y;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{a: null, b: {x: {y: 'found'}}}],
sequentialRenders: [
// a is null, uses b
{a: null, b: {x: {y: 'found'}}},
// a is truthy, uses a
{a: {x: {y: 'first'}}, b: {x: {y: 'second'}}},
// both null
{a: null, b: null},
// a is truthy but a.x is null
{a: {x: null}, b: {x: {y: 'second'}}},
],
};
```
## Code
```javascript
// Test logical expression as part of optional chain base
function Component(props) {
"use memo";
return (props.a || props.b)?.x?.y;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{ a: null, b: { x: { y: "found" } } }],
sequentialRenders: [
// a is null, uses b
{ a: null, b: { x: { y: "found" } } },
// a is truthy, uses a
{ a: { x: { y: "first" } }, b: { x: { y: "second" } } },
// both null
{ a: null, b: null },
// a is truthy but a.x is null
{ a: { x: null }, b: { x: { y: "second" } } },
],
};
```
### Eval output
(kind: ok) "found"
"first"

View File

@@ -0,0 +1,23 @@
// Test logical expression as part of optional chain base
function Component(props: {
a: {x: {y: string} | null} | null;
b: {x: {y: string}} | null;
}) {
'use memo';
return (props.a || props.b)?.x?.y;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{a: null, b: {x: {y: 'found'}}}],
sequentialRenders: [
// a is null, uses b
{a: null, b: {x: {y: 'found'}}},
// a is truthy, uses a
{a: {x: {y: 'first'}}, b: {x: {y: 'second'}}},
// both null
{a: null, b: null},
// a is truthy but a.x is null
{a: {x: null}, b: {x: {y: 'second'}}},
],
};

View File

@@ -0,0 +1,134 @@
## Input
```javascript
import {Stringify} from 'shared-runtime';
// Test optional chaining with method calls in both branches of a ternary
function Component(props: {
a: {getX(): string} | null;
b: {getY(): string} | null;
cond: boolean;
}) {
'use memo';
const result = props.cond ? props.a?.getX() : props.b?.getY();
return <Stringify value={result} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{a: {getX: () => 'hello'}, b: {getY: () => 'world'}, cond: true}],
sequentialRenders: [
{a: {getX: () => 'hello'}, b: {getY: () => 'world'}, cond: true},
{a: {getX: () => 'hello'}, b: {getY: () => 'world'}, cond: false},
{a: null, b: {getY: () => 'world'}, cond: true},
{a: {getX: () => 'hello'}, b: null, cond: false},
],
};
```
## Code
```javascript
import { c as _c } from "react/compiler-runtime";
import { Stringify } from "shared-runtime";
// Test optional chaining with method calls in both branches of a ternary
function Component(props) {
"use memo";
const $ = _c(6);
let t0;
if ($[0] !== props.a || $[1] !== props.b || $[2] !== props.cond) {
t0 = props.cond ? props.a?.getX() : props.b?.getY();
$[0] = props.a;
$[1] = props.b;
$[2] = props.cond;
$[3] = t0;
} else {
t0 = $[3];
}
const result = t0;
let t1;
if ($[4] !== result) {
t1 = <Stringify value={result} />;
$[4] = result;
$[5] = t1;
} else {
t1 = $[5];
}
return t1;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [
{
a: {
getX: () => {
return "hello";
},
},
b: {
getY: () => {
return "world";
},
},
cond: true,
},
],
sequentialRenders: [
{
a: {
getX: () => {
return "hello";
},
},
b: {
getY: () => {
return "world";
},
},
cond: true,
},
{
a: {
getX: () => {
return "hello";
},
},
b: {
getY: () => {
return "world";
},
},
cond: false,
},
{
a: null,
b: {
getY: () => {
return "world";
},
},
cond: true,
},
{
a: {
getX: () => {
return "hello";
},
},
b: null,
cond: false,
},
],
};
```
### Eval output
(kind: ok) <div>{"value":"hello"}</div>
<div>{"value":"world"}</div>
<div>{}</div>
<div>{}</div>

View File

@@ -0,0 +1,23 @@
import {Stringify} from 'shared-runtime';
// Test optional chaining with method calls in both branches of a ternary
function Component(props: {
a: {getX(): string} | null;
b: {getY(): string} | null;
cond: boolean;
}) {
'use memo';
const result = props.cond ? props.a?.getX() : props.b?.getY();
return <Stringify value={result} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{a: {getX: () => 'hello'}, b: {getY: () => 'world'}, cond: true}],
sequentialRenders: [
{a: {getX: () => 'hello'}, b: {getY: () => 'world'}, cond: true},
{a: {getX: () => 'hello'}, b: {getY: () => 'world'}, cond: false},
{a: null, b: {getY: () => 'world'}, cond: true},
{a: {getX: () => 'hello'}, b: null, cond: false},
],
};

View File

@@ -0,0 +1,61 @@
## Input
```javascript
// Test optional chaining in both branches of a ternary
function Component(props: {
a: {x: string} | null;
b: {y: string} | null;
cond: boolean;
}) {
'use memo';
return props.cond ? props.a?.x : props.b?.y;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{a: {x: 'hello'}, b: {y: 'world'}, cond: true}],
sequentialRenders: [
// cond=true, picks a?.x -> 'hello'
{a: {x: 'hello'}, b: {y: 'world'}, cond: true},
// cond=false, picks b?.y -> 'world'
{a: {x: 'hello'}, b: {y: 'world'}, cond: false},
// cond=true, a=null, picks a?.x -> undefined
{a: null, b: {y: 'world'}, cond: true},
// cond=false, b=null, picks b?.y -> undefined
{a: {x: 'hello'}, b: null, cond: false},
],
};
```
## Code
```javascript
// Test optional chaining in both branches of a ternary
function Component(props) {
"use memo";
return props.cond ? props.a?.x : props.b?.y;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{ a: { x: "hello" }, b: { y: "world" }, cond: true }],
sequentialRenders: [
// cond=true, picks a?.x -> 'hello'
{ a: { x: "hello" }, b: { y: "world" }, cond: true },
// cond=false, picks b?.y -> 'world'
{ a: { x: "hello" }, b: { y: "world" }, cond: false },
// cond=true, a=null, picks a?.x -> undefined
{ a: null, b: { y: "world" }, cond: true },
// cond=false, b=null, picks b?.y -> undefined
{ a: { x: "hello" }, b: null, cond: false },
],
};
```
### Eval output
(kind: ok) "hello"
"world"

View File

@@ -0,0 +1,24 @@
// Test optional chaining in both branches of a ternary
function Component(props: {
a: {x: string} | null;
b: {y: string} | null;
cond: boolean;
}) {
'use memo';
return props.cond ? props.a?.x : props.b?.y;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{a: {x: 'hello'}, b: {y: 'world'}, cond: true}],
sequentialRenders: [
// cond=true, picks a?.x -> 'hello'
{a: {x: 'hello'}, b: {y: 'world'}, cond: true},
// cond=false, picks b?.y -> 'world'
{a: {x: 'hello'}, b: {y: 'world'}, cond: false},
// cond=true, a=null, picks a?.x -> undefined
{a: null, b: {y: 'world'}, cond: true},
// cond=false, b=null, picks b?.y -> undefined
{a: {x: 'hello'}, b: null, cond: false},
],
};

View File

@@ -0,0 +1,85 @@
## Input
```javascript
import {Stringify, useIdentity} from 'shared-runtime';
function useFoo(props: {value: {getX(): string; getY(): string} | null}) {
'use memo';
const value = props.value;
const result = useIdentity({x: value?.getX(), y: value?.getY()}) ?? {};
return <Stringify value={result} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: useFoo,
params: [{value: null}],
sequentialRenders: [
{value: null},
{value: {getX: () => 'x1', getY: () => 'y1'}},
{value: {getX: () => 'x2', getY: () => 'y2'}},
{value: null},
],
};
```
## Code
```javascript
import { c as _c } from "react/compiler-runtime";
import { Stringify, useIdentity } from "shared-runtime";
function useFoo(props) {
"use memo";
const $ = _c(2);
const value = props.value;
const result = useIdentity({ x: value?.getX(), y: value?.getY() }) ?? {};
let t0;
if ($[0] !== result) {
t0 = <Stringify value={result} />;
$[0] = result;
$[1] = t0;
} else {
t0 = $[1];
}
return t0;
}
export const FIXTURE_ENTRYPOINT = {
fn: useFoo,
params: [{ value: null }],
sequentialRenders: [
{ value: null },
{
value: {
getX: () => {
return "x1";
},
getY: () => {
return "y1";
},
},
},
{
value: {
getX: () => {
return "x2";
},
getY: () => {
return "y2";
},
},
},
{ value: null },
],
};
```
### Eval output
(kind: ok) <div>{"value":{}}</div>
<div>{"value":{"x":"x1","y":"y1"}}</div>
<div>{"value":{"x":"x2","y":"y2"}}</div>
<div>{"value":{}}</div>

View File

@@ -0,0 +1,19 @@
import {Stringify, useIdentity} from 'shared-runtime';
function useFoo(props: {value: {getX(): string; getY(): string} | null}) {
'use memo';
const value = props.value;
const result = useIdentity({x: value?.getX(), y: value?.getY()}) ?? {};
return <Stringify value={result} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: useFoo,
params: [{value: null}],
sequentialRenders: [
{value: null},
{value: {getX: () => 'x1', getY: () => 'y1'}},
{value: {getX: () => 'x2', getY: () => 'y2'}},
{value: null},
],
};

View File

@@ -0,0 +1,40 @@
## Input
```javascript
import {useNoAlias} from 'shared-runtime';
function useFoo(props: {value: {x: string; y: string} | null}) {
'use memo';
const value = props.value;
return useNoAlias(value?.x, value?.y) ?? {};
}
export const FIXTURE_ENTRYPONT = {
fn: useFoo,
props: [{value: null}],
};
```
## Code
```javascript
import { useNoAlias } from "shared-runtime";
function useFoo(props) {
"use memo";
const value = props.value;
return useNoAlias(value?.x, value?.y) ?? {};
}
export const FIXTURE_ENTRYPONT = {
fn: useFoo,
props: [{ value: null }],
};
```
### Eval output
(kind: exception) Fixture not implemented

View File

@@ -1,6 +1,7 @@
import {useNoAlias} from 'shared-runtime';
function useFoo(props: {value: {x: string; y: string} | null}) {
'use memo';
const value = props.value;
return useNoAlias(value?.x, value?.y) ?? {};
}

View File

@@ -0,0 +1,87 @@
## Input
```javascript
import {Stringify, useIdentity} from 'shared-runtime';
function useFoo(props: {value: {getX(): string; getY(): string} | null}) {
'use memo';
const value = props.value;
const result = useIdentity({x: value?.getX(), y: value?.getY()}) ? {} : null;
return <Stringify value={result} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: useFoo,
params: [{value: null}],
sequentialRenders: [
{value: null},
{value: {getX: () => 'x1', getY: () => 'y1'}},
{value: {getX: () => 'x2', getY: () => 'y2'}},
{value: null},
],
};
```
## Code
```javascript
import { c as _c } from "react/compiler-runtime";
import { Stringify, useIdentity } from "shared-runtime";
function useFoo(props) {
"use memo";
const $ = _c(2);
const value = props.value;
const result = useIdentity({ x: value?.getX(), y: value?.getY() })
? {}
: null;
let t0;
if ($[0] !== result) {
t0 = <Stringify value={result} />;
$[0] = result;
$[1] = t0;
} else {
t0 = $[1];
}
return t0;
}
export const FIXTURE_ENTRYPOINT = {
fn: useFoo,
params: [{ value: null }],
sequentialRenders: [
{ value: null },
{
value: {
getX: () => {
return "x1";
},
getY: () => {
return "y1";
},
},
},
{
value: {
getX: () => {
return "x2";
},
getY: () => {
return "y2";
},
},
},
{ value: null },
],
};
```
### Eval output
(kind: ok) <div>{"value":{}}</div>
<div>{"value":{}}</div>
<div>{"value":{}}</div>
<div>{"value":{}}</div>

View File

@@ -0,0 +1,19 @@
import {Stringify, useIdentity} from 'shared-runtime';
function useFoo(props: {value: {getX(): string; getY(): string} | null}) {
'use memo';
const value = props.value;
const result = useIdentity({x: value?.getX(), y: value?.getY()}) ? {} : null;
return <Stringify value={result} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: useFoo,
params: [{value: null}],
sequentialRenders: [
{value: null},
{value: {getX: () => 'x1', getY: () => 'y1'}},
{value: {getX: () => 'x2', getY: () => 'y2'}},
{value: null},
],
};

View File

@@ -0,0 +1,40 @@
## Input
```javascript
import {useNoAlias} from 'shared-runtime';
function useFoo(props: {value: {x: string; y: string} | null}) {
'use memo';
const value = props.value;
return useNoAlias(value?.x, value?.y) ? {} : null;
}
export const FIXTURE_ENTRYPONT = {
fn: useFoo,
props: [{value: null}],
};
```
## Code
```javascript
import { useNoAlias } from "shared-runtime";
function useFoo(props) {
"use memo";
const value = props.value;
return useNoAlias(value?.x, value?.y) ? {} : null;
}
export const FIXTURE_ENTRYPONT = {
fn: useFoo,
props: [{ value: null }],
};
```
### Eval output
(kind: exception) Fixture not implemented

View File

@@ -1,6 +1,7 @@
import {useNoAlias} from 'shared-runtime';
function useFoo(props: {value: {x: string; y: string} | null}) {
'use memo';
const value = props.value;
return useNoAlias(value?.x, value?.y) ? {} : null;
}

View File

@@ -0,0 +1,108 @@
## Input
```javascript
import {Stringify} from 'shared-runtime';
// Test optional chaining inside logical AND (&&) with method calls
function Component(props: {value: {getX(): string} | null; enabled: boolean}) {
'use memo';
const value = props.value;
const result = props.enabled && value?.getX();
return <Stringify value={result} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{value: {getX: () => 'hello'}, enabled: true}],
sequentialRenders: [
{value: {getX: () => 'hello'}, enabled: true},
{value: {getX: () => 'hello'}, enabled: false},
{value: null, enabled: true},
{value: {getX: () => 'world'}, enabled: true},
],
};
```
## Code
```javascript
import { c as _c } from "react/compiler-runtime";
import { Stringify } from "shared-runtime";
// Test optional chaining inside logical AND (&&) with method calls
function Component(props) {
"use memo";
const $ = _c(5);
const value = props.value;
let t0;
if ($[0] !== props.enabled || $[1] !== value) {
t0 = props.enabled && value?.getX();
$[0] = props.enabled;
$[1] = value;
$[2] = t0;
} else {
t0 = $[2];
}
const result = t0;
let t1;
if ($[3] !== result) {
t1 = <Stringify value={result} />;
$[3] = result;
$[4] = t1;
} else {
t1 = $[4];
}
return t1;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [
{
value: {
getX: () => {
return "hello";
},
},
enabled: true,
},
],
sequentialRenders: [
{
value: {
getX: () => {
return "hello";
},
},
enabled: true,
},
{
value: {
getX: () => {
return "hello";
},
},
enabled: false,
},
{ value: null, enabled: true },
{
value: {
getX: () => {
return "world";
},
},
enabled: true,
},
],
};
```
### Eval output
(kind: ok) <div>{"value":"hello"}</div>
<div>{"value":false}</div>
<div>{}</div>
<div>{"value":"world"}</div>

View File

@@ -0,0 +1,20 @@
import {Stringify} from 'shared-runtime';
// Test optional chaining inside logical AND (&&) with method calls
function Component(props: {value: {getX(): string} | null; enabled: boolean}) {
'use memo';
const value = props.value;
const result = props.enabled && value?.getX();
return <Stringify value={result} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{value: {getX: () => 'hello'}, enabled: true}],
sequentialRenders: [
{value: {getX: () => 'hello'}, enabled: true},
{value: {getX: () => 'hello'}, enabled: false},
{value: null, enabled: true},
{value: {getX: () => 'world'}, enabled: true},
],
};

View File

@@ -0,0 +1,53 @@
## Input
```javascript
// Test optional chaining inside logical AND (&&)
function Component(props: {value: {x: string} | null; enabled: boolean}) {
'use memo';
const value = props.value;
return props.enabled && value?.x;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{value: {x: 'hello'}, enabled: true}],
sequentialRenders: [
{value: {x: 'hello'}, enabled: true},
{value: {x: 'hello'}, enabled: false},
{value: null, enabled: true},
{value: {x: 'world'}, enabled: true},
],
};
```
## Code
```javascript
// Test optional chaining inside logical AND (&&)
function Component(props) {
"use memo";
const value = props.value;
return props.enabled && value?.x;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{ value: { x: "hello" }, enabled: true }],
sequentialRenders: [
{ value: { x: "hello" }, enabled: true },
{ value: { x: "hello" }, enabled: false },
{ value: null, enabled: true },
{ value: { x: "world" }, enabled: true },
],
};
```
### Eval output
(kind: ok) "hello"
false
"world"

View File

@@ -0,0 +1,17 @@
// Test optional chaining inside logical AND (&&)
function Component(props: {value: {x: string} | null; enabled: boolean}) {
'use memo';
const value = props.value;
return props.enabled && value?.x;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{value: {x: 'hello'}, enabled: true}],
sequentialRenders: [
{value: {x: 'hello'}, enabled: true},
{value: {x: 'hello'}, enabled: false},
{value: null, enabled: true},
{value: {x: 'world'}, enabled: true},
],
};

View File

@@ -0,0 +1,92 @@
## Input
```javascript
import {Stringify} from 'shared-runtime';
// Test optional chaining inside logical OR (||) with method calls
function Component(props: {value: {getX(): string} | null; fallback: string}) {
'use memo';
const value = props.value;
const result = value?.getX() || props.fallback;
return <Stringify value={result} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{value: null, fallback: 'default'}],
sequentialRenders: [
{value: null, fallback: 'default'},
{value: {getX: () => 'hello'}, fallback: 'default'},
{value: {getX: () => ''}, fallback: 'default'},
{value: null, fallback: 'other'},
],
};
```
## Code
```javascript
import { c as _c } from "react/compiler-runtime";
import { Stringify } from "shared-runtime";
// Test optional chaining inside logical OR (||) with method calls
function Component(props) {
"use memo";
const $ = _c(5);
const value = props.value;
let t0;
if ($[0] !== props.fallback || $[1] !== value) {
t0 = value?.getX() || props.fallback;
$[0] = props.fallback;
$[1] = value;
$[2] = t0;
} else {
t0 = $[2];
}
const result = t0;
let t1;
if ($[3] !== result) {
t1 = <Stringify value={result} />;
$[3] = result;
$[4] = t1;
} else {
t1 = $[4];
}
return t1;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{ value: null, fallback: "default" }],
sequentialRenders: [
{ value: null, fallback: "default" },
{
value: {
getX: () => {
return "hello";
},
},
fallback: "default",
},
{
value: {
getX: () => {
return "";
},
},
fallback: "default",
},
{ value: null, fallback: "other" },
],
};
```
### Eval output
(kind: ok) <div>{"value":"default"}</div>
<div>{"value":"hello"}</div>
<div>{"value":"default"}</div>
<div>{"value":"other"}</div>

View File

@@ -0,0 +1,20 @@
import {Stringify} from 'shared-runtime';
// Test optional chaining inside logical OR (||) with method calls
function Component(props: {value: {getX(): string} | null; fallback: string}) {
'use memo';
const value = props.value;
const result = value?.getX() || props.fallback;
return <Stringify value={result} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{value: null, fallback: 'default'}],
sequentialRenders: [
{value: null, fallback: 'default'},
{value: {getX: () => 'hello'}, fallback: 'default'},
{value: {getX: () => ''}, fallback: 'default'},
{value: null, fallback: 'other'},
],
};

View File

@@ -0,0 +1,53 @@
## Input
```javascript
// Test optional chaining inside logical OR (||)
function Component(props: {value: {x: string} | null; fallback: string}) {
'use memo';
const value = props.value;
return value?.x || props.fallback;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{value: null, fallback: 'default'}],
sequentialRenders: [
{value: null, fallback: 'default'},
{value: {x: 'hello'}, fallback: 'default'},
{value: {x: ''}, fallback: 'default'},
{value: null, fallback: 'other'},
],
};
```
## Code
```javascript
// Test optional chaining inside logical OR (||)
function Component(props) {
"use memo";
const value = props.value;
return value?.x || props.fallback;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{ value: null, fallback: "default" }],
sequentialRenders: [
{ value: null, fallback: "default" },
{ value: { x: "hello" }, fallback: "default" },
{ value: { x: "" }, fallback: "default" },
{ value: null, fallback: "other" },
],
};
```
### Eval output
(kind: ok) "default"
"hello"
"default"
"other"

View File

@@ -0,0 +1,17 @@
// Test optional chaining inside logical OR (||)
function Component(props: {value: {x: string} | null; fallback: string}) {
'use memo';
const value = props.value;
return value?.x || props.fallback;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{value: null, fallback: 'default'}],
sequentialRenders: [
{value: null, fallback: 'default'},
{value: {x: 'hello'}, fallback: 'default'},
{value: {x: ''}, fallback: 'default'},
{value: null, fallback: 'other'},
],
};

View File

@@ -0,0 +1,135 @@
## Input
```javascript
import {Stringify} from 'shared-runtime';
// Test ternary expression producing the value used in optional chaining with method call
function Component(props: {
a: {getX(): string} | null;
b: {getX(): string} | null;
cond: boolean;
}) {
'use memo';
const obj = props.cond ? props.a : props.b;
const result = obj?.getX();
return <Stringify value={result} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{a: {getX: () => 'a'}, b: {getX: () => 'b'}, cond: true}],
sequentialRenders: [
{a: {getX: () => 'a'}, b: {getX: () => 'b'}, cond: true},
{a: {getX: () => 'a'}, b: {getX: () => 'b'}, cond: false},
{a: null, b: {getX: () => 'b'}, cond: true},
{a: {getX: () => 'a'}, b: null, cond: false},
],
};
```
## Code
```javascript
import { c as _c } from "react/compiler-runtime";
import { Stringify } from "shared-runtime";
// Test ternary expression producing the value used in optional chaining with method call
function Component(props) {
"use memo";
const $ = _c(4);
const obj = props.cond ? props.a : props.b;
let t0;
if ($[0] !== obj) {
t0 = obj?.getX();
$[0] = obj;
$[1] = t0;
} else {
t0 = $[1];
}
const result = t0;
let t1;
if ($[2] !== result) {
t1 = <Stringify value={result} />;
$[2] = result;
$[3] = t1;
} else {
t1 = $[3];
}
return t1;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [
{
a: {
getX: () => {
return "a";
},
},
b: {
getX: () => {
return "b";
},
},
cond: true,
},
],
sequentialRenders: [
{
a: {
getX: () => {
return "a";
},
},
b: {
getX: () => {
return "b";
},
},
cond: true,
},
{
a: {
getX: () => {
return "a";
},
},
b: {
getX: () => {
return "b";
},
},
cond: false,
},
{
a: null,
b: {
getX: () => {
return "b";
},
},
cond: true,
},
{
a: {
getX: () => {
return "a";
},
},
b: null,
cond: false,
},
],
};
```
### Eval output
(kind: ok) <div>{"value":"a"}</div>
<div>{"value":"b"}</div>
<div>{}</div>
<div>{}</div>

View File

@@ -0,0 +1,24 @@
import {Stringify} from 'shared-runtime';
// Test ternary expression producing the value used in optional chaining with method call
function Component(props: {
a: {getX(): string} | null;
b: {getX(): string} | null;
cond: boolean;
}) {
'use memo';
const obj = props.cond ? props.a : props.b;
const result = obj?.getX();
return <Stringify value={result} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{a: {getX: () => 'a'}, b: {getX: () => 'b'}, cond: true}],
sequentialRenders: [
{a: {getX: () => 'a'}, b: {getX: () => 'b'}, cond: true},
{a: {getX: () => 'a'}, b: {getX: () => 'b'}, cond: false},
{a: null, b: {getX: () => 'b'}, cond: true},
{a: {getX: () => 'a'}, b: null, cond: false},
],
};

View File

@@ -0,0 +1,56 @@
## Input
```javascript
// Test ternary expression producing the value used in optional chaining
function Component(props: {
a: {x: string} | null;
b: {x: string} | null;
cond: boolean;
}) {
'use memo';
const obj = props.cond ? props.a : props.b;
return obj?.x;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{a: {x: 'a'}, b: {x: 'b'}, cond: true}],
sequentialRenders: [
{a: {x: 'a'}, b: {x: 'b'}, cond: true}, // picks a -> 'a'
{a: {x: 'a'}, b: {x: 'b'}, cond: false}, // picks b -> 'b'
{a: null, b: {x: 'b'}, cond: true}, // picks a (null) -> undefined
{a: {x: 'a'}, b: null, cond: false}, // picks b (null) -> undefined
],
};
```
## Code
```javascript
// Test ternary expression producing the value used in optional chaining
function Component(props) {
"use memo";
const obj = props.cond ? props.a : props.b;
return obj?.x;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{ a: { x: "a" }, b: { x: "b" }, cond: true }],
sequentialRenders: [
{ a: { x: "a" }, b: { x: "b" }, cond: true }, // picks a -> 'a'
{ a: { x: "a" }, b: { x: "b" }, cond: false }, // picks b -> 'b'
{ a: null, b: { x: "b" }, cond: true }, // picks a (null) -> undefined
{ a: { x: "a" }, b: null, cond: false }, // picks b (null) -> undefined
],
};
```
### Eval output
(kind: ok) "a"
"b"

View File

@@ -0,0 +1,21 @@
// Test ternary expression producing the value used in optional chaining
function Component(props: {
a: {x: string} | null;
b: {x: string} | null;
cond: boolean;
}) {
'use memo';
const obj = props.cond ? props.a : props.b;
return obj?.x;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{a: {x: 'a'}, b: {x: 'b'}, cond: true}],
sequentialRenders: [
{a: {x: 'a'}, b: {x: 'b'}, cond: true}, // picks a -> 'a'
{a: {x: 'a'}, b: {x: 'b'}, cond: false}, // picks b -> 'b'
{a: null, b: {x: 'b'}, cond: true}, // picks a (null) -> undefined
{a: {x: 'a'}, b: null, cond: false}, // picks b (null) -> undefined
],
};