@samitouri / QOS-React / commits / a2dd376820

Drop useMemo/useCallback when called via React namespace

Teaches `DropUseMemo` (which also handles useCallback) to also transform the methodcall case.

Joe Savona committed Oct 3, 2023 at 08:47 UTC a2dd376820f01c3fd10a24ac694d19bb7eaaac62
6 files changed +153 -20
compiler/packages/babel-plugin-react-forget/src/Inference/DropMemoCalls.ts
+6 -1
@@ -11,8 +11,12 @@ export default function (func: HIRFunction): void {
11 for (const [_, block] of func.body.blocks) {
12 for (const instr of block.instructions) {
13 switch (instr.value.kind) {
14 + case "MethodCall":
15 case "CallExpression": {
15 - const hookKind = getHookKind(func.env, instr.value.callee.identifier);
16 + const hookKind =
17 + instr.value.kind === "CallExpression"
18 + ? getHookKind(func.env, instr.value.callee.identifier)
19 + : getHookKind(func.env, instr.value.property.identifier);
20 if (hookKind != null) {
21 if (hookKind === "useMemo") {
22 const [fn] = instr.value.args;
@@ -61,6 +65,7 @@ export default function (func: HIRFunction): void {
65 }
66 }
67 }
68 + break;
69 }
70 }
71 }
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/babel-existing-react-namespace-import.expect.md
+6 -19
@@ -27,32 +27,19 @@ import * as React from "react";
27 import { calculateExpensiveNumber } from "shared-runtime";
28
29 function Component(props) {
30 - const $ = useMemoCache(5);
30 + const $ = useMemoCache(2);
31 const [x] = React.useState(0);
32 - const c_0 = $[0] !== x;
32 + const expensiveNumber = (() => calculateExpensiveNumber(x))();
33 + const c_0 = $[0] !== expensiveNumber;
34 let t0;
34 - let t1;
35 if (c_0) {
36 - t0 = () => calculateExpensiveNumber(x);
37 - t1 = [x];
38 - $[0] = x;
36 + t0 = <div>{expensiveNumber}</div>;
37 + $[0] = expensiveNumber;
38 $[1] = t0;
40 - $[2] = t1;
39 } else {
40 t0 = $[1];
43 - t1 = $[2];
41 }
45 - const expensiveNumber = React.useMemo(t0, t1);
46 - const c_3 = $[3] !== expensiveNumber;
47 - let t2;
48 - if (c_3) {
49 - t2 = <div>{expensiveNumber}</div>;
50 - $[3] = expensiveNumber;
51 - $[4] = t2;
52 - } else {
53 - t2 = $[4];
54 - }
55 - return t2;
42 + return t0;
43 }
44
45 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/drop-methodcall-usecallback.expect.md new
+59
@@ -0,0 +1,59 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +import * as React from "react";
6 +
7 +function Component(props) {
8 + const onClick = React.useCallback(() => {
9 + console.log(props.value);
10 + }, [props.value]);
11 + return <div onClick={onClick} />;
12 +}
13 +
14 +export const FIXTURE_ENTRYPOINT = {
15 + fn: Component,
16 + params: [{ value: 42 }],
17 +};
18 +
19 +```
20 +
21 +## Code
22 +
23 +```javascript
24 +import { unstable_useMemoCache as useMemoCache } from "react";
25 +import * as React from "react";
26 +
27 +function Component(props) {
28 + const $ = useMemoCache(4);
29 + const c_0 = $[0] !== props.value;
30 + let t0;
31 + if (c_0) {
32 + t0 = () => {
33 + console.log(props.value);
34 + };
35 + $[0] = props.value;
36 + $[1] = t0;
37 + } else {
38 + t0 = $[1];
39 + }
40 + const onClick = t0;
41 + const c_2 = $[2] !== onClick;
42 + let t1;
43 + if (c_2) {
44 + t1 = <div onClick={onClick} />;
45 + $[2] = onClick;
46 + $[3] = t1;
47 + } else {
48 + t1 = $[3];
49 + }
50 + return t1;
51 +}
52 +
53 +export const FIXTURE_ENTRYPOINT = {
54 + fn: Component,
55 + params: [{ value: 42 }],
56 +};
57 +
58 +```
59 +
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/drop-methodcall-usecallback.js new
+13
@@ -0,0 +1,13 @@
1 +import * as React from "react";
2 +
3 +function Component(props) {
4 + const onClick = React.useCallback(() => {
5 + console.log(props.value);
6 + }, [props.value]);
7 + return <div onClick={onClick} />;
8 +}
9 +
10 +export const FIXTURE_ENTRYPOINT = {
11 + fn: Component,
12 + params: [{ value: 42 }],
13 +};
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/drop-methodcall-usememo.expect.md new
+54
@@ -0,0 +1,54 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +import * as React from "react";
6 +
7 +function Component(props) {
8 + const x = React.useMemo(() => {
9 + const x = [];
10 + x.push(props.value);
11 + return x;
12 + }, [props.value]);
13 + return x;
14 +}
15 +
16 +export const FIXTURE_ENTRYPOINT = {
17 + fn: Component,
18 + params: [{ value: 42 }],
19 +};
20 +
21 +```
22 +
23 +## Code
24 +
25 +```javascript
26 +import { unstable_useMemoCache as useMemoCache } from "react";
27 +import * as React from "react";
28 +
29 +function Component(props) {
30 + const $ = useMemoCache(2);
31 + const c_0 = $[0] !== props.value;
32 + let t0;
33 + if (c_0) {
34 + t0 = (() => {
35 + const x = [];
36 + x.push(props.value);
37 + return x;
38 + })();
39 + $[0] = props.value;
40 + $[1] = t0;
41 + } else {
42 + t0 = $[1];
43 + }
44 + const x_0 = t0;
45 + return x_0;
46 +}
47 +
48 +export const FIXTURE_ENTRYPOINT = {
49 + fn: Component,
50 + params: [{ value: 42 }],
51 +};
52 +
53 +```
54 +
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/drop-methodcall-usememo.js new
+15
@@ -0,0 +1,15 @@
1 +import * as React from "react";
2 +
3 +function Component(props) {
4 + const x = React.useMemo(() => {
5 + const x = [];
6 + x.push(props.value);
7 + return x;
8 + }, [props.value]);
9 + return x;
10 +}
11 +
12 +export const FIXTURE_ENTRYPOINT = {
13 + fn: Component,
14 + params: [{ value: 42 }],
15 +};