From 3e79c386048c4fe569afb023d85b71ed2ffe5b8e Mon Sep 17 00:00:00 2001 From: Joe Savona Date: Fri, 15 Dec 2023 16:59:19 -0800 Subject: [PATCH] More useCallback with ref fixtures --- ...ia-function-preserve-memoization.expect.md | 42 +++++++++ ...later-via-function-preserve-memoization.js | 25 +++++ ...fied-later-preserve-memoization.expect.md} | 1 + ...ref-modified-later-preserve-memoization.js | 22 +++++ ...ng-same-ref-preserve-memoization.expect.md | 91 +++++++++++++++++++ ...modifying-same-ref-preserve-memoization.js | 23 +++++ ...operty-dont-preserve-memoization.expect.md | 4 +- ...ed-property-preserve-memoization.expect.md | 76 ++++++++++++++++ ...f-nested-property-preserve-memoization.js} | 2 - 9 files changed, 283 insertions(+), 3 deletions(-) create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-accesses-ref-mutated-later-via-function-preserve-memoization.expect.md create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-accesses-ref-mutated-later-via-function-preserve-memoization.js rename compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/{error.todo-useCallback-set-ref-nested-property-preserve-memoization.expect.md => error.todo-useCallback-set-ref-nested-property-ref-modified-later-preserve-memoization.expect.md} (90%) create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-set-ref-nested-property-ref-modified-later-preserve-memoization.js create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-multiple-callbacks-modifying-same-ref-preserve-memoization.expect.md create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-multiple-callbacks-modifying-same-ref-preserve-memoization.js create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-nested-property-preserve-memoization.expect.md rename compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/{error.todo-useCallback-set-ref-nested-property-preserve-memoization.js => useCallback-set-ref-nested-property-preserve-memoization.js} (94%) diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-accesses-ref-mutated-later-via-function-preserve-memoization.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-accesses-ref-mutated-later-via-function-preserve-memoization.expect.md new file mode 100644 index 0000000000..eb8ace2ed3 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-accesses-ref-mutated-later-via-function-preserve-memoization.expect.md @@ -0,0 +1,42 @@ + +## Input + +```javascript +// @enablePreserveExistingMemoizationGuarantees +import { useCallback, useRef } from "react"; + +function Component(props) { + const ref = useRef({ inner: null }); + + const onChange = useCallback((event) => { + // The ref should still be mutable here even though function deps are frozen in + // @enablePreserveExistingMemoizationGuarantees mode + ref.current.inner = event.target.value; + }); + + // The ref is modified later, extending its range and preventing memoization of onChange + const reset = () => { + ref.current.inner = null; + }; + reset(); + + return ; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; + +``` + + +## Error + +``` +[ReactForget] InvalidReact: This value was manually memoized, but cannot be memoized under Forget because it may be mutated after it is memoized (7:11) + +[ReactForget] InvalidReact: This value was manually memoized, but cannot be memoized under Forget because it may be mutated after it is memoized (7:11) +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-accesses-ref-mutated-later-via-function-preserve-memoization.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-accesses-ref-mutated-later-via-function-preserve-memoization.js new file mode 100644 index 0000000000..b96e65780b --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-accesses-ref-mutated-later-via-function-preserve-memoization.js @@ -0,0 +1,25 @@ +// @enablePreserveExistingMemoizationGuarantees +import { useCallback, useRef } from "react"; + +function Component(props) { + const ref = useRef({ inner: null }); + + const onChange = useCallback((event) => { + // The ref should still be mutable here even though function deps are frozen in + // @enablePreserveExistingMemoizationGuarantees mode + ref.current.inner = event.target.value; + }); + + // The ref is modified later, extending its range and preventing memoization of onChange + const reset = () => { + ref.current.inner = null; + }; + reset(); + + return ; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-set-ref-nested-property-preserve-memoization.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-set-ref-nested-property-ref-modified-later-preserve-memoization.expect.md similarity index 90% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-set-ref-nested-property-preserve-memoization.expect.md rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-set-ref-nested-property-ref-modified-later-preserve-memoization.expect.md index 6d811b9889..169870e86e 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-set-ref-nested-property-preserve-memoization.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-set-ref-nested-property-ref-modified-later-preserve-memoization.expect.md @@ -14,6 +14,7 @@ function Component(props) { ref.current.inner = event.target.value; }); + // The ref is modified later, extending its range and preventing memoization of onChange ref.current.inner = null; return ; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-set-ref-nested-property-ref-modified-later-preserve-memoization.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-set-ref-nested-property-ref-modified-later-preserve-memoization.js new file mode 100644 index 0000000000..349e8f40c7 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-set-ref-nested-property-ref-modified-later-preserve-memoization.js @@ -0,0 +1,22 @@ +// @enablePreserveExistingMemoizationGuarantees +import { useCallback, useRef } from "react"; + +function Component(props) { + const ref = useRef({ inner: null }); + + const onChange = useCallback((event) => { + // The ref should still be mutable here even though function deps are frozen in + // @enablePreserveExistingMemoizationGuarantees mode + ref.current.inner = event.target.value; + }); + + // The ref is modified later, extending its range and preventing memoization of onChange + ref.current.inner = null; + + return ; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-multiple-callbacks-modifying-same-ref-preserve-memoization.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-multiple-callbacks-modifying-same-ref-preserve-memoization.expect.md new file mode 100644 index 0000000000..d770acd5f8 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-multiple-callbacks-modifying-same-ref-preserve-memoization.expect.md @@ -0,0 +1,91 @@ + +## Input + +```javascript +// @enablePreserveExistingMemoizationGuarantees +import { useCallback, useRef } from "react"; + +function Component(props) { + const ref = useRef({ inner: null }); + + const onChange = useCallback((event) => { + // The ref should still be mutable here even though function deps are frozen in + // @enablePreserveExistingMemoizationGuarantees mode + ref.current.inner = event.target.value; + }); + + const onReset = useCallback(() => { + ref.current.inner = null; + }); + + return ; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; + +``` + +## Code + +```javascript +// @enablePreserveExistingMemoizationGuarantees +import { + useCallback, + useRef, + unstable_useMemoCache as useMemoCache, +} from "react"; + +function Component(props) { + const $ = useMemoCache(6); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = { inner: null }; + $[0] = t0; + } else { + t0 = $[0]; + } + const ref = useRef(t0); + let t1; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + t1 = (event) => { + ref.current.inner = event.target.value; + }; + $[1] = t1; + } else { + t1 = $[1]; + } + const onChange = t1; + let t2; + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { + t2 = () => { + ref.current.inner = null; + }; + $[2] = t2; + } else { + t2 = $[2]; + } + const onReset = t2; + let t3; + if ($[3] !== onChange || $[4] !== onReset) { + t3 = ; + $[3] = onChange; + $[4] = onReset; + $[5] = t3; + } else { + t3 = $[5]; + } + return t3; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; + +``` + +### Eval output +(kind: ok) \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-multiple-callbacks-modifying-same-ref-preserve-memoization.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-multiple-callbacks-modifying-same-ref-preserve-memoization.js new file mode 100644 index 0000000000..9031ae221a --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-multiple-callbacks-modifying-same-ref-preserve-memoization.js @@ -0,0 +1,23 @@ +// @enablePreserveExistingMemoizationGuarantees +import { useCallback, useRef } from "react"; + +function Component(props) { + const ref = useRef({ inner: null }); + + const onChange = useCallback((event) => { + // The ref should still be mutable here even though function deps are frozen in + // @enablePreserveExistingMemoizationGuarantees mode + ref.current.inner = event.target.value; + }); + + const onReset = useCallback(() => { + ref.current.inner = null; + }); + + return ; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-nested-property-dont-preserve-memoization.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-nested-property-dont-preserve-memoization.expect.md index 28a9e95668..3273c08df9 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-nested-property-dont-preserve-memoization.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-nested-property-dont-preserve-memoization.expect.md @@ -62,4 +62,6 @@ export const FIXTURE_ENTRYPOINT = { }; ``` - \ No newline at end of file + +### Eval output +(kind: ok) \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-nested-property-preserve-memoization.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-nested-property-preserve-memoization.expect.md new file mode 100644 index 0000000000..14a7cc3ba3 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-nested-property-preserve-memoization.expect.md @@ -0,0 +1,76 @@ + +## Input + +```javascript +// @enablePreserveExistingMemoizationGuarantees +import { useCallback, useRef } from "react"; + +function Component(props) { + const ref = useRef({ inner: null }); + + const onChange = useCallback((event) => { + // The ref should still be mutable here even though function deps are frozen in + // @enablePreserveExistingMemoizationGuarantees mode + ref.current.inner = event.target.value; + }); + + return ; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; + +``` + +## Code + +```javascript +// @enablePreserveExistingMemoizationGuarantees +import { + useCallback, + useRef, + unstable_useMemoCache as useMemoCache, +} from "react"; + +function Component(props) { + const $ = useMemoCache(4); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = { inner: null }; + $[0] = t0; + } else { + t0 = $[0]; + } + const ref = useRef(t0); + let t1; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + t1 = (event) => { + ref.current.inner = event.target.value; + }; + $[1] = t1; + } else { + t1 = $[1]; + } + const onChange = t1; + let t2; + if ($[2] !== onChange) { + t2 = ; + $[2] = onChange; + $[3] = t2; + } else { + t2 = $[3]; + } + return t2; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; + +``` + +### Eval output +(kind: ok) \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-set-ref-nested-property-preserve-memoization.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-nested-property-preserve-memoization.js similarity index 94% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-set-ref-nested-property-preserve-memoization.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-nested-property-preserve-memoization.js index 2bbf682733..8ee70dc4de 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-set-ref-nested-property-preserve-memoization.js +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-nested-property-preserve-memoization.js @@ -10,8 +10,6 @@ function Component(props) { ref.current.inner = event.target.value; }); - ref.current.inner = null; - return ; }