The library for web and native user interfaces.
Disable compilation of "Components" inside class methods
Minimal repro extracted from our internal codebase. Our inference mode sees that this arrow function is component-like and attempts to compile it, which then fails because the function accesses `this` which we bailout on.
Joe Savona committed
Aug 31, 2023 at 23:16 UTC
41c23e87c52b958f7c93b0f94940abc50a2ead8d
4 files changed
+70
compiler/packages/babel-plugin-react-forget/src/Entrypoint/Program.ts
+14
@@ -270,6 +270,20 @@ export function compileProgram(
270
// Main traversal to compile with Forget
271
program.traverse(
272
{
273
+ ClassDeclaration(node: NodePath<t.ClassDeclaration>) {
274
+ // Don't visit functions defined inside classes, because they
275
+ // can reference `this` which is unsafe for compilation
276
+ node.skip();
277
+ return;
278
+ },
279
+
280
+ ClassExpression(node: NodePath<t.ClassExpression>) {
281
+ // Don't visit functions defined inside classes, because they
282
+ // can reference `this` which is unsafe for compilation
283
+ node.skip();
284
+ return;
285
+ },
286
+
287
FunctionDeclaration(
288
fn: NodePath<t.FunctionDeclaration>,
289
pass: CompilerPass
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/class-component-with-render-helper.expect.md
new
+41
@@ -0,0 +1,41 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+// @compilationMode(infer)
6
+class Component {
7
+ _renderMessage = () => {
8
+ const Message = () => {
9
+ const message = this.state.message;
10
+ return <div>{message}</div>;
11
+ };
12
+ return <Message />;
13
+ };
14
+
15
+ render() {
16
+ return this._renderMessage();
17
+ }
18
+}
19
+
20
+```
21
+
22
+## Code
23
+
24
+```javascript
25
+// @compilationMode(infer)
26
+class Component {
27
+ _renderMessage = () => {
28
+ const Message = () => {
29
+ const message = this.state.message;
30
+ return <div>{message}</div>;
31
+ };
32
+ return <Message />;
33
+ };
34
+
35
+ render() {
36
+ return this._renderMessage();
37
+ }
38
+}
39
+
40
+```
41
+
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/class-component-with-render-helper.js
new
+14
@@ -0,0 +1,14 @@
1
+// @compilationMode(infer)
2
+class Component {
3
+ _renderMessage = () => {
4
+ const Message = () => {
5
+ const message = this.state.message;
6
+ return <div>{message}</div>;
7
+ };
8
+ return <Message />;
9
+ };
10
+
11
+ render() {
12
+ return this._renderMessage();
13
+ }
14
+}
compiler/packages/sprout/src/SproutTodoFilter.ts
+1
@@ -450,6 +450,7 @@ const skipFilter = new Set([
450
"infer-function-expression-component",
451
"infer-function-expression-React-memo-gating",
452
"infer-skip-components-without-hooks-or-jsx",
453
+ "class-component-with-render-helper",
454
]);
455
456
export default skipFilter;