diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-call-second-function-which-captures-maybe-mutable-value-dont-preserve-memoization.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-call-second-function-which-captures-maybe-mutable-value-dont-preserve-memoization.expect.md new file mode 100644 index 0000000000..f3bbcc346b --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-call-second-function-which-captures-maybe-mutable-value-dont-preserve-memoization.expect.md @@ -0,0 +1,84 @@ + +## Input + +```javascript +// @enablePreserveExistingMemoizationGuarantees:false +import { useCallback } from "react"; +import { + identity, + logValue, + makeObject_Primitives, + useHook, +} from "shared-runtime"; + +function Component(props) { + const object = makeObject_Primitives(); + + useHook(); + + const log = () => { + logValue(object); + }; + + const onClick = useCallback(() => { + log(); + }, [log]); + + identity(object); + + return
; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; + +``` + +## Code + +```javascript +// @enablePreserveExistingMemoizationGuarantees:false +import { useCallback, unstable_useMemoCache as useMemoCache } from "react"; +import { + identity, + logValue, + makeObject_Primitives, + useHook, +} from "shared-runtime"; + +function Component(props) { + const $ = useMemoCache(1); + const object = makeObject_Primitives(); + + useHook(); + + const log = () => { + logValue(object); + }; + + const onClick = () => { + log(); + }; + + identity(object); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = ; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; +} + +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-call-second-function-which-captures-maybe-mutable-value-dont-preserve-memoization.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-call-second-function-which-captures-maybe-mutable-value-dont-preserve-memoization.js new file mode 100644 index 0000000000..5f6716fb19 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-call-second-function-which-captures-maybe-mutable-value-dont-preserve-memoization.js @@ -0,0 +1,31 @@ +// @enablePreserveExistingMemoizationGuarantees:false +import { useCallback } from "react"; +import { + identity, + logValue, + makeObject_Primitives, + useHook, +} from "shared-runtime"; + +function Component(props) { + const object = makeObject_Primitives(); + + useHook(); + + const log = () => { + logValue(object); + }; + + const onClick = useCallback(() => { + log(); + }, [log]); + + identity(object); + + return ; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-call-second-function-which-captures-maybe-mutable-value-preserve-memoization.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-call-second-function-which-captures-maybe-mutable-value-preserve-memoization.expect.md new file mode 100644 index 0000000000..874a4120eb --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-call-second-function-which-captures-maybe-mutable-value-preserve-memoization.expect.md @@ -0,0 +1,84 @@ + +## Input + +```javascript +// @enablePreserveExistingMemoizationGuarantees +import { useCallback } from "react"; +import { + identity, + logValue, + makeObject_Primitives, + useHook, +} from "shared-runtime"; + +function Component(props) { + const object = makeObject_Primitives(); + + useHook(); + + const log = () => { + logValue(object); + }; + + const onClick = useCallback(() => { + log(); + }, [log]); + + identity(object); + + return ; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; + +``` + +## Code + +```javascript +// @enablePreserveExistingMemoizationGuarantees +import { useCallback, unstable_useMemoCache as useMemoCache } from "react"; +import { + identity, + logValue, + makeObject_Primitives, + useHook, +} from "shared-runtime"; + +function Component(props) { + const $ = useMemoCache(1); + const object = makeObject_Primitives(); + + useHook(); + + const log = () => { + logValue(object); + }; + + const onClick = () => { + log(); + }; + + identity(object); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = ; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; +} + +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-call-second-function-which-captures-maybe-mutable-value-preserve-memoization.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-call-second-function-which-captures-maybe-mutable-value-preserve-memoization.js new file mode 100644 index 0000000000..19f5858623 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-call-second-function-which-captures-maybe-mutable-value-preserve-memoization.js @@ -0,0 +1,31 @@ +// @enablePreserveExistingMemoizationGuarantees +import { useCallback } from "react"; +import { + identity, + logValue, + makeObject_Primitives, + useHook, +} from "shared-runtime"; + +function Component(props) { + const object = makeObject_Primitives(); + + useHook(); + + const log = () => { + logValue(object); + }; + + const onClick = useCallback(() => { + log(); + }, [log]); + + identity(object); + + return ; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-value-dont-preserve-memoization.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-value-dont-preserve-memoization.expect.md new file mode 100644 index 0000000000..d205081829 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-value-dont-preserve-memoization.expect.md @@ -0,0 +1,69 @@ + +## Input + +```javascript +// @enablePreserveExistingMemoizationGuarantees +import { useCallback, useRef } from "react"; + +function Component(props) { + const ref = useRef(null); + + const onChange = useCallback((event) => { + // The ref should still be mutable here even though function deps are frozen in + // @enablePreserveExistingMemoizationGuarantees mode + ref.current = 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(3); + const ref = useRef(null); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = (event) => { + ref.current = event.target.value; + }; + $[0] = t0; + } else { + t0 = $[0]; + } + const onChange = t0; + let t1; + if ($[1] !== onChange) { + t1 = ; + $[1] = onChange; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; +} + +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-set-ref-value-dont-preserve-memoization.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-value-dont-preserve-memoization.js new file mode 100644 index 0000000000..f9e5c9b171 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-value-dont-preserve-memoization.js @@ -0,0 +1,19 @@ +// @enablePreserveExistingMemoizationGuarantees +import { useCallback, useRef } from "react"; + +function Component(props) { + const ref = useRef(null); + + const onChange = useCallback((event) => { + // The ref should still be mutable here even though function deps are frozen in + // @enablePreserveExistingMemoizationGuarantees mode + ref.current = event.target.value; + }); + + return ; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-value-preserve-memoization.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-value-preserve-memoization.expect.md new file mode 100644 index 0000000000..d205081829 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-value-preserve-memoization.expect.md @@ -0,0 +1,69 @@ + +## Input + +```javascript +// @enablePreserveExistingMemoizationGuarantees +import { useCallback, useRef } from "react"; + +function Component(props) { + const ref = useRef(null); + + const onChange = useCallback((event) => { + // The ref should still be mutable here even though function deps are frozen in + // @enablePreserveExistingMemoizationGuarantees mode + ref.current = 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(3); + const ref = useRef(null); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = (event) => { + ref.current = event.target.value; + }; + $[0] = t0; + } else { + t0 = $[0]; + } + const onChange = t0; + let t1; + if ($[1] !== onChange) { + t1 = ; + $[1] = onChange; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; +} + +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-set-ref-value-preserve-memoization.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-value-preserve-memoization.js new file mode 100644 index 0000000000..f9e5c9b171 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-value-preserve-memoization.js @@ -0,0 +1,19 @@ +// @enablePreserveExistingMemoizationGuarantees +import { useCallback, useRef } from "react"; + +function Component(props) { + const ref = useRef(null); + + const onChange = useCallback((event) => { + // The ref should still be mutable here even though function deps are frozen in + // @enablePreserveExistingMemoizationGuarantees mode + ref.current = event.target.value; + }); + + return ; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; diff --git a/compiler/packages/sprout/src/shared-runtime.ts b/compiler/packages/sprout/src/shared-runtime.ts index 8f1133713f..9ccba51bbb 100644 --- a/compiler/packages/sprout/src/shared-runtime.ts +++ b/compiler/packages/sprout/src/shared-runtime.ts @@ -153,6 +153,10 @@ export function throwInput(x: Object): never { throw x; } +export function logValue