@samitouri / QOS-React-2 / commits / ddc9f8030e

Enable compilation of FunctionExpressions

Thanks to the previous diff we can trivially support components or hooks defined as a FunctionExpression.

Joe Savona committed Aug 29, 2023 at 22:09 UTC ddc9f8030e179f01959e465261c0fd5acfe0eb4e
9 files changed +94 -6
compiler/packages/babel-plugin-react-forget/src/Entrypoint/Program.ts
+13
@@ -265,6 +265,19 @@ export function compileProgram(
265 }
266 },
267
268 + FunctionExpression(
269 + fn: NodePath<t.FunctionExpression>,
270 + pass: CompilerPass
271 + ): void {
272 + if (!shouldVisitNode(fn, pass)) {
273 + return;
274 + }
275 +
276 + if (compileAndInsertNewFunctionDeclaration(fn, pass) === true) {
277 + hasForgetMutatedOriginalSource = true;
278 + }
279 + },
280 +
281 ArrowFunctionExpression(
282 fn: NodePath<t.ArrowFunctionExpression>,
283 pass: CompilerPass
compiler/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts
+2
@@ -83,6 +83,8 @@ export function lower(
83 let id: string | null = null;
84 if (func.isFunctionDeclaration() && func.get("id").node != null) {
85 id = (func.get("id") as NodePath<t.Identifier>).node.name;
86 + } else if (func.isFunctionExpression() && func.get("id").node != null) {
87 + id = (func.get("id") as NodePath<t.Identifier>).node.name;
88 }
89 const params: Array<Place> = [];
90 func.get("params").forEach((param) => {
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/infer-function-expression-component.expect.md new
+31
@@ -0,0 +1,31 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +// @compilationMode(infer)
6 +
7 +const Component = function ComponentName(props) {
8 + return <Foo />;
9 +};
10 +
11 +```
12 +
13 +## Code
14 +
15 +```javascript
16 +import { unstable_useMemoCache as useMemoCache } from "react"; // @compilationMode(infer)
17 +
18 +const Component = function ComponentName(props) {
19 + const $ = useMemoCache(1);
20 + let t0;
21 + if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
22 + t0 = <Foo />;
23 + $[0] = t0;
24 + } else {
25 + t0 = $[0];
26 + }
27 + return t0;
28 +};
29 +
30 +```
31 +
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/infer-function-expression-component.js new
+5
@@ -0,0 +1,5 @@
1 +// @compilationMode(infer)
2 +
3 +const Component = function ComponentName(props) {
4 + return <Foo />;
5 +};
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/rules-of-hooks-9a47e97b5d13.expect.md
+14 -2
@@ -14,11 +14,23 @@ const FancyButton = React.forwardRef(function (props, ref) {
14 ## Code
15
16 ```javascript
17 -// Valid because hooks can be used in anonymous function arguments to
17 +import { unstable_useMemoCache as useMemoCache } from "react"; // Valid because hooks can be used in anonymous function arguments to
18 // forwardRef.
19 const FancyButton = React.forwardRef(function (props, ref) {
20 + const $ = useMemoCache(3);
21 useHook();
21 - return <button {...props} ref={ref} />;
22 + const c_0 = $[0] !== props;
23 + const c_1 = $[1] !== ref;
24 + let t0;
25 + if (c_0 || c_1) {
26 + t0 = <button {...props} ref={ref} />;
27 + $[0] = props;
28 + $[1] = ref;
29 + $[2] = t0;
30 + } else {
31 + t0 = $[2];
32 + }
33 + return t0;
34 });
35
36 ```
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/rules-of-hooks-e66a744cffbe.expect.md
+14 -2
@@ -14,11 +14,23 @@ const FancyButton = forwardRef(function (props, ref) {
14 ## Code
15
16 ```javascript
17 -// Valid because hooks can be used in anonymous function arguments to
17 +import { unstable_useMemoCache as useMemoCache } from "react"; // Valid because hooks can be used in anonymous function arguments to
18 // forwardRef.
19 const FancyButton = forwardRef(function (props, ref) {
20 + const $ = useMemoCache(3);
21 useHook();
21 - return <button {...props} ref={ref} />;
22 + const c_0 = $[0] !== props;
23 + const c_1 = $[1] !== ref;
24 + let t0;
25 + if (c_0 || c_1) {
26 + t0 = <button {...props} ref={ref} />;
27 + $[0] = props;
28 + $[1] = ref;
29 + $[2] = t0;
30 + } else {
31 + t0 = $[2];
32 + }
33 + return t0;
34 });
35
36 ```
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/rules-of-hooks-eacfcaa6ef89.expect.md
+12 -2
@@ -14,11 +14,21 @@ const MemoizedFunction = memo(function (props) {
14 ## Code
15
16 ```javascript
17 -// Valid because hooks can be used in anonymous function arguments to
17 +import { unstable_useMemoCache as useMemoCache } from "react"; // Valid because hooks can be used in anonymous function arguments to
18 // memo.
19 const MemoizedFunction = memo(function (props) {
20 + const $ = useMemoCache(2);
21 useHook();
21 - return <button {...props} />;
22 + const c_0 = $[0] !== props;
23 + let t0;
24 + if (c_0) {
25 + t0 = <button {...props} />;
26 + $[0] = props;
27 + $[1] = t0;
28 + } else {
29 + t0 = $[1];
30 + }
31 + return t0;
32 });
33
34 ```
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/rules-of-hooks-fe6042f7628b.expect.md
+2
@@ -2,6 +2,7 @@
2 ## Input
3
4 ```javascript
5 +// @compilationMode(infer)
6 // This is valid because "use"-prefixed functions called in
7 // unnamed function arguments are not assumed to be hooks.
8 unknownFunction(function (foo, bar) {
@@ -15,6 +16,7 @@ unknownFunction(function (foo, bar) {
16 ## Code
17
18 ```javascript
19 +// @compilationMode(infer)
20 // This is valid because "use"-prefixed functions called in
21 // unnamed function arguments are not assumed to be hooks.
22 unknownFunction(function (foo, bar) {
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/rules-of-hooks-fe6042f7628b.js
+1
@@ -1,3 +1,4 @@
1 +// @compilationMode(infer)
2 // This is valid because "use"-prefixed functions called in
3 // unnamed function arguments are not assumed to be hooks.
4 unknownFunction(function (foo, bar) {