From a2dd376820f01c3fd10a24ac694d19bb7eaaac62 Mon Sep 17 00:00:00 2001 From: Joe Savona Date: Tue, 3 Oct 2023 08:47:07 -0700 Subject: [PATCH] Drop useMemo/useCallback when called via React namespace Teaches `DropUseMemo` (which also handles useCallback) to also transform the methodcall case. --- .../src/Inference/DropMemoCalls.ts | 7 ++- ...-existing-react-namespace-import.expect.md | 25 ++------ .../drop-methodcall-usecallback.expect.md | 59 +++++++++++++++++++ .../compiler/drop-methodcall-usecallback.js | 13 ++++ .../drop-methodcall-usememo.expect.md | 54 +++++++++++++++++ .../compiler/drop-methodcall-usememo.js | 15 +++++ 6 files changed, 153 insertions(+), 20 deletions(-) create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/drop-methodcall-usecallback.expect.md create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/drop-methodcall-usecallback.js create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/drop-methodcall-usememo.expect.md create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/drop-methodcall-usememo.js diff --git a/compiler/packages/babel-plugin-react-forget/src/Inference/DropMemoCalls.ts b/compiler/packages/babel-plugin-react-forget/src/Inference/DropMemoCalls.ts index 6267b7c385..08f35c91b3 100644 --- a/compiler/packages/babel-plugin-react-forget/src/Inference/DropMemoCalls.ts +++ b/compiler/packages/babel-plugin-react-forget/src/Inference/DropMemoCalls.ts @@ -11,8 +11,12 @@ export default function (func: HIRFunction): void { for (const [_, block] of func.body.blocks) { for (const instr of block.instructions) { switch (instr.value.kind) { + case "MethodCall": case "CallExpression": { - const hookKind = getHookKind(func.env, instr.value.callee.identifier); + const hookKind = + instr.value.kind === "CallExpression" + ? getHookKind(func.env, instr.value.callee.identifier) + : getHookKind(func.env, instr.value.property.identifier); if (hookKind != null) { if (hookKind === "useMemo") { const [fn] = instr.value.args; @@ -61,6 +65,7 @@ export default function (func: HIRFunction): void { } } } + break; } } } diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/babel-existing-react-namespace-import.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/babel-existing-react-namespace-import.expect.md index 4f53132de5..1cec876bc6 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/babel-existing-react-namespace-import.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/babel-existing-react-namespace-import.expect.md @@ -27,32 +27,19 @@ import * as React from "react"; import { calculateExpensiveNumber } from "shared-runtime"; function Component(props) { - const $ = useMemoCache(5); + const $ = useMemoCache(2); const [x] = React.useState(0); - const c_0 = $[0] !== x; + const expensiveNumber = (() => calculateExpensiveNumber(x))(); + const c_0 = $[0] !== expensiveNumber; let t0; - let t1; if (c_0) { - t0 = () => calculateExpensiveNumber(x); - t1 = [x]; - $[0] = x; + t0 =
{expensiveNumber}
; + $[0] = expensiveNumber; $[1] = t0; - $[2] = t1; } else { t0 = $[1]; - t1 = $[2]; } - const expensiveNumber = React.useMemo(t0, t1); - const c_3 = $[3] !== expensiveNumber; - let t2; - if (c_3) { - t2 =
{expensiveNumber}
; - $[3] = expensiveNumber; - $[4] = t2; - } else { - t2 = $[4]; - } - return t2; + return t0; } export const FIXTURE_ENTRYPOINT = { diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/drop-methodcall-usecallback.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/drop-methodcall-usecallback.expect.md new file mode 100644 index 0000000000..e0552b2d8a --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/drop-methodcall-usecallback.expect.md @@ -0,0 +1,59 @@ + +## Input + +```javascript +import * as React from "react"; + +function Component(props) { + const onClick = React.useCallback(() => { + console.log(props.value); + }, [props.value]); + return
; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], +}; + +``` + +## Code + +```javascript +import { unstable_useMemoCache as useMemoCache } from "react"; +import * as React from "react"; + +function Component(props) { + const $ = useMemoCache(4); + const c_0 = $[0] !== props.value; + let t0; + if (c_0) { + t0 = () => { + console.log(props.value); + }; + $[0] = props.value; + $[1] = t0; + } else { + t0 = $[1]; + } + const onClick = t0; + const c_2 = $[2] !== onClick; + let t1; + if (c_2) { + t1 =
; + $[2] = onClick; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], +}; + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/drop-methodcall-usecallback.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/drop-methodcall-usecallback.js new file mode 100644 index 0000000000..1f32668c86 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/drop-methodcall-usecallback.js @@ -0,0 +1,13 @@ +import * as React from "react"; + +function Component(props) { + const onClick = React.useCallback(() => { + console.log(props.value); + }, [props.value]); + return
; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], +}; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/drop-methodcall-usememo.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/drop-methodcall-usememo.expect.md new file mode 100644 index 0000000000..84e25bb733 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/drop-methodcall-usememo.expect.md @@ -0,0 +1,54 @@ + +## Input + +```javascript +import * as React from "react"; + +function Component(props) { + const x = React.useMemo(() => { + const x = []; + x.push(props.value); + return x; + }, [props.value]); + return x; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], +}; + +``` + +## Code + +```javascript +import { unstable_useMemoCache as useMemoCache } from "react"; +import * as React from "react"; + +function Component(props) { + const $ = useMemoCache(2); + const c_0 = $[0] !== props.value; + let t0; + if (c_0) { + t0 = (() => { + const x = []; + x.push(props.value); + return x; + })(); + $[0] = props.value; + $[1] = t0; + } else { + t0 = $[1]; + } + const x_0 = t0; + return x_0; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], +}; + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/drop-methodcall-usememo.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/drop-methodcall-usememo.js new file mode 100644 index 0000000000..b2b1065288 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/drop-methodcall-usememo.js @@ -0,0 +1,15 @@ +import * as React from "react"; + +function Component(props) { + const x = React.useMemo(() => { + const x = []; + x.push(props.value); + return x; + }, [props.value]); + return x; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], +};