Skip to content

Commit 63cce17

Browse files
committed
[compiler] Make inserting outlined functions more resilient
To handle more cases, always append the synthetic outlined function as a new child of the module rather than make assumptions about the original function. This should handle whatever case where the original function expression may be a child of a variety of parents ghstack-source-id: 4a0d861 Pull Request resolved: #30466
1 parent 8b0e900 commit 63cce17

File tree

5 files changed

+59
-56
lines changed

5 files changed

+59
-56
lines changed

compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Program.ts

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ export function createNewFunctionNode(
196196
}
197197

198198
function insertNewOutlinedFunctionNode(
199+
program: NodePath<t.Program>,
199200
originalFn: BabelFn,
200201
compiledFn: CodegenFunction,
201202
): NodePath<t.Function> {
@@ -216,14 +217,6 @@ function insertNewOutlinedFunctionNode(
216217
*/
217218
case 'ArrowFunctionExpression':
218219
case 'FunctionExpression': {
219-
CompilerError.invariant(
220-
originalFn.parentPath.isVariableDeclarator() &&
221-
originalFn.parentPath.parentPath.isVariableDeclaration(),
222-
{
223-
reason: 'Expected a variable declarator parent',
224-
loc: originalFn.node.loc ?? null,
225-
},
226-
);
227220
const fn: t.FunctionDeclaration = {
228221
type: 'FunctionDeclaration',
229222
id: compiledFn.id,
@@ -233,8 +226,7 @@ function insertNewOutlinedFunctionNode(
233226
params: compiledFn.params,
234227
body: compiledFn.body,
235228
};
236-
const varDecl = originalFn.parentPath.parentPath;
237-
const insertedFuncDecl = varDecl.insertAfter(fn)[0]!;
229+
const insertedFuncDecl = program.pushContainer('body', [fn])[0]!;
238230
CompilerError.invariant(insertedFuncDecl.isFunctionDeclaration(), {
239231
reason: 'Expected inserted function declaration',
240232
description: `Got: ${insertedFuncDecl}`,
@@ -468,7 +460,11 @@ export function compileProgram(
468460
reason: 'Unexpected nested outlined functions',
469461
loc: outlined.fn.loc,
470462
});
471-
const fn = insertNewOutlinedFunctionNode(current.fn, outlined.fn);
463+
const fn = insertNewOutlinedFunctionNode(
464+
program,
465+
current.fn,
466+
outlined.fn,
467+
);
472468
fn.skip();
473469
ALREADY_COMPILED.add(fn.node);
474470
if (outlined.type !== null) {

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.bug-outlining-in-react-memo.expect.md

Lines changed: 0 additions & 42 deletions
This file was deleted.

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/outlining-in-func-expr.expect.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,6 @@ const Component2 = (props) => {
5050
}
5151
return t1;
5252
};
53-
function _temp(item) {
54-
return <li key={item.id}>{item.name}</li>;
55-
}
5653

5754
export const FIXTURE_ENTRYPOINT = {
5855
fn: Component2,
@@ -65,6 +62,9 @@ export const FIXTURE_ENTRYPOINT = {
6562
},
6663
],
6764
};
65+
function _temp(item) {
66+
return <li key={item.id}>{item.name}</li>;
67+
}
6868

6969
```
7070
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
2+
## Input
3+
4+
```javascript
5+
const View = React.memo(({items}) => {
6+
return (
7+
<ul>
8+
{items.map(item => (
9+
<li key={item.id}>{item.name}</li>
10+
))}
11+
</ul>
12+
);
13+
});
14+
15+
```
16+
17+
## Code
18+
19+
```javascript
20+
import { c as _c } from "react/compiler-runtime";
21+
const View = React.memo((t0) => {
22+
const $ = _c(4);
23+
const { items } = t0;
24+
let t1;
25+
if ($[0] !== items) {
26+
t1 = items.map(_temp);
27+
$[0] = items;
28+
$[1] = t1;
29+
} else {
30+
t1 = $[1];
31+
}
32+
let t2;
33+
if ($[2] !== t1) {
34+
t2 = <ul>{t1}</ul>;
35+
$[2] = t1;
36+
$[3] = t2;
37+
} else {
38+
t2 = $[3];
39+
}
40+
return t2;
41+
});
42+
function _temp(item) {
43+
return <li key={item.id}>{item.name}</li>;
44+
}
45+
46+
```
47+
48+
### Eval output
49+
(kind: exception) Fixture not implemented

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.bug-outlining-in-react-memo.js renamed to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/outlining-in-react-memo.js

File renamed without changes.

0 commit comments

Comments
 (0)