@samitouri / QOS-React / commits / b28bb19e44

[codegen] Don't drop directives in simple arrow fn

The compiler has an optimisation where it transforms a simple arrow function with only a return statement to a implicit arrow function. In the case, there's a directive in this simple arrow function, the directive gets dropped. Instead of dropping the directive, the compiler should perform this optimisation only if there are no directives. ghstack-source-id: 514cd2440025986a2d6d950694a7339d779b09f2 Pull Request resolved: https://github.com/facebook/react-forget/pull/2848

Sathya Gunsasekaran committed Apr 15, 2024 at 15:52 UTC b28bb19e44d4624ffda33ff5f3a7a2dcce291635
5 files changed +125 -1
compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/CodegenReactiveFunction.ts
+1 -1
@@ -1646,7 +1646,7 @@ function codegenInstructionValue(
1646 ).unwrap();
1647 if (instrValue.expr.type === "ArrowFunctionExpression") {
1648 let body: t.BlockStatement | t.Expression = fn.body;
1649 - if (body.body.length === 1) {
1649 + if (body.body.length === 1 && loweredFunc.directives.length == 0) {
1650 const stmt = body.body[0]!;
1651 if (stmt.type === "ReturnStatement" && stmt.argument != null) {
1652 body = stmt.argument;
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/arrow-expr-directive.expect.md new
+52
@@ -0,0 +1,52 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function Component() {
6 + "use strict";
7 + let [count, setCount] = React.useState(0);
8 + const update = () => {
9 + "worklet";
10 + setCount((count) => count + 1);
11 + };
12 + return <button onClick={update}>{count}</button>;
13 +}
14 +
15 +```
16 +
17 +## Code
18 +
19 +```javascript
20 +import { unstable_useMemoCache as useMemoCache } from "react";
21 +function Component() {
22 + "use strict";
23 + const $ = useMemoCache(3);
24 +
25 + const [count, setCount] = React.useState(0);
26 + let t0;
27 + if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
28 + t0 = () => {
29 + "worklet";
30 +
31 + setCount((count_0) => count_0 + 1);
32 + };
33 + $[0] = t0;
34 + } else {
35 + t0 = $[0];
36 + }
37 + const update = t0;
38 + let t1;
39 + if ($[1] !== count) {
40 + t1 = <button onClick={update}>{count}</button>;
41 + $[1] = count;
42 + $[2] = t1;
43 + } else {
44 + t1 = $[2];
45 + }
46 + return t1;
47 +}
48 +
49 +```
50 +
51 +### Eval output
52 +(kind: exception) Fixture not implemented
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/arrow-expr-directive.js new
+9
@@ -0,0 +1,9 @@
1 +function Component() {
2 + "use strict";
3 + let [count, setCount] = React.useState(0);
4 + const update = () => {
5 + "worklet";
6 + setCount((count) => count + 1);
7 + };
8 + return <button onClick={update}>{count}</button>;
9 +}
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/arrow-function-one-line-directive.expect.md new
+50
@@ -0,0 +1,50 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function useFoo() {
6 + const update = () => {
7 + "worklet";
8 + return 1;
9 + };
10 + return update;
11 +}
12 +
13 +export const FIXTURE_ENTRYPOINT = {
14 + fn: useFoo,
15 + params: [],
16 + isComponent: false,
17 +};
18 +
19 +```
20 +
21 +## Code
22 +
23 +```javascript
24 +import { unstable_useMemoCache as useMemoCache } from "react";
25 +function useFoo() {
26 + const $ = useMemoCache(1);
27 + let t0;
28 + if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
29 + t0 = () => {
30 + "worklet";
31 + return 1;
32 + };
33 + $[0] = t0;
34 + } else {
35 + t0 = $[0];
36 + }
37 + const update = t0;
38 + return update;
39 +}
40 +
41 +export const FIXTURE_ENTRYPOINT = {
42 + fn: useFoo,
43 + params: [],
44 + isComponent: false,
45 +};
46 +
47 +```
48 +
49 +### Eval output
50 +(kind: ok) "[[ function params=0 ]]"
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/arrow-function-one-line-directive.js new
+13
@@ -0,0 +1,13 @@
1 +function useFoo() {
2 + const update = () => {
3 + "worklet";
4 + return 1;
5 + };
6 + return update;
7 +}
8 +
9 +export const FIXTURE_ENTRYPOINT = {
10 + fn: useFoo,
11 + params: [],
12 + isComponent: false,
13 +};