Enable compilation of FunctionExpressions

Thanks to the previous diff we can trivially support components or hooks defined 
as a FunctionExpression.
This commit is contained in:
Joe Savona
2023-08-29 22:09:41 +01:00
parent cee08ba750
commit ddc9f8030e
9 changed files with 94 additions and 6 deletions
@@ -265,6 +265,19 @@ export function compileProgram(
}
},
FunctionExpression(
fn: NodePath<t.FunctionExpression>,
pass: CompilerPass
): void {
if (!shouldVisitNode(fn, pass)) {
return;
}
if (compileAndInsertNewFunctionDeclaration(fn, pass) === true) {
hasForgetMutatedOriginalSource = true;
}
},
ArrowFunctionExpression(
fn: NodePath<t.ArrowFunctionExpression>,
pass: CompilerPass
@@ -83,6 +83,8 @@ export function lower(
let id: string | null = null;
if (func.isFunctionDeclaration() && func.get("id").node != null) {
id = (func.get("id") as NodePath<t.Identifier>).node.name;
} else if (func.isFunctionExpression() && func.get("id").node != null) {
id = (func.get("id") as NodePath<t.Identifier>).node.name;
}
const params: Array<Place> = [];
func.get("params").forEach((param) => {
@@ -0,0 +1,31 @@
## Input
```javascript
// @compilationMode(infer)
const Component = function ComponentName(props) {
return <Foo />;
};
```
## Code
```javascript
import { unstable_useMemoCache as useMemoCache } from "react"; // @compilationMode(infer)
const Component = function ComponentName(props) {
const $ = useMemoCache(1);
let t0;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t0 = <Foo />;
$[0] = t0;
} else {
t0 = $[0];
}
return t0;
};
```
@@ -0,0 +1,5 @@
// @compilationMode(infer)
const Component = function ComponentName(props) {
return <Foo />;
};
@@ -14,11 +14,23 @@ const FancyButton = React.forwardRef(function (props, ref) {
## Code
```javascript
// Valid because hooks can be used in anonymous function arguments to
import { unstable_useMemoCache as useMemoCache } from "react"; // Valid because hooks can be used in anonymous function arguments to
// forwardRef.
const FancyButton = React.forwardRef(function (props, ref) {
const $ = useMemoCache(3);
useHook();
return <button {...props} ref={ref} />;
const c_0 = $[0] !== props;
const c_1 = $[1] !== ref;
let t0;
if (c_0 || c_1) {
t0 = <button {...props} ref={ref} />;
$[0] = props;
$[1] = ref;
$[2] = t0;
} else {
t0 = $[2];
}
return t0;
});
```
@@ -14,11 +14,23 @@ const FancyButton = forwardRef(function (props, ref) {
## Code
```javascript
// Valid because hooks can be used in anonymous function arguments to
import { unstable_useMemoCache as useMemoCache } from "react"; // Valid because hooks can be used in anonymous function arguments to
// forwardRef.
const FancyButton = forwardRef(function (props, ref) {
const $ = useMemoCache(3);
useHook();
return <button {...props} ref={ref} />;
const c_0 = $[0] !== props;
const c_1 = $[1] !== ref;
let t0;
if (c_0 || c_1) {
t0 = <button {...props} ref={ref} />;
$[0] = props;
$[1] = ref;
$[2] = t0;
} else {
t0 = $[2];
}
return t0;
});
```
@@ -14,11 +14,21 @@ const MemoizedFunction = memo(function (props) {
## Code
```javascript
// Valid because hooks can be used in anonymous function arguments to
import { unstable_useMemoCache as useMemoCache } from "react"; // Valid because hooks can be used in anonymous function arguments to
// memo.
const MemoizedFunction = memo(function (props) {
const $ = useMemoCache(2);
useHook();
return <button {...props} />;
const c_0 = $[0] !== props;
let t0;
if (c_0) {
t0 = <button {...props} />;
$[0] = props;
$[1] = t0;
} else {
t0 = $[1];
}
return t0;
});
```
@@ -2,6 +2,7 @@
## Input
```javascript
// @compilationMode(infer)
// This is valid because "use"-prefixed functions called in
// unnamed function arguments are not assumed to be hooks.
unknownFunction(function (foo, bar) {
@@ -15,6 +16,7 @@ unknownFunction(function (foo, bar) {
## Code
```javascript
// @compilationMode(infer)
// This is valid because "use"-prefixed functions called in
// unnamed function arguments are not assumed to be hooks.
unknownFunction(function (foo, bar) {
@@ -1,3 +1,4 @@
// @compilationMode(infer)
// This is valid because "use"-prefixed functions called in
// unnamed function arguments are not assumed to be hooks.
unknownFunction(function (foo, bar) {