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.
This commit is contained in:
Joe Savona
2023-08-31 23:16:27 +01:00
parent e36c8cb395
commit 41c23e87c5
4 changed files with 70 additions and 0 deletions
@@ -270,6 +270,20 @@ export function compileProgram(
// Main traversal to compile with Forget
program.traverse(
{
ClassDeclaration(node: NodePath<t.ClassDeclaration>) {
// Don't visit functions defined inside classes, because they
// can reference `this` which is unsafe for compilation
node.skip();
return;
},
ClassExpression(node: NodePath<t.ClassExpression>) {
// Don't visit functions defined inside classes, because they
// can reference `this` which is unsafe for compilation
node.skip();
return;
},
FunctionDeclaration(
fn: NodePath<t.FunctionDeclaration>,
pass: CompilerPass
@@ -0,0 +1,41 @@
## Input
```javascript
// @compilationMode(infer)
class Component {
_renderMessage = () => {
const Message = () => {
const message = this.state.message;
return <div>{message}</div>;
};
return <Message />;
};
render() {
return this._renderMessage();
}
}
```
## Code
```javascript
// @compilationMode(infer)
class Component {
_renderMessage = () => {
const Message = () => {
const message = this.state.message;
return <div>{message}</div>;
};
return <Message />;
};
render() {
return this._renderMessage();
}
}
```
@@ -0,0 +1,14 @@
// @compilationMode(infer)
class Component {
_renderMessage = () => {
const Message = () => {
const message = this.state.message;
return <div>{message}</div>;
};
return <Message />;
};
render() {
return this._renderMessage();
}
}
@@ -450,6 +450,7 @@ const skipFilter = new Set([
"infer-function-expression-component",
"infer-function-expression-React-memo-gating",
"infer-skip-components-without-hooks-or-jsx",
"class-component-with-render-helper",
]);
export default skipFilter;