[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
+};