Skip to content

Commit 9c02c87

Browse files
committed
[compiler][ez] Patch hoistability for ObjectMethods
Extends #31066 to ObjectMethods (somehow missed this before).
1 parent 69d4b80 commit 9c02c87

File tree

3 files changed

+114
-2
lines changed

3 files changed

+114
-2
lines changed

compiler/packages/babel-plugin-react-compiler/src/HIR/CollectHoistablePropertyLoads.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,8 @@ function collectNonNullsInBlocks(
348348
assumedNonNullObjects.add(maybeNonNull);
349349
}
350350
if (
351-
instr.value.kind === 'FunctionExpression' &&
351+
(instr.value.kind === 'FunctionExpression' ||
352+
instr.value.kind === 'ObjectMethod') &&
352353
!fn.env.config.enableTreatFunctionDepsAsConditional
353354
) {
354355
const innerFn = instr.value.loweredFunc;
@@ -591,7 +592,10 @@ function collectFunctionExpressionFakeLoads(
591592

592593
for (const [_, block] of fn.body.blocks) {
593594
for (const {lvalue, value} of block.instructions) {
594-
if (value.kind === 'FunctionExpression') {
595+
if (
596+
value.kind === 'FunctionExpression' ||
597+
value.kind === 'ObjectMethod'
598+
) {
595599
for (const reference of value.loweredFunc.dependencies) {
596600
let curr: IdentifierId | undefined = reference.identifier.id;
597601
while (curr != null) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
2+
## Input
3+
4+
```javascript
5+
// @enablePropagateDepsInHIR
6+
import {Stringify} from 'shared-runtime';
7+
8+
function Foo({a, shouldReadA}) {
9+
return (
10+
<Stringify
11+
objectMethod={{
12+
method() {
13+
if (shouldReadA) return a.b.c;
14+
return null;
15+
},
16+
}}
17+
shouldInvokeFns={true}
18+
/>
19+
);
20+
}
21+
22+
export const FIXTURE_ENTRYPOINT = {
23+
fn: Foo,
24+
params: [{a: null, shouldReadA: true}],
25+
sequentialRenders: [
26+
{a: null, shouldReadA: true},
27+
{a: null, shouldReadA: false},
28+
{a: {b: {c: 4}}, shouldReadA: true},
29+
],
30+
};
31+
32+
```
33+
34+
## Code
35+
36+
```javascript
37+
import { c as _c } from "react/compiler-runtime"; // @enablePropagateDepsInHIR
38+
import { Stringify } from "shared-runtime";
39+
40+
function Foo(t0) {
41+
const $ = _c(3);
42+
const { a, shouldReadA } = t0;
43+
let t1;
44+
if ($[0] !== shouldReadA || $[1] !== a) {
45+
t1 = (
46+
<Stringify
47+
objectMethod={{
48+
method() {
49+
if (shouldReadA) {
50+
return a.b.c;
51+
}
52+
return null;
53+
},
54+
}}
55+
shouldInvokeFns={true}
56+
/>
57+
);
58+
$[0] = shouldReadA;
59+
$[1] = a;
60+
$[2] = t1;
61+
} else {
62+
t1 = $[2];
63+
}
64+
return t1;
65+
}
66+
67+
export const FIXTURE_ENTRYPOINT = {
68+
fn: Foo,
69+
params: [{ a: null, shouldReadA: true }],
70+
sequentialRenders: [
71+
{ a: null, shouldReadA: true },
72+
{ a: null, shouldReadA: false },
73+
{ a: { b: { c: 4 } }, shouldReadA: true },
74+
],
75+
};
76+
77+
```
78+
79+
### Eval output
80+
(kind: ok) [[ (exception in render) TypeError: Cannot read properties of null (reading 'b') ]]
81+
<div>{"objectMethod":{"method":{"kind":"Function","result":null}},"shouldInvokeFns":true}</div>
82+
<div>{"objectMethod":{"method":{"kind":"Function","result":4}},"shouldInvokeFns":true}</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// @enablePropagateDepsInHIR
2+
import {Stringify} from 'shared-runtime';
3+
4+
function Foo({a, shouldReadA}) {
5+
return (
6+
<Stringify
7+
objectMethod={{
8+
method() {
9+
if (shouldReadA) return a.b.c;
10+
return null;
11+
},
12+
}}
13+
shouldInvokeFns={true}
14+
/>
15+
);
16+
}
17+
18+
export const FIXTURE_ENTRYPOINT = {
19+
fn: Foo,
20+
params: [{a: null, shouldReadA: true}],
21+
sequentialRenders: [
22+
{a: null, shouldReadA: true},
23+
{a: null, shouldReadA: false},
24+
{a: {b: {c: 4}}, shouldReadA: true},
25+
],
26+
};

0 commit comments

Comments
 (0)