From d39a1d6b638de6b990ea783544df775b8be59f1a Mon Sep 17 00:00:00 2001 From: Joseph Savona <6425824+josephsavona@users.noreply.github.com> Date: Tue, 25 Nov 2025 12:06:25 -0800 Subject: [PATCH 1/4] [compiler] Distingush optional/extraneous deps (#35204) In ValidateExhaustiveDependencies, I previously changed to allow extraneous dependencies as long as they were non-reactive. Here we make that more precise, and distinguish between values that are definitely referenced in the memo function but optional as dependencies vs values that are not even referenced in the memo function. The latter now error as extraneous even if they're non-reactive. This also turned up a case where constant-folded primitives could show up as false positives of the latter category, so now we track manual deps which quality for constant folding and don't error on them. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/35204). * #35213 * #35201 * __->__ #35204 --- .../src/HIR/HIR.ts | 1 + .../src/Inference/DropManualMemoization.ts | 1 + .../src/Optimization/ConstantPropagation.ts | 13 ++++ .../ValidateExhaustiveDependencies.ts | 66 ++++++++++--------- .../ValidatePreservedManualMemoization.ts | 3 + ...text-variable-as-jsx-element-tag.expect.md | 3 +- .../context-variable-as-jsx-element-tag.js | 2 +- ...eps-disallow-unused-stable-types.expect.md | 42 ++++++++++++ ...stive-deps-disallow-unused-stable-types.js | 14 ++++ ...eps-allow-constant-folded-values.expect.md | 41 ++++++++++++ ...stive-deps-allow-constant-folded-values.js | 11 ++++ ...-constant-prop-decls-get-removed.expect.md | 4 +- ...-ensure-constant-prop-decls-get-removed.ts | 2 +- ...e-preserve-memoization-guarantee.expect.md | 2 +- ...variable-preserve-memoization-guarantee.js | 2 +- 15 files changed, 169 insertions(+), 38 deletions(-) create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-exhaustive-deps-disallow-unused-stable-types.expect.md create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-exhaustive-deps-disallow-unused-stable-types.js create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps-allow-constant-folded-values.expect.md create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps-allow-constant-folded-values.js diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts index 55bcd0bc5ce..9fb360cf8a5 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts @@ -803,6 +803,7 @@ export type ManualMemoDependency = { | { kind: 'NamedLocal'; value: Place; + constant: boolean; } | {kind: 'Global'; identifierName: string}; path: DependencyPath; diff --git a/compiler/packages/babel-plugin-react-compiler/src/Inference/DropManualMemoization.ts b/compiler/packages/babel-plugin-react-compiler/src/Inference/DropManualMemoization.ts index bcfc53413ab..0138e52ef60 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Inference/DropManualMemoization.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Inference/DropManualMemoization.ts @@ -92,6 +92,7 @@ export function collectMaybeMemoDependencies( root: { kind: 'NamedLocal', value: {...value.place}, + constant: false, }, path: [], }; diff --git a/compiler/packages/babel-plugin-react-compiler/src/Optimization/ConstantPropagation.ts b/compiler/packages/babel-plugin-react-compiler/src/Optimization/ConstantPropagation.ts index ca2f6e00a5d..7330b63ddce 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Optimization/ConstantPropagation.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Optimization/ConstantPropagation.ts @@ -609,6 +609,19 @@ function evaluateInstruction( constantPropagationImpl(value.loweredFunc.func, constants); return null; } + case 'StartMemoize': { + if (value.deps != null) { + for (const dep of value.deps) { + if (dep.root.kind === 'NamedLocal') { + const placeValue = read(constants, dep.root.value); + if (placeValue != null && placeValue.kind === 'Primitive') { + dep.root.constant = true; + } + } + } + } + return null; + } default: { // TODO: handle more cases return null; diff --git a/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateExhaustiveDependencies.ts b/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateExhaustiveDependencies.ts index b3a68fc0134..5035fa9260f 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateExhaustiveDependencies.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateExhaustiveDependencies.ts @@ -22,6 +22,7 @@ import { Identifier, IdentifierId, InstructionKind, + isPrimitiveType, isStableType, isSubPath, isSubPathIgnoringOptionals, @@ -53,20 +54,18 @@ const DEBUG = false; * - If the manual dependencies had extraneous deps, then auto memoization * will remove them and cause the value to update *less* frequently. * - * We consider a value V as missing if ALL of the following conditions are met: - * - V is reactive - * - There is no manual dependency path P such that whenever V would change, - * P would also change. If V is `x.y.z`, this means there must be some - * path P that is either `x.y.z`, `x.y`, or `x`. Note that we assume no - * interior mutability, such that a shorter path "covers" changes to longer - * more precise paths. - * - * We consider a value V extraneous if either of the folowing are true: - * - V is a reactive local that is unreferenced - * - V is a global that is unreferenced - * - * In other words, we allow extraneous non-reactive values since we know they cannot - * impact how often the memoization would run. + * The implementation compares the manual dependencies against the values + * actually used within the memoization function + * - For each value V referenced in the memo function, either: + * - If the value is non-reactive *and* a known stable type, then the + * value may optionally be specified as an exact dependency. + * - Otherwise, report an error unless there is a manual dependency that will + * invalidate whenever V invalidates. If `x.y.z` is referenced, there must + * be a manual dependency for `x.y.z`, `x.y`, or `x`. Note that we assume + * no interior mutability, ie we assume that any changes to inner paths must + * always cause the other path to change as well. + * - Any dependencies that do not correspond to a value referenced in the memo + * function are considered extraneous and throw an error * * ## TODO: Invalid, Complex Deps * @@ -226,9 +225,6 @@ export function validateExhaustiveDependencies( reason: 'Unexpected function dependency', loc: value.loc, }); - const isRequiredDependency = reactive.has( - inferredDependency.identifier.id, - ); let hasMatchingManualDependency = false; for (const manualDependency of manualDependencies) { if ( @@ -243,32 +239,40 @@ export function validateExhaustiveDependencies( ) { hasMatchingManualDependency = true; matched.add(manualDependency); - if (!isRequiredDependency) { - extra.push(manualDependency); - } } } - if (isRequiredDependency && !hasMatchingManualDependency) { - missing.push(inferredDependency); + const isOptionalDependency = + !reactive.has(inferredDependency.identifier.id) && + (isStableType(inferredDependency.identifier) || + isPrimitiveType(inferredDependency.identifier)); + if (hasMatchingManualDependency || isOptionalDependency) { + continue; } + missing.push(inferredDependency); } for (const dep of startMemo.deps ?? []) { if (matched.has(dep)) { continue; } + if (dep.root.kind === 'NamedLocal' && dep.root.constant) { + CompilerError.simpleInvariant( + !dep.root.value.reactive && + isPrimitiveType(dep.root.value.identifier), + { + reason: 'Expected constant-folded dependency to be non-reactive', + loc: dep.root.value.loc, + }, + ); + /* + * Constant primitives can get constant-folded, which means we won't + * see a LoadLocal for the value within the memo function. + */ + continue; + } extra.push(dep); } - /** - * Per docblock, we only consider dependencies as extraneous if - * they are unused globals or reactive locals. Notably, this allows - * non-reactive locals. - */ - retainWhere(extra, dep => { - return dep.root.kind === 'Global' || dep.root.value.reactive; - }); - if (missing.length !== 0 || extra.length !== 0) { let suggestions: Array | null = null; if (startMemo.depsLoc != null && typeof startMemo.depsLoc !== 'symbol') { diff --git a/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidatePreservedManualMemoization.ts b/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidatePreservedManualMemoization.ts index 19af0ed0801..48cec3cb122 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidatePreservedManualMemoization.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidatePreservedManualMemoization.ts @@ -267,6 +267,7 @@ function validateInferredDep( effect: Effect.Read, reactive: false, }, + constant: false, }, path: [...dep.path], }; @@ -379,6 +380,7 @@ class Visitor extends ReactiveFunctionVisitor { root: { kind: 'NamedLocal', value: storeTarget, + constant: false, }, path: [], }); @@ -408,6 +410,7 @@ class Visitor extends ReactiveFunctionVisitor { root: { kind: 'NamedLocal', value: {...lvalue}, + constant: false, }, path: [], }); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/context-variable-as-jsx-element-tag.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/context-variable-as-jsx-element-tag.expect.md index 407fdcb0488..636bc53a172 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/context-variable-as-jsx-element-tag.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/context-variable-as-jsx-element-tag.expect.md @@ -11,7 +11,7 @@ function Component(props) { Component = useMemo(() => { return Component; - }); + }, [Component]); return ; } @@ -36,6 +36,7 @@ function Component(props) { if ($[0] === Symbol.for("react.memo_cache_sentinel")) { Component = Stringify; + Component; Component = Component; $[0] = Component; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/context-variable-as-jsx-element-tag.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/context-variable-as-jsx-element-tag.js index 5ed1a9157bd..49cf3364b1c 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/context-variable-as-jsx-element-tag.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/context-variable-as-jsx-element-tag.js @@ -7,7 +7,7 @@ function Component(props) { Component = useMemo(() => { return Component; - }); + }, [Component]); return ; } diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-exhaustive-deps-disallow-unused-stable-types.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-exhaustive-deps-disallow-unused-stable-types.expect.md new file mode 100644 index 00000000000..b6d8a467426 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-exhaustive-deps-disallow-unused-stable-types.expect.md @@ -0,0 +1,42 @@ + +## Input + +```javascript +// @validateExhaustiveMemoizationDependencies + +import {useState} from 'react'; +import {Stringify} from 'shared-runtime'; + +function Component() { + const [state, setState] = useState(0); + const x = useMemo(() => { + return [state]; + // error: `setState` is a stable type, but not actually referenced + }, [state, setState]); + + return 'oops'; +} + +``` + + +## Error + +``` +Found 1 error: + +Error: Found unnecessary memoization dependencies + +Unnecessary dependencies can cause a value to update more often than necessary, causing performance regressions and effects to fire more often than expected. + +error.invalid-exhaustive-deps-disallow-unused-stable-types.ts:11:5 + 9 | return [state]; + 10 | // error: `setState` is a stable type, but not actually referenced +> 11 | }, [state, setState]); + | ^^^^^^^^^^^^^^^^^ Unnecessary dependencies `setState` + 12 | + 13 | return 'oops'; + 14 | } +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-exhaustive-deps-disallow-unused-stable-types.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-exhaustive-deps-disallow-unused-stable-types.js new file mode 100644 index 00000000000..2bb03c36611 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-exhaustive-deps-disallow-unused-stable-types.js @@ -0,0 +1,14 @@ +// @validateExhaustiveMemoizationDependencies + +import {useState} from 'react'; +import {Stringify} from 'shared-runtime'; + +function Component() { + const [state, setState] = useState(0); + const x = useMemo(() => { + return [state]; + // error: `setState` is a stable type, but not actually referenced + }, [state, setState]); + + return 'oops'; +} diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps-allow-constant-folded-values.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps-allow-constant-folded-values.expect.md new file mode 100644 index 00000000000..bda2b035625 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps-allow-constant-folded-values.expect.md @@ -0,0 +1,41 @@ + +## Input + +```javascript +// @validateExhaustiveMemoizationDependencies + +function Component() { + const x = 0; + const y = useMemo(() => { + return [x]; + // x gets constant-folded but shouldn't count as extraneous, + // it was referenced in the memo block + }, [x]); + return y; +} + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; // @validateExhaustiveMemoizationDependencies + +function Component() { + const $ = _c(1); + const x = 0; + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = [0]; + $[0] = t0; + } else { + t0 = $[0]; + } + const y = t0; + return y; +} + +``` + +### Eval output +(kind: exception) Fixture not implemented \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps-allow-constant-folded-values.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps-allow-constant-folded-values.js new file mode 100644 index 00000000000..6ee141cb3ae --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps-allow-constant-folded-values.js @@ -0,0 +1,11 @@ +// @validateExhaustiveMemoizationDependencies + +function Component() { + const x = 0; + const y = useMemo(() => { + return [x]; + // x gets constant-folded but shouldn't count as extraneous, + // it was referenced in the memo block + }, [x]); + return y; +} diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/todo-ensure-constant-prop-decls-get-removed.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/todo-ensure-constant-prop-decls-get-removed.expect.md index cf36d6ed673..f23cf84e504 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/todo-ensure-constant-prop-decls-get-removed.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/todo-ensure-constant-prop-decls-get-removed.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; @@ -27,7 +27,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validatePreserveExistingMemoizationGuarantees +import { c as _c } from "react/compiler-runtime"; // @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import { useMemo } from "react"; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/todo-ensure-constant-prop-decls-get-removed.ts b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/todo-ensure-constant-prop-decls-get-removed.ts index b0c01395269..bfbc0ab5056 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/todo-ensure-constant-prop-decls-get-removed.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/todo-ensure-constant-prop-decls-get-removed.ts @@ -1,4 +1,4 @@ -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useCallback-maybe-modify-free-variable-preserve-memoization-guarantee.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useCallback-maybe-modify-free-variable-preserve-memoization-guarantee.expect.md index 43b3b599e19..16169a74d71 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useCallback-maybe-modify-free-variable-preserve-memoization-guarantee.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useCallback-maybe-modify-free-variable-preserve-memoization-guarantee.expect.md @@ -15,7 +15,7 @@ function Component(props) { const x = makeObject_Primitives(); x.value = props.value; mutate(x, free, part); - }, [props.value]); + }, [props.value, free, part]); mutate(free, part); return callback; } diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useCallback-maybe-modify-free-variable-preserve-memoization-guarantee.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useCallback-maybe-modify-free-variable-preserve-memoization-guarantee.js index 662162ed644..e9d11525e2c 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useCallback-maybe-modify-free-variable-preserve-memoization-guarantee.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useCallback-maybe-modify-free-variable-preserve-memoization-guarantee.js @@ -11,7 +11,7 @@ function Component(props) { const x = makeObject_Primitives(); x.value = props.value; mutate(x, free, part); - }, [props.value]); + }, [props.value, free, part]); mutate(free, part); return callback; } From ddff35441a63d573ef41fcedabc32105e0ac3122 Mon Sep 17 00:00:00 2001 From: Joseph Savona <6425824+josephsavona@users.noreply.github.com> Date: Tue, 25 Nov 2025 12:07:55 -0800 Subject: [PATCH 2/4] [compiler] Enable validateExhaustiveMemoizationDependencies by default (#35201) Enables `@validateExhaustiveMemoizationDependencies` feature flag by default, and disables it in select tests that failed due to the change. Some of our tests intentionally use incorrect memo dependencies in order to test edge cases. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/35201). * #35213 * __->__ #35201 --- .../src/HIR/Environment.ts | 2 +- ...ow-modify-global-in-callback-jsx.expect.md | 4 +-- .../allow-modify-global-in-callback-jsx.js | 2 +- ...ray-pattern-spread-creates-array.expect.md | 4 +-- .../array-pattern-spread-creates-array.js | 2 +- ...-scoping-switch-variable-scoping.expect.md | 3 ++- .../block-scoping-switch-variable-scoping.js | 1 + ...ut-on-suppression-of-custom-rule.expect.md | 4 +-- ...r.bailout-on-suppression-of-custom-rule.js | 2 +- ....invalid-sketchy-code-use-forget.expect.md | 26 ++++++++++--------- .../error.invalid-sketchy-code-use-forget.js | 1 + ...alid-unclosed-eslint-suppression.expect.md | 4 +-- ...ror.invalid-unclosed-eslint-suppression.js | 2 +- .../error.ref-like-name-not-Ref.expect.md | 2 +- .../compiler/error.ref-like-name-not-Ref.js | 2 +- .../error.ref-like-name-not-a-ref.expect.md | 2 +- .../compiler/error.ref-like-name-not-a-ref.js | 2 +- ...ror.sketchy-code-exhaustive-deps.expect.md | 25 ++++++++++-------- .../error.sketchy-code-exhaustive-deps.js | 5 +++- ...rror.sketchy-code-rules-of-hooks.expect.md | 12 +++++---- .../error.sketchy-code-rules-of-hooks.js | 1 + ...from-inferred-mutation-in-logger.expect.md | 2 +- ...zation-from-inferred-mutation-in-logger.js | 2 +- .../existing-variables-with-c-name.expect.md | 4 +-- .../existing-variables-with-c-name.js | 2 +- ...esh-refresh-on-const-changes-dev.expect.md | 8 +++--- ...st-refresh-refresh-on-const-changes-dev.js | 2 +- .../dynamic-gating-bailout-nopanic.expect.md | 6 ++--- .../gating/dynamic-gating-bailout-nopanic.js | 2 +- .../use-memo-returned.expect.md | 3 ++- .../assume-invoked/use-memo-returned.ts | 1 + .../invalid-useMemo-return-empty.expect.md | 8 +++--- .../compiler/invalid-useMemo-return-empty.js | 2 +- ...ugh-identity-function-expression.expect.md | 4 +-- ...te-through-identity-function-expression.js | 2 +- .../mutate-through-identity.expect.md | 4 +-- .../new-mutability/mutate-through-identity.js | 2 +- ...ure-from-prop-with-default-value.expect.md | 3 ++- ...estructure-from-prop-with-default-value.js | 1 + ...-control-flow-sensitive-mutation.expect.md | 4 +-- .../todo-control-flow-sensitive-mutation.tsx | 2 +- ...ity-add-captured-array-to-itself.expect.md | 4 +-- ...nsitivity-add-captured-array-to-itself.tsx | 2 +- ...tivity-capture-createfrom-lambda.expect.md | 4 +-- ...transitivity-capture-createfrom-lambda.tsx | 2 +- .../transitivity-capture-createfrom.expect.md | 4 +-- .../transitivity-capture-createfrom.tsx | 2 +- ...ansitivity-phi-assign-or-capture.expect.md | 4 +-- .../transitivity-phi-assign-or-capture.tsx | 2 +- ...k-reordering-deplist-controlflow.expect.md | 4 +-- ...allback-reordering-deplist-controlflow.tsx | 2 +- ...k-reordering-depslist-assignment.expect.md | 4 +-- ...allback-reordering-depslist-assignment.tsx | 2 +- ...o-reordering-depslist-assignment.expect.md | 4 +-- .../useMemo-reordering-depslist-assignment.ts | 2 +- ...ve-use-memo-ref-missing-reactive.expect.md | 2 +- ....preserve-use-memo-ref-missing-reactive.ts | 2 +- .../error.useCallback-aliased-var.expect.md | 2 +- .../error.useCallback-aliased-var.ts | 2 +- ...or.useCallback-property-call-dep.expect.md | 2 +- .../error.useCallback-property-call-dep.ts | 2 +- .../error.useMemo-aliased-var.expect.md | 2 +- .../error.useMemo-aliased-var.ts | 2 +- ...emo-property-call-chained-object.expect.md | 2 +- ...or.useMemo-property-call-chained-object.ts | 2 +- .../error.useMemo-property-call-dep.expect.md | 2 +- .../error.useMemo-property-call-dep.ts | 2 +- ...o-unrelated-mutation-in-depslist.expect.md | 16 +++++------- ...be-invalid-useMemo-read-maybeRef.expect.md | 4 +-- ...pro-maybe-invalid-useMemo-read-maybeRef.ts | 2 +- .../useCallback-infer-fewer-deps.expect.md | 4 +-- .../useCallback-infer-fewer-deps.ts | 2 +- .../useCallback-infer-scope-global.expect.md | 4 +-- .../useCallback-infer-scope-global.ts | 2 +- ...invoked-callback-escaping-return.expect.md | 4 +-- ...caping-invoked-callback-escaping-return.js | 2 +- ...k-reordering-deplist-controlflow.expect.md | 4 +-- ...allback-reordering-deplist-controlflow.tsx | 2 +- ...k-reordering-depslist-assignment.expect.md | 4 +-- ...allback-reordering-depslist-assignment.tsx | 2 +- .../useCallback-with-no-depslist.expect.md | 4 +-- .../useCallback-with-no-depslist.ts | 2 +- ...useMemo-dep-array-literal-access.expect.md | 4 +-- .../useMemo-dep-array-literal-access.ts | 2 +- .../useMemo-infer-fewer-deps.expect.md | 4 +-- .../useMemo-infer-fewer-deps.ts | 2 +- .../useMemo-infer-scope-global.expect.md | 4 +-- .../useMemo-infer-scope-global.ts | 2 +- ...o-reordering-depslist-assignment.expect.md | 4 +-- .../useMemo-reordering-depslist-assignment.ts | 2 +- ...-reordering-depslist-controlflow.expect.md | 4 +-- ...seMemo-reordering-depslist-controlflow.tsx | 2 +- .../useMemo-with-no-depslist.expect.md | 4 +-- .../useMemo-with-no-depslist.ts | 2 +- .../useMemo-multiple-if-else.expect.md | 4 +-- .../useMemo-multiple-if-else.js | 2 +- ...reactive-scope-with-early-return.expect.md | 4 +-- ...ons-in-reactive-scope-with-early-return.js | 2 +- .../fixtures/compiler/repro.expect.md | 4 +-- .../src/__tests__/fixtures/compiler/repro.js | 2 +- ...suppression-skips-all-components.expect.md | 4 +-- ...eslint-suppression-skips-all-components.js | 2 +- .../compiler/use-callback-simple.expect.md | 3 ++- .../fixtures/compiler/use-callback-simple.js | 1 + ...t-preserve-memoization-guarantee.expect.md | 4 +-- ...ble-dont-preserve-memoization-guarantee.js | 2 +- .../useMemo-if-else-multiple-return.expect.md | 3 ++- .../useMemo-if-else-multiple-return.js | 1 + ...seMemo-independently-memoizeable.expect.md | 3 ++- .../useMemo-independently-memoizeable.js | 1 + .../compiler/useMemo-inverted-if.expect.md | 2 ++ .../fixtures/compiler/useMemo-inverted-if.js | 1 + ...d-statement-unconditional-return.expect.md | 2 ++ ...-labeled-statement-unconditional-return.js | 1 + .../compiler/useMemo-logical.expect.md | 2 ++ .../fixtures/compiler/useMemo-logical.js | 1 + ...-preserve-memoization-guarantees.expect.md | 4 +-- ...le-dont-preserve-memoization-guarantees.js | 2 +- .../useMemo-multiple-if-else.expect.md | 3 ++- .../compiler/useMemo-multiple-if-else.js | 1 + .../compiler/useMemo-nested-ifs.expect.md | 2 ++ .../fixtures/compiler/useMemo-nested-ifs.js | 1 + .../useMemo-switch-no-fallthrough.expect.md | 2 ++ .../compiler/useMemo-switch-no-fallthrough.js | 1 + .../compiler/useMemo-switch-return.expect.md | 2 ++ .../compiler/useMemo-switch-return.js | 1 + .../compiler/useMemo-with-optional.expect.md | 4 +-- .../compiler/useMemo-with-optional.js | 2 +- 128 files changed, 224 insertions(+), 184 deletions(-) diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/Environment.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/Environment.ts index 92bfe913d7e..fc5ba403817 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/Environment.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/Environment.ts @@ -221,7 +221,7 @@ export const EnvironmentConfigSchema = z.object({ /** * Validate that dependencies supplied to manual memoization calls are exhaustive. */ - validateExhaustiveMemoizationDependencies: z.boolean().default(false), + validateExhaustiveMemoizationDependencies: z.boolean().default(true), /** * When this is true, rather than pruning existing manual memoization but ensuring or validating diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-modify-global-in-callback-jsx.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-modify-global-in-callback-jsx.expect.md index e9475a070b8..8a3d0fac963 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-modify-global-in-callback-jsx.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-modify-global-in-callback-jsx.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; const someGlobal = {value: 0}; @@ -33,7 +33,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false +import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import { useMemo } from "react"; const someGlobal = { value: 0 }; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-modify-global-in-callback-jsx.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-modify-global-in-callback-jsx.js index 5bdeeaee1a8..9f0653d9d38 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-modify-global-in-callback-jsx.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-modify-global-in-callback-jsx.js @@ -1,4 +1,4 @@ -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; const someGlobal = {value: 0}; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-pattern-spread-creates-array.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-pattern-spread-creates-array.expect.md index 9994a6536f4..c3bc1d16238 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-pattern-spread-creates-array.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-pattern-spread-creates-array.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; import {makeObject_Primitives, ValidateMemoization} from 'shared-runtime'; @@ -36,7 +36,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validatePreserveExistingMemoizationGuarantees +import { c as _c } from "react/compiler-runtime"; // @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import { useMemo } from "react"; import { makeObject_Primitives, ValidateMemoization } from "shared-runtime"; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-pattern-spread-creates-array.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-pattern-spread-creates-array.js index 888bdbcb8b9..686e8744077 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-pattern-spread-creates-array.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-pattern-spread-creates-array.js @@ -1,4 +1,4 @@ -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; import {makeObject_Primitives, ValidateMemoization} from 'shared-runtime'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/block-scoping-switch-variable-scoping.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/block-scoping-switch-variable-scoping.expect.md index ce8e7b42232..8c2b57cbad5 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/block-scoping-switch-variable-scoping.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/block-scoping-switch-variable-scoping.expect.md @@ -2,6 +2,7 @@ ## Input ```javascript +// @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; function Component(props) { @@ -30,7 +31,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; +import { c as _c } from "react/compiler-runtime"; // @validateExhaustiveMemoizationDependencies:false import { useMemo } from "react"; function Component(props) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/block-scoping-switch-variable-scoping.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/block-scoping-switch-variable-scoping.js index 6b005c0e046..9448a284dd6 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/block-scoping-switch-variable-scoping.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/block-scoping-switch-variable-scoping.js @@ -1,3 +1,4 @@ +// @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; function Component(props) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.bailout-on-suppression-of-custom-rule.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.bailout-on-suppression-of-custom-rule.expect.md index ed9f73a0163..df3524de027 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.bailout-on-suppression-of-custom-rule.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.bailout-on-suppression-of-custom-rule.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @eslintSuppressionRules:["my-app","react-rule"] +// @eslintSuppressionRules:["my-app","react-rule"] @validateExhaustiveMemoizationDependencies:false /* eslint-disable my-app/react-rule */ function lowercasecomponent() { @@ -26,7 +26,7 @@ Error: React Compiler has skipped optimizing this component because one or more React Compiler only works when your components follow all the rules of React, disabling them may result in unexpected or incorrect behavior. Found suppression `eslint-disable my-app/react-rule`. error.bailout-on-suppression-of-custom-rule.ts:3:0 - 1 | // @eslintSuppressionRules:["my-app","react-rule"] + 1 | // @eslintSuppressionRules:["my-app","react-rule"] @validateExhaustiveMemoizationDependencies:false 2 | > 3 | /* eslint-disable my-app/react-rule */ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Found React rule suppression diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.bailout-on-suppression-of-custom-rule.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.bailout-on-suppression-of-custom-rule.js index 331e551596b..b9344d663b9 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.bailout-on-suppression-of-custom-rule.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.bailout-on-suppression-of-custom-rule.js @@ -1,4 +1,4 @@ -// @eslintSuppressionRules:["my-app","react-rule"] +// @eslintSuppressionRules:["my-app","react-rule"] @validateExhaustiveMemoizationDependencies:false /* eslint-disable my-app/react-rule */ function lowercasecomponent() { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-sketchy-code-use-forget.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-sketchy-code-use-forget.expect.md index be22558e3c7..c4150096508 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-sketchy-code-use-forget.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-sketchy-code-use-forget.expect.md @@ -2,6 +2,7 @@ ## Input ```javascript +// @validateExhaustiveMemoizationDependencies:false /* eslint-disable react-hooks/rules-of-hooks */ function lowercasecomponent() { 'use forget'; @@ -23,25 +24,26 @@ Error: React Compiler has skipped optimizing this component because one or more React Compiler only works when your components follow all the rules of React, disabling them may result in unexpected or incorrect behavior. Found suppression `eslint-disable react-hooks/rules-of-hooks`. -error.invalid-sketchy-code-use-forget.ts:1:0 -> 1 | /* eslint-disable react-hooks/rules-of-hooks */ +error.invalid-sketchy-code-use-forget.ts:2:0 + 1 | // @validateExhaustiveMemoizationDependencies:false +> 2 | /* eslint-disable react-hooks/rules-of-hooks */ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Found React rule suppression - 2 | function lowercasecomponent() { - 3 | 'use forget'; - 4 | const x = []; + 3 | function lowercasecomponent() { + 4 | 'use forget'; + 5 | const x = []; Error: React Compiler has skipped optimizing this component because one or more React ESLint rules were disabled React Compiler only works when your components follow all the rules of React, disabling them may result in unexpected or incorrect behavior. Found suppression `eslint-disable-next-line react-hooks/rules-of-hooks`. -error.invalid-sketchy-code-use-forget.ts:5:2 - 3 | 'use forget'; - 4 | const x = []; -> 5 | // eslint-disable-next-line react-hooks/rules-of-hooks +error.invalid-sketchy-code-use-forget.ts:6:2 + 4 | 'use forget'; + 5 | const x = []; +> 6 | // eslint-disable-next-line react-hooks/rules-of-hooks | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Found React rule suppression - 6 | return
{x}
; - 7 | } - 8 | /* eslint-enable react-hooks/rules-of-hooks */ + 7 | return
{x}
; + 8 | } + 9 | /* eslint-enable react-hooks/rules-of-hooks */ ``` \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-sketchy-code-use-forget.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-sketchy-code-use-forget.js index 861dd92cf55..682c8119110 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-sketchy-code-use-forget.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-sketchy-code-use-forget.js @@ -1,3 +1,4 @@ +// @validateExhaustiveMemoizationDependencies:false /* eslint-disable react-hooks/rules-of-hooks */ function lowercasecomponent() { 'use forget'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-unclosed-eslint-suppression.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-unclosed-eslint-suppression.expect.md index 9b7883f6172..a812cfac3ad 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-unclosed-eslint-suppression.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-unclosed-eslint-suppression.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// Note: Everything below this is sketchy +// Note: Everything below this is sketchy @validateExhaustiveMemoizationDependencies:false /* eslint-disable react-hooks/rules-of-hooks */ function lowercasecomponent() { 'use forget'; @@ -43,7 +43,7 @@ Error: React Compiler has skipped optimizing this component because one or more React Compiler only works when your components follow all the rules of React, disabling them may result in unexpected or incorrect behavior. Found suppression `eslint-disable react-hooks/rules-of-hooks`. error.invalid-unclosed-eslint-suppression.ts:2:0 - 1 | // Note: Everything below this is sketchy + 1 | // Note: Everything below this is sketchy @validateExhaustiveMemoizationDependencies:false > 2 | /* eslint-disable react-hooks/rules-of-hooks */ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Found React rule suppression 3 | function lowercasecomponent() { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-unclosed-eslint-suppression.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-unclosed-eslint-suppression.js index 2388488eb9e..d08f3f2f6f4 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-unclosed-eslint-suppression.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-unclosed-eslint-suppression.js @@ -1,4 +1,4 @@ -// Note: Everything below this is sketchy +// Note: Everything below this is sketchy @validateExhaustiveMemoizationDependencies:false /* eslint-disable react-hooks/rules-of-hooks */ function lowercasecomponent() { 'use forget'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.ref-like-name-not-Ref.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.ref-like-name-not-Ref.expect.md index 22e2f41f799..2558d10d19c 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.ref-like-name-not-Ref.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.ref-like-name-not-Ref.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useCallback, useRef} from 'react'; function useCustomRef() { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.ref-like-name-not-Ref.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.ref-like-name-not-Ref.js index 71c133b0edc..60ab46e4eb4 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.ref-like-name-not-Ref.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.ref-like-name-not-Ref.js @@ -1,4 +1,4 @@ -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useCallback, useRef} from 'react'; function useCustomRef() { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.ref-like-name-not-a-ref.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.ref-like-name-not-a-ref.expect.md index fbde27f77e6..2c2f725ec84 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.ref-like-name-not-a-ref.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.ref-like-name-not-a-ref.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useCallback, useRef} from 'react'; function useCustomRef() { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.ref-like-name-not-a-ref.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.ref-like-name-not-a-ref.js index bd67fe2a9d1..f0e0b584e9f 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.ref-like-name-not-a-ref.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.ref-like-name-not-a-ref.js @@ -1,4 +1,4 @@ -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useCallback, useRef} from 'react'; function useCustomRef() { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.sketchy-code-exhaustive-deps.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.sketchy-code-exhaustive-deps.expect.md index 92c0d5ab1a0..332fee9f06a 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.sketchy-code-exhaustive-deps.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.sketchy-code-exhaustive-deps.expect.md @@ -2,11 +2,14 @@ ## Input ```javascript +import {arrayPush} from 'shared-runtime'; + +// @validateExhaustiveMemoizationDependencies function Component() { const item = []; const foo = useCallback( () => { - item.push(1); + arrayPush(item, 1); }, // eslint-disable-next-line react-hooks/exhaustive-deps [] ); @@ -22,18 +25,18 @@ function Component() { ``` Found 1 error: -Error: React Compiler has skipped optimizing this component because one or more React ESLint rules were disabled +Error: Found missing memoization dependencies -React Compiler only works when your components follow all the rules of React, disabling them may result in unexpected or incorrect behavior. Found suppression `eslint-disable-next-line react-hooks/exhaustive-deps`. +Missing dependencies can cause a value not to update when those inputs change, resulting in stale UI. -error.sketchy-code-exhaustive-deps.ts:6:7 - 4 | () => { - 5 | item.push(1); -> 6 | }, // eslint-disable-next-line react-hooks/exhaustive-deps - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Found React rule suppression - 7 | [] - 8 | ); - 9 | +error.sketchy-code-exhaustive-deps.ts:8:16 + 6 | const foo = useCallback( + 7 | () => { +> 8 | arrayPush(item, 1); + | ^^^^ Missing dependency `item` + 9 | }, // eslint-disable-next-line react-hooks/exhaustive-deps + 10 | [] + 11 | ); ``` \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.sketchy-code-exhaustive-deps.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.sketchy-code-exhaustive-deps.js index ebfb84375e2..3739c0cc841 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.sketchy-code-exhaustive-deps.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.sketchy-code-exhaustive-deps.js @@ -1,8 +1,11 @@ +import {arrayPush} from 'shared-runtime'; + +// @validateExhaustiveMemoizationDependencies function Component() { const item = []; const foo = useCallback( () => { - item.push(1); + arrayPush(item, 1); }, // eslint-disable-next-line react-hooks/exhaustive-deps [] ); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.sketchy-code-rules-of-hooks.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.sketchy-code-rules-of-hooks.expect.md index 2e95c637897..ea2842d0b38 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.sketchy-code-rules-of-hooks.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.sketchy-code-rules-of-hooks.expect.md @@ -2,6 +2,7 @@ ## Input ```javascript +// @validateExhaustiveMemoizationDependencies:false /* eslint-disable react-hooks/rules-of-hooks */ function lowercasecomponent() { const x = []; @@ -27,12 +28,13 @@ Error: React Compiler has skipped optimizing this component because one or more React Compiler only works when your components follow all the rules of React, disabling them may result in unexpected or incorrect behavior. Found suppression `eslint-disable react-hooks/rules-of-hooks`. -error.sketchy-code-rules-of-hooks.ts:1:0 -> 1 | /* eslint-disable react-hooks/rules-of-hooks */ +error.sketchy-code-rules-of-hooks.ts:2:0 + 1 | // @validateExhaustiveMemoizationDependencies:false +> 2 | /* eslint-disable react-hooks/rules-of-hooks */ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Found React rule suppression - 2 | function lowercasecomponent() { - 3 | const x = []; - 4 | return
{x}
; + 3 | function lowercasecomponent() { + 4 | const x = []; + 5 | return
{x}
; ``` \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.sketchy-code-rules-of-hooks.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.sketchy-code-rules-of-hooks.js index a08b1708fcd..c8dd66f67f1 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.sketchy-code-rules-of-hooks.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.sketchy-code-rules-of-hooks.js @@ -1,3 +1,4 @@ +// @validateExhaustiveMemoizationDependencies:false /* eslint-disable react-hooks/rules-of-hooks */ function lowercasecomponent() { const x = []; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-repro-missed-memoization-from-inferred-mutation-in-logger.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-repro-missed-memoization-from-inferred-mutation-in-logger.expect.md index be31341d15d..618e1fb2883 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-repro-missed-memoization-from-inferred-mutation-in-logger.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-repro-missed-memoization-from-inferred-mutation-in-logger.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @flow @validatePreserveExistingMemoizationGuarantees @enablePreserveExistingMemoizationGuarantees:false +// @flow @validatePreserveExistingMemoizationGuarantees @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useFragment} from 'react-relay'; import LogEvent from 'LogEvent'; import {useCallback, useMemo} from 'react'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-repro-missed-memoization-from-inferred-mutation-in-logger.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-repro-missed-memoization-from-inferred-mutation-in-logger.js index c71723f4964..a59fda33df0 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-repro-missed-memoization-from-inferred-mutation-in-logger.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-repro-missed-memoization-from-inferred-mutation-in-logger.js @@ -1,4 +1,4 @@ -// @flow @validatePreserveExistingMemoizationGuarantees @enablePreserveExistingMemoizationGuarantees:false +// @flow @validatePreserveExistingMemoizationGuarantees @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useFragment} from 'react-relay'; import LogEvent from 'LogEvent'; import {useCallback, useMemo} from 'react'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/existing-variables-with-c-name.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/existing-variables-with-c-name.expect.md index 0ead4d68f58..4257f9b6047 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/existing-variables-with-c-name.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/existing-variables-with-c-name.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo, useState} from 'react'; import {ValidateMemoization} from 'shared-runtime'; @@ -29,7 +29,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c2 } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false +import { c as _c2 } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import { useMemo, useState } from "react"; import { ValidateMemoization } from "shared-runtime"; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/existing-variables-with-c-name.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/existing-variables-with-c-name.js index 16af7ef85d1..bcc2fba9788 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/existing-variables-with-c-name.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/existing-variables-with-c-name.js @@ -1,4 +1,4 @@ -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo, useState} from 'react'; import {ValidateMemoization} from 'shared-runtime'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fast-refresh-refresh-on-const-changes-dev.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fast-refresh-refresh-on-const-changes-dev.expect.md index 1524de192d7..301eee10da0 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fast-refresh-refresh-on-const-changes-dev.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fast-refresh-refresh-on-const-changes-dev.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @compilationMode:"infer" @enableResetCacheOnSourceFileChanges +// @compilationMode:"infer" @enableResetCacheOnSourceFileChanges @validateExhaustiveMemoizationDependencies:false import {useEffect, useMemo, useState} from 'react'; import {ValidateMemoization} from 'shared-runtime'; @@ -46,7 +46,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @compilationMode:"infer" @enableResetCacheOnSourceFileChanges +import { c as _c } from "react/compiler-runtime"; // @compilationMode:"infer" @enableResetCacheOnSourceFileChanges @validateExhaustiveMemoizationDependencies:false import { useEffect, useMemo, useState } from "react"; import { ValidateMemoization } from "shared-runtime"; @@ -63,12 +63,12 @@ function unsafeUpdateConst() { function Component() { const $ = _c(3); if ( - $[0] !== "a585d27423c1181e7b6305ff909458183d284658c3c3d2e3764e1128be302fd7" + $[0] !== "36c02976ff5bc474b7510128ea8220ffe31d92cd5d245148ed0a43146d18ded4" ) { for (let $i = 0; $i < 3; $i += 1) { $[$i] = Symbol.for("react.memo_cache_sentinel"); } - $[0] = "a585d27423c1181e7b6305ff909458183d284658c3c3d2e3764e1128be302fd7"; + $[0] = "36c02976ff5bc474b7510128ea8220ffe31d92cd5d245148ed0a43146d18ded4"; } useState(_temp); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fast-refresh-refresh-on-const-changes-dev.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fast-refresh-refresh-on-const-changes-dev.js index 9130f13c15c..c5fcdf146ed 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fast-refresh-refresh-on-const-changes-dev.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fast-refresh-refresh-on-const-changes-dev.js @@ -1,4 +1,4 @@ -// @compilationMode:"infer" @enableResetCacheOnSourceFileChanges +// @compilationMode:"infer" @enableResetCacheOnSourceFileChanges @validateExhaustiveMemoizationDependencies:false import {useEffect, useMemo, useState} from 'react'; import {ValidateMemoization} from 'shared-runtime'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/gating/dynamic-gating-bailout-nopanic.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/gating/dynamic-gating-bailout-nopanic.expect.md index 4c5461f6f34..535f98e574f 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/gating/dynamic-gating-bailout-nopanic.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/gating/dynamic-gating-bailout-nopanic.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @dynamicGating:{"source":"shared-runtime"} @validatePreserveExistingMemoizationGuarantees @panicThreshold:"none" @loggerTestOnly +// @dynamicGating:{"source":"shared-runtime"} @validatePreserveExistingMemoizationGuarantees @panicThreshold:"none" @loggerTestOnly @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; import {identity} from 'shared-runtime'; @@ -30,7 +30,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -// @dynamicGating:{"source":"shared-runtime"} @validatePreserveExistingMemoizationGuarantees @panicThreshold:"none" @loggerTestOnly +// @dynamicGating:{"source":"shared-runtime"} @validatePreserveExistingMemoizationGuarantees @panicThreshold:"none" @loggerTestOnly @validateExhaustiveMemoizationDependencies:false import { useMemo } from "react"; import { identity } from "shared-runtime"; @@ -58,7 +58,7 @@ export const FIXTURE_ENTRYPOINT = { ## Logs ``` -{"kind":"CompileError","fnLoc":{"start":{"line":6,"column":0,"index":206},"end":{"line":16,"column":1,"index":433},"filename":"dynamic-gating-bailout-nopanic.ts"},"detail":{"options":{"category":"PreserveManualMemo","reason":"Existing memoization could not be preserved","description":"React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected. The inferred dependency was `value`, but the source dependencies were []. Inferred dependency not present in source","suggestions":null,"details":[{"kind":"error","loc":{"start":{"line":9,"column":31,"index":288},"end":{"line":9,"column":52,"index":309},"filename":"dynamic-gating-bailout-nopanic.ts"},"message":"Could not preserve existing manual memoization"}]}}} +{"kind":"CompileError","fnLoc":{"start":{"line":6,"column":0,"index":255},"end":{"line":16,"column":1,"index":482},"filename":"dynamic-gating-bailout-nopanic.ts"},"detail":{"options":{"category":"PreserveManualMemo","reason":"Existing memoization could not be preserved","description":"React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected. The inferred dependency was `value`, but the source dependencies were []. Inferred dependency not present in source","suggestions":null,"details":[{"kind":"error","loc":{"start":{"line":9,"column":31,"index":337},"end":{"line":9,"column":52,"index":358},"filename":"dynamic-gating-bailout-nopanic.ts"},"message":"Could not preserve existing manual memoization"}]}}} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/gating/dynamic-gating-bailout-nopanic.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/gating/dynamic-gating-bailout-nopanic.js index ceddbefdd1b..381c2d4c565 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/gating/dynamic-gating-bailout-nopanic.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/gating/dynamic-gating-bailout-nopanic.js @@ -1,4 +1,4 @@ -// @dynamicGating:{"source":"shared-runtime"} @validatePreserveExistingMemoizationGuarantees @panicThreshold:"none" @loggerTestOnly +// @dynamicGating:{"source":"shared-runtime"} @validatePreserveExistingMemoizationGuarantees @panicThreshold:"none" @loggerTestOnly @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; import {identity} from 'shared-runtime'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-function/nullable-objects/assume-invoked/use-memo-returned.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-function/nullable-objects/assume-invoked/use-memo-returned.expect.md index 32d454712f3..c5cfff1cf71 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-function/nullable-objects/assume-invoked/use-memo-returned.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-function/nullable-objects/assume-invoked/use-memo-returned.expect.md @@ -2,6 +2,7 @@ ## Input ```javascript +// @validateExhaustiveMemoizationDependencies:false import {useState, useMemo} from 'react'; import {useIdentity} from 'shared-runtime'; @@ -36,7 +37,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; +import { c as _c } from "react/compiler-runtime"; // @validateExhaustiveMemoizationDependencies:false import { useState, useMemo } from "react"; import { useIdentity } from "shared-runtime"; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-function/nullable-objects/assume-invoked/use-memo-returned.ts b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-function/nullable-objects/assume-invoked/use-memo-returned.ts index 6cb2e44a2b4..6d0546289c2 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-function/nullable-objects/assume-invoked/use-memo-returned.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-function/nullable-objects/assume-invoked/use-memo-returned.ts @@ -1,3 +1,4 @@ +// @validateExhaustiveMemoizationDependencies:false import {useState, useMemo} from 'react'; import {useIdentity} from 'shared-runtime'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-useMemo-return-empty.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-useMemo-return-empty.expect.md index c6737d78a1b..44e70351691 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-useMemo-return-empty.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-useMemo-return-empty.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @loggerTestOnly +// @loggerTestOnly @validateExhaustiveMemoizationDependencies:false function component(a) { let x = useMemo(() => { mutate(a); @@ -15,7 +15,7 @@ function component(a) { ## Code ```javascript -// @loggerTestOnly +// @loggerTestOnly @validateExhaustiveMemoizationDependencies:false function component(a) { mutate(a); } @@ -25,8 +25,8 @@ function component(a) { ## Logs ``` -{"kind":"CompileError","detail":{"options":{"category":"VoidUseMemo","reason":"useMemo() callbacks must return a value","description":"This useMemo() callback doesn't return a value. useMemo() is for computing and caching values, not for arbitrary side effects","suggestions":null,"details":[{"kind":"error","loc":{"start":{"line":3,"column":18,"index":61},"end":{"line":5,"column":3,"index":87},"filename":"invalid-useMemo-return-empty.ts"},"message":"useMemo() callbacks must return a value"}]}},"fnLoc":null} -{"kind":"CompileSuccess","fnLoc":{"start":{"line":2,"column":0,"index":19},"end":{"line":7,"column":1,"index":107},"filename":"invalid-useMemo-return-empty.ts"},"fnName":"component","memoSlots":0,"memoBlocks":0,"memoValues":0,"prunedMemoBlocks":1,"prunedMemoValues":0} +{"kind":"CompileError","detail":{"options":{"category":"VoidUseMemo","reason":"useMemo() callbacks must return a value","description":"This useMemo() callback doesn't return a value. useMemo() is for computing and caching values, not for arbitrary side effects","suggestions":null,"details":[{"kind":"error","loc":{"start":{"line":3,"column":18,"index":110},"end":{"line":5,"column":3,"index":136},"filename":"invalid-useMemo-return-empty.ts"},"message":"useMemo() callbacks must return a value"}]}},"fnLoc":null} +{"kind":"CompileSuccess","fnLoc":{"start":{"line":2,"column":0,"index":68},"end":{"line":7,"column":1,"index":156},"filename":"invalid-useMemo-return-empty.ts"},"fnName":"component","memoSlots":0,"memoBlocks":0,"memoValues":0,"prunedMemoBlocks":1,"prunedMemoValues":0} ``` ### Eval output diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-useMemo-return-empty.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-useMemo-return-empty.js index d70bd138113..8095a7af8f1 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-useMemo-return-empty.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/invalid-useMemo-return-empty.js @@ -1,4 +1,4 @@ -// @loggerTestOnly +// @loggerTestOnly @validateExhaustiveMemoizationDependencies:false function component(a) { let x = useMemo(() => { mutate(a); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-through-identity-function-expression.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-through-identity-function-expression.expect.md index 98128b1e506..e7b0fe8e75e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-through-identity-function-expression.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-through-identity-function-expression.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; import {identity, ValidateMemoization} from 'shared-runtime'; @@ -33,7 +33,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false +import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import { useMemo } from "react"; import { identity, ValidateMemoization } from "shared-runtime"; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-through-identity-function-expression.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-through-identity-function-expression.js index 3190c0e7c7c..2ac414570d8 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-through-identity-function-expression.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-through-identity-function-expression.js @@ -1,4 +1,4 @@ -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; import {identity, ValidateMemoization} from 'shared-runtime'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-through-identity.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-through-identity.expect.md index 012aec12b36..a392cb1137f 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-through-identity.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-through-identity.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; import {identity, ValidateMemoization} from 'shared-runtime'; @@ -30,7 +30,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false +import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import { useMemo } from "react"; import { identity, ValidateMemoization } from "shared-runtime"; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-through-identity.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-through-identity.js index a542514109e..33ba3a106ff 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-through-identity.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-through-identity.js @@ -1,4 +1,4 @@ -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; import {identity, ValidateMemoization} from 'shared-runtime'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/repro-destructure-from-prop-with-default-value.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/repro-destructure-from-prop-with-default-value.expect.md index eec95683aa2..25e4a3843cf 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/repro-destructure-from-prop-with-default-value.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/repro-destructure-from-prop-with-default-value.expect.md @@ -2,6 +2,7 @@ ## Input ```javascript +// @validateExhaustiveMemoizationDependencies:false export function useFormatRelativeTime(opts = {}) { const {timeZone, minimal} = opts; const format = useCallback(function formatWithUnit() {}, [minimal]); @@ -21,7 +22,7 @@ export function useFormatRelativeTime(opts = {}) { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; +import { c as _c } from "react/compiler-runtime"; // @validateExhaustiveMemoizationDependencies:false export function useFormatRelativeTime(t0) { const $ = _c(1); const opts = t0 === undefined ? {} : t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/repro-destructure-from-prop-with-default-value.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/repro-destructure-from-prop-with-default-value.js index dbcb7303778..bd2548f672b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/repro-destructure-from-prop-with-default-value.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/repro-destructure-from-prop-with-default-value.js @@ -1,3 +1,4 @@ +// @validateExhaustiveMemoizationDependencies:false export function useFormatRelativeTime(opts = {}) { const {timeZone, minimal} = opts; const format = useCallback(function formatWithUnit() {}, [minimal]); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/todo-control-flow-sensitive-mutation.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/todo-control-flow-sensitive-mutation.expect.md index 53a99470a92..92e1a1c3b8e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/todo-control-flow-sensitive-mutation.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/todo-control-flow-sensitive-mutation.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; import { mutate, @@ -50,7 +50,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false +import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import { useMemo } from "react"; import { mutate, diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/todo-control-flow-sensitive-mutation.tsx b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/todo-control-flow-sensitive-mutation.tsx index 5d61126ee97..c40d192468e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/todo-control-flow-sensitive-mutation.tsx +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/todo-control-flow-sensitive-mutation.tsx @@ -1,4 +1,4 @@ -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; import { mutate, diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-add-captured-array-to-itself.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-add-captured-array-to-itself.expect.md index 9cb71732a09..0f7eebb877c 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-add-captured-array-to-itself.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-add-captured-array-to-itself.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; import { typedCapture, @@ -43,7 +43,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false +import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import { useMemo } from "react"; import { typedCapture, diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-add-captured-array-to-itself.tsx b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-add-captured-array-to-itself.tsx index 1e997906428..ada8679f251 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-add-captured-array-to-itself.tsx +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-add-captured-array-to-itself.tsx @@ -1,4 +1,4 @@ -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; import { typedCapture, diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-capture-createfrom-lambda.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-capture-createfrom-lambda.expect.md index 81c53c90167..5a3388fd8e8 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-capture-createfrom-lambda.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-capture-createfrom-lambda.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; import { typedCapture, @@ -41,7 +41,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false +import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import { useMemo } from "react"; import { typedCapture, diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-capture-createfrom-lambda.tsx b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-capture-createfrom-lambda.tsx index cb282549f06..a4a2279810c 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-capture-createfrom-lambda.tsx +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-capture-createfrom-lambda.tsx @@ -1,4 +1,4 @@ -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; import { typedCapture, diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-capture-createfrom.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-capture-createfrom.expect.md index a51aaf5367c..9885ef17c10 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-capture-createfrom.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-capture-createfrom.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; import { typedCapture, @@ -37,7 +37,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false +import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import { useMemo } from "react"; import { typedCapture, diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-capture-createfrom.tsx b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-capture-createfrom.tsx index 6d2f1785316..f343cc2afa2 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-capture-createfrom.tsx +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-capture-createfrom.tsx @@ -1,4 +1,4 @@ -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; import { typedCapture, diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-phi-assign-or-capture.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-phi-assign-or-capture.expect.md index fd7f2b0cda0..4222c0dfe2c 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-phi-assign-or-capture.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-phi-assign-or-capture.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; import { typedCapture, @@ -41,7 +41,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false +import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import { useMemo } from "react"; import { typedCapture, diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-phi-assign-or-capture.tsx b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-phi-assign-or-capture.tsx index 03ca2ef583a..ece6a2dc135 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-phi-assign-or-capture.tsx +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/transitivity-phi-assign-or-capture.tsx @@ -1,4 +1,4 @@ -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; import { typedCapture, diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useCallback-reordering-deplist-controlflow.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useCallback-reordering-deplist-controlflow.expect.md index 6c45eb8bfaf..a9f6e8805f3 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useCallback-reordering-deplist-controlflow.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useCallback-reordering-deplist-controlflow.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false +// @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useCallback} from 'react'; import {Stringify} from 'shared-runtime'; @@ -36,7 +36,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false +import { c as _c } from "react/compiler-runtime"; // @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import { useCallback } from "react"; import { Stringify } from "shared-runtime"; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useCallback-reordering-deplist-controlflow.tsx b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useCallback-reordering-deplist-controlflow.tsx index f360a821325..861c413386d 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useCallback-reordering-deplist-controlflow.tsx +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useCallback-reordering-deplist-controlflow.tsx @@ -1,4 +1,4 @@ -// @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false +// @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useCallback} from 'react'; import {Stringify} from 'shared-runtime'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useCallback-reordering-depslist-assignment.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useCallback-reordering-depslist-assignment.expect.md index f29be3d405b..4a65f8a4e29 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useCallback-reordering-depslist-assignment.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useCallback-reordering-depslist-assignment.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false +// @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useCallback} from 'react'; import {Stringify} from 'shared-runtime'; @@ -31,7 +31,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false +import { c as _c } from "react/compiler-runtime"; // @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import { useCallback } from "react"; import { Stringify } from "shared-runtime"; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useCallback-reordering-depslist-assignment.tsx b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useCallback-reordering-depslist-assignment.tsx index 061af52723e..01a87a22599 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useCallback-reordering-depslist-assignment.tsx +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useCallback-reordering-depslist-assignment.tsx @@ -1,4 +1,4 @@ -// @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false +// @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useCallback} from 'react'; import {Stringify} from 'shared-runtime'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useMemo-reordering-depslist-assignment.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useMemo-reordering-depslist-assignment.expect.md index ce3e3734e98..2d3f4699866 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useMemo-reordering-depslist-assignment.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useMemo-reordering-depslist-assignment.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false +// @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; function useFoo(arr1, arr2) { @@ -27,7 +27,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false +import { c as _c } from "react/compiler-runtime"; // @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import { useMemo } from "react"; function useFoo(arr1, arr2) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useMemo-reordering-depslist-assignment.ts b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useMemo-reordering-depslist-assignment.ts index 7c4daae371f..7b9c6e54da7 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useMemo-reordering-depslist-assignment.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/useMemo-reordering-depslist-assignment.ts @@ -1,4 +1,4 @@ -// @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false +// @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; function useFoo(arr1, arr2) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.preserve-use-memo-ref-missing-reactive.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.preserve-use-memo-ref-missing-reactive.expect.md index 3eb8e6cb262..ca650005c79 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.preserve-use-memo-ref-missing-reactive.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.preserve-use-memo-ref-missing-reactive.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useCallback, useRef} from 'react'; function useFoo({cond}) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.preserve-use-memo-ref-missing-reactive.ts b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.preserve-use-memo-ref-missing-reactive.ts index 8238e1b74d0..826e79f526d 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.preserve-use-memo-ref-missing-reactive.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.preserve-use-memo-ref-missing-reactive.ts @@ -1,4 +1,4 @@ -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useCallback, useRef} from 'react'; function useFoo({cond}) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useCallback-aliased-var.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useCallback-aliased-var.expect.md index f742006ea12..9d45c500d28 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useCallback-aliased-var.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useCallback-aliased-var.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false // This is technically a false positive, but source is already breaking // `exhaustive-deps` lint rule (and can be considered invalid). diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useCallback-aliased-var.ts b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useCallback-aliased-var.ts index b6f64482a25..98c697d2208 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useCallback-aliased-var.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useCallback-aliased-var.ts @@ -1,4 +1,4 @@ -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false // This is technically a false positive, but source is already breaking // `exhaustive-deps` lint rule (and can be considered invalid). diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useCallback-property-call-dep.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useCallback-property-call-dep.expect.md index 506a20792e9..ba1cc7e545e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useCallback-property-call-dep.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useCallback-property-call-dep.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useCallback} from 'react'; function Component({propA}) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useCallback-property-call-dep.ts b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useCallback-property-call-dep.ts index f87c68f9f1c..0c1f02778c6 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useCallback-property-call-dep.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useCallback-property-call-dep.ts @@ -1,4 +1,4 @@ -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useCallback} from 'react'; function Component({propA}) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-aliased-var.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-aliased-var.expect.md index 11a7de33481..7c1539a8cd8 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-aliased-var.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-aliased-var.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false // This is technically a false positive, but source is already breaking // `exhaustive-deps` lint rule (and can be considered invalid). diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-aliased-var.ts b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-aliased-var.ts index e61c721034b..31baea97a4f 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-aliased-var.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-aliased-var.ts @@ -1,4 +1,4 @@ -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false // This is technically a false positive, but source is already breaking // `exhaustive-deps` lint rule (and can be considered invalid). diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-property-call-chained-object.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-property-call-chained-object.expect.md index 00cc3fb8395..6b707f3fe3b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-property-call-chained-object.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-property-call-chained-object.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; function Component({propA}) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-property-call-chained-object.ts b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-property-call-chained-object.ts index 9c5b851ab6e..5bd9603c49d 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-property-call-chained-object.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-property-call-chained-object.ts @@ -1,4 +1,4 @@ -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; function Component({propA}) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-property-call-dep.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-property-call-dep.expect.md index 1c86ef5a927..293b35629ff 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-property-call-dep.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-property-call-dep.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; function Component({propA}) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-property-call-dep.ts b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-property-call-dep.ts index 658c20f810c..6109e8033ac 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-property-call-dep.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-property-call-dep.ts @@ -1,4 +1,4 @@ -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; function Component({propA}) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-unrelated-mutation-in-depslist.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-unrelated-mutation-in-depslist.expect.md index 8ed05bcaf40..7d2125259ae 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-unrelated-mutation-in-depslist.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-unrelated-mutation-in-depslist.expect.md @@ -32,19 +32,15 @@ function useFoo(input1) { ``` Found 1 error: -Compilation Skipped: Existing memoization could not be preserved +Error: Found missing memoization dependencies -React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected. The inferred dependency was `input1`, but the source dependencies were [y]. Inferred different dependency than source. +Missing dependencies can cause a value not to update when those inputs change, resulting in stale UI. -error.useMemo-unrelated-mutation-in-depslist.ts:16:27 - 14 | const x = {}; - 15 | const y = [input1]; -> 16 | const memoized = useMemo(() => { - | ^^^^^^^ -> 17 | return [y]; - | ^^^^^^^^^^^^^^^ +error.useMemo-unrelated-mutation-in-depslist.ts:18:14 + 16 | const memoized = useMemo(() => { + 17 | return [y]; > 18 | }, [(mutate(x), y)]); - | ^^^^ Could not preserve existing manual memoization + | ^ Missing dependency `x` 19 | 20 | return [x, memoized]; 21 | } diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/repro-maybe-invalid-useMemo-read-maybeRef.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/repro-maybe-invalid-useMemo-read-maybeRef.expect.md index 9d02bff8b4c..7bb7de6ea2a 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/repro-maybe-invalid-useMemo-read-maybeRef.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/repro-maybe-invalid-useMemo-read-maybeRef.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; function useHook(maybeRef, shouldRead) { @@ -16,7 +16,7 @@ function useHook(maybeRef, shouldRead) { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validatePreserveExistingMemoizationGuarantees +import { c as _c } from "react/compiler-runtime"; // @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import { useMemo } from "react"; function useHook(maybeRef, shouldRead) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/repro-maybe-invalid-useMemo-read-maybeRef.ts b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/repro-maybe-invalid-useMemo-read-maybeRef.ts index 1bf54a5aa53..1513065f2cf 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/repro-maybe-invalid-useMemo-read-maybeRef.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/repro-maybe-invalid-useMemo-read-maybeRef.ts @@ -1,4 +1,4 @@ -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; function useHook(maybeRef, shouldRead) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-infer-fewer-deps.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-infer-fewer-deps.expect.md index 3f1607a4f30..cccbe2d31f2 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-infer-fewer-deps.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-infer-fewer-deps.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useCallback} from 'react'; @@ -21,7 +21,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validatePreserveExistingMemoizationGuarantees +import { c as _c } from "react/compiler-runtime"; // @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import { useCallback } from "react"; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-infer-fewer-deps.ts b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-infer-fewer-deps.ts index ab60de9a0eb..78dfa1e658c 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-infer-fewer-deps.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-infer-fewer-deps.ts @@ -1,4 +1,4 @@ -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useCallback} from 'react'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-infer-scope-global.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-infer-scope-global.expect.md index a046c76b047..87cd57e917e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-infer-scope-global.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-infer-scope-global.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useCallback} from 'react'; import {CONST_STRING0} from 'shared-runtime'; @@ -22,7 +22,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import { useCallback } from "react"; import { CONST_STRING0 } from "shared-runtime"; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-infer-scope-global.ts b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-infer-scope-global.ts index 1e8b509551a..0f8836d2030 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-infer-scope-global.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-infer-scope-global.ts @@ -1,4 +1,4 @@ -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useCallback} from 'react'; import {CONST_STRING0} from 'shared-runtime'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-nonescaping-invoked-callback-escaping-return.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-nonescaping-invoked-callback-escaping-return.expect.md index 6d918391546..0eb58ef85e0 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-nonescaping-invoked-callback-escaping-return.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-nonescaping-invoked-callback-escaping-return.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validatePreserveExistingMemoizationGuarantees @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions +// @validatePreserveExistingMemoizationGuarantees @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions @validateExhaustiveMemoizationDependencies:false import {useCallback} from 'react'; function Component({entity, children}) { @@ -36,7 +36,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validatePreserveExistingMemoizationGuarantees @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions +import { c as _c } from "react/compiler-runtime"; // @validatePreserveExistingMemoizationGuarantees @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions @validateExhaustiveMemoizationDependencies:false import { useCallback } from "react"; function Component(t0) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-nonescaping-invoked-callback-escaping-return.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-nonescaping-invoked-callback-escaping-return.js index 825df4ce085..640b9b8b9e6 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-nonescaping-invoked-callback-escaping-return.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-nonescaping-invoked-callback-escaping-return.js @@ -1,4 +1,4 @@ -// @validatePreserveExistingMemoizationGuarantees @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions +// @validatePreserveExistingMemoizationGuarantees @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions @validateExhaustiveMemoizationDependencies:false import {useCallback} from 'react'; function Component({entity, children}) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-reordering-deplist-controlflow.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-reordering-deplist-controlflow.expect.md index db5ff86ed23..1b94677c78d 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-reordering-deplist-controlflow.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-reordering-deplist-controlflow.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useCallback} from 'react'; import {Stringify} from 'shared-runtime'; @@ -36,7 +36,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false +import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import { useCallback } from "react"; import { Stringify } from "shared-runtime"; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-reordering-deplist-controlflow.tsx b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-reordering-deplist-controlflow.tsx index 698fbeb2ca0..9831fcfdec9 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-reordering-deplist-controlflow.tsx +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-reordering-deplist-controlflow.tsx @@ -1,4 +1,4 @@ -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useCallback} from 'react'; import {Stringify} from 'shared-runtime'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-reordering-depslist-assignment.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-reordering-depslist-assignment.expect.md index 448c2133301..78a7b36eba6 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-reordering-depslist-assignment.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-reordering-depslist-assignment.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useCallback} from 'react'; import {Stringify} from 'shared-runtime'; @@ -31,7 +31,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false +import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import { useCallback } from "react"; import { Stringify } from "shared-runtime"; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-reordering-depslist-assignment.tsx b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-reordering-depslist-assignment.tsx index d5d36490dfb..170593c486a 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-reordering-depslist-assignment.tsx +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-reordering-depslist-assignment.tsx @@ -1,4 +1,4 @@ -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useCallback} from 'react'; import {Stringify} from 'shared-runtime'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-with-no-depslist.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-with-no-depslist.expect.md index f139b540b38..81d7a48aa75 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-with-no-depslist.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-with-no-depslist.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useCallback} from 'react'; // Compiler can produce any memoization it finds valid if the @@ -24,7 +24,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validatePreserveExistingMemoizationGuarantees +import { c as _c } from "react/compiler-runtime"; // @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import { useCallback } from "react"; // Compiler can produce any memoization it finds valid if the diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-with-no-depslist.ts b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-with-no-depslist.ts index 0e640f130d3..5cabcdf7676 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-with-no-depslist.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-with-no-depslist.ts @@ -1,4 +1,4 @@ -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useCallback} from 'react'; // Compiler can produce any memoization it finds valid if the diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-dep-array-literal-access.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-dep-array-literal-access.expect.md index 85a27553d71..d20b74d04b6 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-dep-array-literal-access.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-dep-array-literal-access.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; import {makeArray} from 'shared-runtime'; @@ -27,7 +27,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validatePreserveExistingMemoizationGuarantees +import { c as _c } from "react/compiler-runtime"; // @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import { useMemo } from "react"; import { makeArray } from "shared-runtime"; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-dep-array-literal-access.ts b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-dep-array-literal-access.ts index 619f8129451..7602807972d 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-dep-array-literal-access.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-dep-array-literal-access.ts @@ -1,4 +1,4 @@ -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; import {makeArray} from 'shared-runtime'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-infer-fewer-deps.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-infer-fewer-deps.expect.md index 27dbb57698a..11025151911 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-infer-fewer-deps.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-infer-fewer-deps.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; @@ -21,7 +21,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validatePreserveExistingMemoizationGuarantees +import { c as _c } from "react/compiler-runtime"; // @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import { useMemo } from "react"; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-infer-fewer-deps.ts b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-infer-fewer-deps.ts index 6522bdae9d3..2ca2e7c7155 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-infer-fewer-deps.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-infer-fewer-deps.ts @@ -1,4 +1,4 @@ -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-infer-scope-global.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-infer-scope-global.expect.md index 2a805aa7775..3d146ba3e61 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-infer-scope-global.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-infer-scope-global.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; import {CONST_STRING0} from 'shared-runtime'; @@ -22,7 +22,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validatePreserveExistingMemoizationGuarantees +import { c as _c } from "react/compiler-runtime"; // @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import { useMemo } from "react"; import { CONST_STRING0 } from "shared-runtime"; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-infer-scope-global.ts b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-infer-scope-global.ts index 7037e9ee3d2..3565dfd39b9 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-infer-scope-global.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-infer-scope-global.ts @@ -1,4 +1,4 @@ -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; import {CONST_STRING0} from 'shared-runtime'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-reordering-depslist-assignment.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-reordering-depslist-assignment.expect.md index 58b2c9762b2..7af90abc7b8 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-reordering-depslist-assignment.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-reordering-depslist-assignment.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; function useFoo(arr1, arr2) { @@ -27,7 +27,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false +import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import { useMemo } from "react"; function useFoo(arr1, arr2) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-reordering-depslist-assignment.ts b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-reordering-depslist-assignment.ts index 673380de119..9838cd9456d 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-reordering-depslist-assignment.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-reordering-depslist-assignment.ts @@ -1,4 +1,4 @@ -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; function useFoo(arr1, arr2) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-reordering-depslist-controlflow.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-reordering-depslist-controlflow.expect.md index d208ce4fb74..735120f9000 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-reordering-depslist-controlflow.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-reordering-depslist-controlflow.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; import {Stringify} from 'shared-runtime'; @@ -36,7 +36,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false +import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import { useMemo } from "react"; import { Stringify } from "shared-runtime"; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-reordering-depslist-controlflow.tsx b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-reordering-depslist-controlflow.tsx index eae6a75854e..673493c313b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-reordering-depslist-controlflow.tsx +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-reordering-depslist-controlflow.tsx @@ -1,4 +1,4 @@ -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; import {Stringify} from 'shared-runtime'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-with-no-depslist.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-with-no-depslist.expect.md index bb0518c25fd..3a8a7393f51 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-with-no-depslist.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-with-no-depslist.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; // Compiler can produce any memoization it finds valid if the @@ -24,7 +24,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validatePreserveExistingMemoizationGuarantees +import { c as _c } from "react/compiler-runtime"; // @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import { useMemo } from "react"; // Compiler can produce any memoization it finds valid if the diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-with-no-depslist.ts b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-with-no-depslist.ts index 917f7b75ab7..05799ccfa3b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-with-no-depslist.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-with-no-depslist.ts @@ -1,4 +1,4 @@ -// @validatePreserveExistingMemoizationGuarantees +// @validatePreserveExistingMemoizationGuarantees @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; // Compiler can produce any memoization it finds valid if the diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/useMemo-multiple-if-else.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/useMemo-multiple-if-else.expect.md index 1d4761e447b..bd8c1b994e1 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/useMemo-multiple-if-else.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/useMemo-multiple-if-else.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @enablePropagateDepsInHIR +// @enablePropagateDepsInHIR @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; function Component(props) { @@ -30,7 +30,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @enablePropagateDepsInHIR +import { c as _c } from "react/compiler-runtime"; // @enablePropagateDepsInHIR @validateExhaustiveMemoizationDependencies:false import { useMemo } from "react"; function Component(props) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/useMemo-multiple-if-else.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/useMemo-multiple-if-else.js index 7075ecaac53..81794651893 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/useMemo-multiple-if-else.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/useMemo-multiple-if-else.js @@ -1,4 +1,4 @@ -// @enablePropagateDepsInHIR +// @enablePropagateDepsInHIR @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; function Component(props) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-no-declarations-in-reactive-scope-with-early-return.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-no-declarations-in-reactive-scope-with-early-return.expect.md index 6cf8820e984..1b8f59e45e8 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-no-declarations-in-reactive-scope-with-early-return.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-no-declarations-in-reactive-scope-with-early-return.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions @enablePreserveExistingMemoizationGuarantees:false +// @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false function Component() { const items = useItems(); const filteredItems = useMemo( @@ -37,7 +37,7 @@ function Component() { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions @enablePreserveExistingMemoizationGuarantees:false +import { c as _c } from "react/compiler-runtime"; // @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false function Component() { const $ = _c(6); const items = useItems(); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-no-declarations-in-reactive-scope-with-early-return.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-no-declarations-in-reactive-scope-with-early-return.js index aa43a8d1886..a4baa811b5f 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-no-declarations-in-reactive-scope-with-early-return.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-no-declarations-in-reactive-scope-with-early-return.js @@ -1,4 +1,4 @@ -// @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions @enablePreserveExistingMemoizationGuarantees:false +// @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false function Component() { const items = useItems(); const filteredItems = useMemo( diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro.expect.md index 9ca367e8a8e..19102267cc1 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @validateNoVoidUseMemo:false +// @validateNoVoidUseMemo:false @validateExhaustiveMemoizationDependencies:false function Component(props) { const item = props.item; const thumbnails = []; @@ -23,7 +23,7 @@ function Component(props) { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @validateNoVoidUseMemo:false +import { c as _c } from "react/compiler-runtime"; // @validateNoVoidUseMemo:false @validateExhaustiveMemoizationDependencies:false function Component(props) { const $ = _c(6); const item = props.item; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro.js index de3026e4e58..0a4bbac2e08 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro.js @@ -1,4 +1,4 @@ -// @validateNoVoidUseMemo:false +// @validateNoVoidUseMemo:false @validateExhaustiveMemoizationDependencies:false function Component(props) { const item = props.item; const thumbnails = []; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/unclosed-eslint-suppression-skips-all-components.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/unclosed-eslint-suppression-skips-all-components.expect.md index 2a419a6415d..a55ca6e3713 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/unclosed-eslint-suppression-skips-all-components.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/unclosed-eslint-suppression-skips-all-components.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @panicThreshold:"none" +// @panicThreshold:"none" @validateExhaustiveMemoizationDependencies:false // unclosed disable rule should affect all components /* eslint-disable react-hooks/rules-of-hooks */ @@ -20,7 +20,7 @@ function ValidComponent2(props) { ## Code ```javascript -// @panicThreshold:"none" +// @panicThreshold:"none" @validateExhaustiveMemoizationDependencies:false // unclosed disable rule should affect all components /* eslint-disable react-hooks/rules-of-hooks */ diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/unclosed-eslint-suppression-skips-all-components.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/unclosed-eslint-suppression-skips-all-components.js index a3e2bab77e2..98308be1f82 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/unclosed-eslint-suppression-skips-all-components.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/unclosed-eslint-suppression-skips-all-components.js @@ -1,4 +1,4 @@ -// @panicThreshold:"none" +// @panicThreshold:"none" @validateExhaustiveMemoizationDependencies:false // unclosed disable rule should affect all components /* eslint-disable react-hooks/rules-of-hooks */ diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-callback-simple.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-callback-simple.expect.md index 6eb085435dd..da6b14a0c97 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-callback-simple.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-callback-simple.expect.md @@ -2,6 +2,7 @@ ## Input ```javascript +// @validateExhaustiveMemoizationDependencies:false function component() { const [count, setCount] = useState(0); const increment = useCallback(() => setCount(count + 1)); @@ -14,7 +15,7 @@ function component() { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; +import { c as _c } from "react/compiler-runtime"; // @validateExhaustiveMemoizationDependencies:false function component() { const $ = _c(4); const [count, setCount] = useState(0); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-callback-simple.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-callback-simple.js index 132fcb30a2b..89b87f2d591 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-callback-simple.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-callback-simple.js @@ -1,3 +1,4 @@ +// @validateExhaustiveMemoizationDependencies:false function component() { const [count, setCount] = useState(0); const increment = useCallback(() => setCount(count + 1)); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useCallback-maybe-modify-free-variable-dont-preserve-memoization-guarantee.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useCallback-maybe-modify-free-variable-dont-preserve-memoization-guarantee.expect.md index a1d176728d2..ea6e43029ce 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useCallback-maybe-modify-free-variable-dont-preserve-memoization-guarantee.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useCallback-maybe-modify-free-variable-dont-preserve-memoization-guarantee.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useCallback} from 'react'; import {identity, makeObject_Primitives, mutate, useHook} from 'shared-runtime'; @@ -31,7 +31,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import { useCallback } from "react"; import { identity, diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useCallback-maybe-modify-free-variable-dont-preserve-memoization-guarantee.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useCallback-maybe-modify-free-variable-dont-preserve-memoization-guarantee.js index 6c8405d0d19..c0984e32193 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useCallback-maybe-modify-free-variable-dont-preserve-memoization-guarantee.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useCallback-maybe-modify-free-variable-dont-preserve-memoization-guarantee.js @@ -1,4 +1,4 @@ -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useCallback} from 'react'; import {identity, makeObject_Primitives, mutate, useHook} from 'shared-runtime'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-if-else-multiple-return.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-if-else-multiple-return.expect.md index 25edfe4e650..40642ebb2d5 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-if-else-multiple-return.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-if-else-multiple-return.expect.md @@ -2,6 +2,7 @@ ## Input ```javascript +// @validateExhaustiveMemoizationDependencies:false function Component(props) { const x = useMemo(() => { if (props.cond) { @@ -17,7 +18,7 @@ function Component(props) { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; +import { c as _c } from "react/compiler-runtime"; // @validateExhaustiveMemoizationDependencies:false function Component(props) { const $ = _c(4); let t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-if-else-multiple-return.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-if-else-multiple-return.js index a39f3b2826e..ba5ab1cb2f4 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-if-else-multiple-return.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-if-else-multiple-return.js @@ -1,3 +1,4 @@ +// @validateExhaustiveMemoizationDependencies:false function Component(props) { const x = useMemo(() => { if (props.cond) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-independently-memoizeable.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-independently-memoizeable.expect.md index 479b1b2c823..c433cd2dfca 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-independently-memoizeable.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-independently-memoizeable.expect.md @@ -2,6 +2,7 @@ ## Input ```javascript +// @validateExhaustiveMemoizationDependencies:false function Component(props) { const [a, b] = useMemo(() => { const items = []; @@ -17,7 +18,7 @@ function Component(props) { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; +import { c as _c } from "react/compiler-runtime"; // @validateExhaustiveMemoizationDependencies:false function Component(props) { const $ = _c(10); let t0; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-independently-memoizeable.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-independently-memoizeable.js index 4f9f5f39c14..a557a278197 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-independently-memoizeable.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-independently-memoizeable.js @@ -1,3 +1,4 @@ +// @validateExhaustiveMemoizationDependencies:false function Component(props) { const [a, b] = useMemo(() => { const items = []; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-inverted-if.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-inverted-if.expect.md index 6a0ba292650..87784e39841 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-inverted-if.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-inverted-if.expect.md @@ -2,6 +2,7 @@ ## Input ```javascript +// @validateExhaustiveMemoizationDependencies:false function Component(props) { const x = useMemo(() => { label: { @@ -26,6 +27,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript +// @validateExhaustiveMemoizationDependencies:false function Component(props) { let t0; bb0: { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-inverted-if.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-inverted-if.js index ca3c838d88a..baecabc252b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-inverted-if.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-inverted-if.js @@ -1,3 +1,4 @@ +// @validateExhaustiveMemoizationDependencies:false function Component(props) { const x = useMemo(() => { label: { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-labeled-statement-unconditional-return.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-labeled-statement-unconditional-return.expect.md index dda4a25e9f0..e4725740624 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-labeled-statement-unconditional-return.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-labeled-statement-unconditional-return.expect.md @@ -2,6 +2,7 @@ ## Input ```javascript +// @validateExhaustiveMemoizationDependencies:false function Component(props) { const x = useMemo(() => { label: { @@ -22,6 +23,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript +// @validateExhaustiveMemoizationDependencies:false function Component(props) { const x = props.value; return x; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-labeled-statement-unconditional-return.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-labeled-statement-unconditional-return.js index 242a1983826..85c63f7470c 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-labeled-statement-unconditional-return.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-labeled-statement-unconditional-return.js @@ -1,3 +1,4 @@ +// @validateExhaustiveMemoizationDependencies:false function Component(props) { const x = useMemo(() => { label: { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-logical.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-logical.expect.md index f944aa454d8..aa195e650a6 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-logical.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-logical.expect.md @@ -2,6 +2,7 @@ ## Input ```javascript +// @validateExhaustiveMemoizationDependencies:false function Component(props) { const x = useMemo(() => props.a && props.b); return x; @@ -18,6 +19,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript +// @validateExhaustiveMemoizationDependencies:false function Component(props) { const x = props.a && props.b; return x; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-logical.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-logical.js index a432c27d9b2..1f05ae7d6a3 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-logical.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-logical.js @@ -1,3 +1,4 @@ +// @validateExhaustiveMemoizationDependencies:false function Component(props) { const x = useMemo(() => props.a && props.b); return x; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-mabye-modified-free-variable-dont-preserve-memoization-guarantees.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-mabye-modified-free-variable-dont-preserve-memoization-guarantees.expect.md index 8b4de101cac..b7f36a1aa9f 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-mabye-modified-free-variable-dont-preserve-memoization-guarantees.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-mabye-modified-free-variable-dont-preserve-memoization-guarantees.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; import {identity, makeObject_Primitives, mutate, useHook} from 'shared-runtime'; @@ -36,7 +36,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import { useMemo } from "react"; import { identity, diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-mabye-modified-free-variable-dont-preserve-memoization-guarantees.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-mabye-modified-free-variable-dont-preserve-memoization-guarantees.js index e1a766e99a3..31617484664 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-mabye-modified-free-variable-dont-preserve-memoization-guarantees.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-mabye-modified-free-variable-dont-preserve-memoization-guarantees.js @@ -1,4 +1,4 @@ -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; import {identity, makeObject_Primitives, mutate, useHook} from 'shared-runtime'; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-multiple-if-else.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-multiple-if-else.expect.md index bf110b75dc8..cb6282de291 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-multiple-if-else.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-multiple-if-else.expect.md @@ -2,6 +2,7 @@ ## Input ```javascript +// @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; function Component(props) { @@ -29,7 +30,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; +import { c as _c } from "react/compiler-runtime"; // @validateExhaustiveMemoizationDependencies:false import { useMemo } from "react"; function Component(props) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-multiple-if-else.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-multiple-if-else.js index dab1cefd0c6..b51cc5fb5f1 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-multiple-if-else.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-multiple-if-else.js @@ -1,3 +1,4 @@ +// @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; function Component(props) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-nested-ifs.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-nested-ifs.expect.md index e0525518c96..0d265a7c296 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-nested-ifs.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-nested-ifs.expect.md @@ -2,6 +2,7 @@ ## Input ```javascript +// @validateExhaustiveMemoizationDependencies:false function Component(props) { const x = useMemo(() => { if (props.cond) { @@ -24,6 +25,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript +// @validateExhaustiveMemoizationDependencies:false function Component(props) { let t0; bb0: { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-nested-ifs.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-nested-ifs.js index d122dcc7a3e..02890978ad1 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-nested-ifs.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-nested-ifs.js @@ -1,3 +1,4 @@ +// @validateExhaustiveMemoizationDependencies:false function Component(props) { const x = useMemo(() => { if (props.cond) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-switch-no-fallthrough.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-switch-no-fallthrough.expect.md index 296589b6eb5..8f1d7a7e065 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-switch-no-fallthrough.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-switch-no-fallthrough.expect.md @@ -2,6 +2,7 @@ ## Input ```javascript +// @validateExhaustiveMemoizationDependencies:false function Component(props) { const x = useMemo(() => { switch (props.key) { @@ -27,6 +28,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript +// @validateExhaustiveMemoizationDependencies:false function Component(props) { let t0; bb0: switch (props.key) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-switch-no-fallthrough.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-switch-no-fallthrough.js index 71cea731cab..e2a60ab6baf 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-switch-no-fallthrough.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-switch-no-fallthrough.js @@ -1,3 +1,4 @@ +// @validateExhaustiveMemoizationDependencies:false function Component(props) { const x = useMemo(() => { switch (props.key) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-switch-return.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-switch-return.expect.md index 652e675cfd1..c9001a56374 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-switch-return.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-switch-return.expect.md @@ -2,6 +2,7 @@ ## Input ```javascript +// @validateExhaustiveMemoizationDependencies:false function Component(props) { const x = useMemo(() => { let y; @@ -33,6 +34,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript +// @validateExhaustiveMemoizationDependencies:false function Component(props) { let t0; bb0: { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-switch-return.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-switch-return.js index 481543499bc..a55a487d9b7 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-switch-return.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-switch-return.js @@ -1,3 +1,4 @@ +// @validateExhaustiveMemoizationDependencies:false function Component(props) { const x = useMemo(() => { let y; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-with-optional.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-with-optional.expect.md index 34529a21080..783ad2c12fa 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-with-optional.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-with-optional.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; function Component(props) { return ( @@ -22,7 +22,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false +import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import { useMemo } from "react"; function Component(props) { const $ = _c(2); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-with-optional.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-with-optional.js index 7df73db402f..01a7b6b25e3 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-with-optional.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useMemo-with-optional.js @@ -1,4 +1,4 @@ -// @enablePreserveExistingMemoizationGuarantees:false +// @enablePreserveExistingMemoizationGuarantees:false @validateExhaustiveMemoizationDependencies:false import {useMemo} from 'react'; function Component(props) { return ( From fb18ad3fd372623190a8f74387b79e28151cefc4 Mon Sep 17 00:00:00 2001 From: Joseph Savona <6425824+josephsavona@users.noreply.github.com> Date: Tue, 25 Nov 2025 12:09:09 -0800 Subject: [PATCH 3/4] [compiler] Exhaustive deps: extra tests, improve diagnostic (#35213) First, this adds some more tests and organizes them into an `exhaustive-deps/` subdirectory. Second, the diagnostics are overhauled. For each memo block we now report a single diagnostic which summarizes the issue, plus individual errors for each missing/extra dependency. Within the extra deps, we distinguish whether it's truly extra vs whether its just a more (too) precise version of an inferred dep. For example, if you depend on `x.y.z` but the inferred dep was `x.y`. Finally, we print the full inferred deps at the end as a hint (it's also a suggestion, but this makes it more clear what would be suggested). --- .../src/HIR/HIR.ts | 1 + .../src/Inference/DropManualMemoization.ts | 3 + .../ValidateExhaustiveDependencies.ts | 148 +++++++++---- .../ValidatePreservedManualMemoization.ts | 4 + .../error.invalid-exhaustive-deps.expect.md | 109 ---------- ...ustive-deps-violation-in-effects.expect.md | 0 ...th-exhaustive-deps-violation-in-effects.js | 0 ...invalid-dep-on-ref-current-value.expect.md | 40 ++++ .../error.invalid-dep-on-ref-current-value.js | 10 + ...eps-disallow-unused-stable-types.expect.md | 10 +- ...stive-deps-disallow-unused-stable-types.js | 0 .../error.invalid-exhaustive-deps.expect.md | 204 ++++++++++++++++++ .../error.invalid-exhaustive-deps.js | 0 ...g-nonreactive-dep-inner-function.expect.md | 43 ++++ ...-missing-nonreactive-dep-inner-function.js | 15 ++ ...ssing-nonreactive-dep-unmemoized.expect.md | 43 ++++ ...alid-missing-nonreactive-dep-unmemoized.js | 13 ++ ....invalid-missing-nonreactive-dep.expect.md | 40 ++++ .../error.invalid-missing-nonreactive-dep.js | 10 + ...ror.sketchy-code-exhaustive-deps.expect.md | 6 +- .../error.sketchy-code-exhaustive-deps.js | 0 ...eps-allow-constant-folded-values.expect.md | 0 ...stive-deps-allow-constant-folded-values.js | 0 ...ctive-stable-types-as-extra-deps.expect.md | 0 ...-nonreactive-stable-types-as-extra-deps.js | 0 .../exhaustive-deps.expect.md | 0 .../{ => exhaustive-deps}/exhaustive-deps.js | 0 ...o-unrelated-mutation-in-depslist.expect.md | 6 +- 28 files changed, 545 insertions(+), 160 deletions(-) delete mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-exhaustive-deps.expect.md rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => exhaustive-deps}/compile-files-with-exhaustive-deps-violation-in-effects.expect.md (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => exhaustive-deps}/compile-files-with-exhaustive-deps-violation-in-effects.js (100%) create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-dep-on-ref-current-value.expect.md create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-dep-on-ref-current-value.js rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => exhaustive-deps}/error.invalid-exhaustive-deps-disallow-unused-stable-types.expect.md (68%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => exhaustive-deps}/error.invalid-exhaustive-deps-disallow-unused-stable-types.js (100%) create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-exhaustive-deps.expect.md rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => exhaustive-deps}/error.invalid-exhaustive-deps.js (100%) create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-missing-nonreactive-dep-inner-function.expect.md create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-missing-nonreactive-dep-inner-function.js create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-missing-nonreactive-dep-unmemoized.expect.md create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-missing-nonreactive-dep-unmemoized.js create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-missing-nonreactive-dep.expect.md create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-missing-nonreactive-dep.js rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => exhaustive-deps}/error.sketchy-code-exhaustive-deps.expect.md (78%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => exhaustive-deps}/error.sketchy-code-exhaustive-deps.js (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => exhaustive-deps}/exhaustive-deps-allow-constant-folded-values.expect.md (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => exhaustive-deps}/exhaustive-deps-allow-constant-folded-values.js (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => exhaustive-deps}/exhaustive-deps-allow-nonreactive-stable-types-as-extra-deps.expect.md (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => exhaustive-deps}/exhaustive-deps-allow-nonreactive-stable-types-as-extra-deps.js (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => exhaustive-deps}/exhaustive-deps.expect.md (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => exhaustive-deps}/exhaustive-deps.js (100%) diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts index 9fb360cf8a5..3e4cbb93b44 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts @@ -807,6 +807,7 @@ export type ManualMemoDependency = { } | {kind: 'Global'; identifierName: string}; path: DependencyPath; + loc: SourceLocation; }; export type StartMemoize = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/Inference/DropManualMemoization.ts b/compiler/packages/babel-plugin-react-compiler/src/Inference/DropManualMemoization.ts index 0138e52ef60..647562aee59 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Inference/DropManualMemoization.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Inference/DropManualMemoization.ts @@ -65,6 +65,7 @@ export function collectMaybeMemoDependencies( identifierName: value.binding.name, }, path: [], + loc: value.loc, }; } case 'PropertyLoad': { @@ -74,6 +75,7 @@ export function collectMaybeMemoDependencies( root: object.root, // TODO: determine if the access is optional path: [...object.path, {property: value.property, optional}], + loc: value.loc, }; } break; @@ -95,6 +97,7 @@ export function collectMaybeMemoDependencies( constant: false, }, path: [], + loc: value.place.loc, }; } break; diff --git a/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateExhaustiveDependencies.ts b/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateExhaustiveDependencies.ts index 5035fa9260f..2e6217bb51a 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateExhaustiveDependencies.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateExhaustiveDependencies.ts @@ -241,11 +241,10 @@ export function validateExhaustiveDependencies( matched.add(manualDependency); } } - const isOptionalDependency = - !reactive.has(inferredDependency.identifier.id) && - (isStableType(inferredDependency.identifier) || - isPrimitiveType(inferredDependency.identifier)); - if (hasMatchingManualDependency || isOptionalDependency) { + if ( + hasMatchingManualDependency || + isOptionalDependency(inferredDependency, reactive) + ) { continue; } missing.push(inferredDependency); @@ -274,54 +273,106 @@ export function validateExhaustiveDependencies( } if (missing.length !== 0 || extra.length !== 0) { - let suggestions: Array | null = null; + let suggestion: CompilerSuggestion | null = null; if (startMemo.depsLoc != null && typeof startMemo.depsLoc !== 'symbol') { - suggestions = [ - { - description: 'Update dependencies', - range: [startMemo.depsLoc.start.index, startMemo.depsLoc.end.index], - op: CompilerSuggestionOperation.Replace, - text: `[${inferred.map(printInferredDependency).join(', ')}]`, - }, - ]; + suggestion = { + description: 'Update dependencies', + range: [startMemo.depsLoc.start.index, startMemo.depsLoc.end.index], + op: CompilerSuggestionOperation.Replace, + text: `[${inferred + .filter( + dep => + dep.kind === 'Local' && !isOptionalDependency(dep, reactive), + ) + .map(printInferredDependency) + .join(', ')}]`, + }; } - if (missing.length !== 0) { - const diagnostic = CompilerDiagnostic.create({ - category: ErrorCategory.MemoDependencies, - reason: 'Found missing memoization dependencies', - description: - 'Missing dependencies can cause a value not to update when those inputs change, ' + - 'resulting in stale UI', - suggestions, + const diagnostic = CompilerDiagnostic.create({ + category: ErrorCategory.MemoDependencies, + reason: 'Found missing/extra memoization dependencies', + description: [ + missing.length !== 0 + ? 'Missing dependencies can cause a value to update less often than it should, ' + + 'resulting in stale UI' + : null, + extra.length !== 0 + ? 'Extra dependencies can cause a value to update more often than it should, ' + + 'resulting in performance problems such as excessive renders or effects firing too often' + : null, + ] + .filter(Boolean) + .join('. '), + suggestions: suggestion != null ? [suggestion] : null, + }); + for (const dep of missing) { + let reactiveStableValueHint = ''; + if (isStableType(dep.identifier)) { + reactiveStableValueHint = + '. Refs, setState functions, and other "stable" values generally do not need to be added ' + + 'as dependencies, but this variable may change over time to point to different values'; + } + diagnostic.withDetails({ + kind: 'error', + message: `Missing dependency \`${printInferredDependency(dep)}\`${reactiveStableValueHint}`, + loc: dep.loc, }); - for (const dep of missing) { - let reactiveStableValueHint = ''; - if (isStableType(dep.identifier)) { - reactiveStableValueHint = - '. Refs, setState functions, and other "stable" values generally do not need to be added as dependencies, but this variable may change over time to point to different values'; - } + } + for (const dep of extra) { + if (dep.root.kind === 'Global') { diagnostic.withDetails({ kind: 'error', - message: `Missing dependency \`${printInferredDependency(dep)}\`${reactiveStableValueHint}`, - loc: dep.loc, + message: + `Unnecessary dependency \`${printManualMemoDependency(dep)}\`. ` + + 'Values declared outside of a component/hook should not be listed as ' + + 'dependencies as the component will not re-render if they change', + loc: dep.loc ?? startMemo.depsLoc ?? value.loc, }); + error.pushDiagnostic(diagnostic); + } else { + const root = dep.root.value; + const matchingInferred = inferred.find( + ( + inferredDep, + ): inferredDep is Extract => { + return ( + inferredDep.kind === 'Local' && + inferredDep.identifier.id === root.identifier.id && + isSubPathIgnoringOptionals(inferredDep.path, dep.path) + ); + }, + ); + if ( + matchingInferred != null && + !isOptionalDependency(matchingInferred, reactive) + ) { + diagnostic.withDetails({ + kind: 'error', + message: + `Overly precise dependency \`${printManualMemoDependency(dep)}\`, ` + + `use \`${printInferredDependency(matchingInferred)}\` instead`, + loc: dep.loc ?? startMemo.depsLoc ?? value.loc, + }); + } else { + /** + * Else this dependency doesn't correspond to anything referenced in the memo function, + * or is an optional dependency so we don't want to suggest adding it + */ + diagnostic.withDetails({ + kind: 'error', + message: `Unnecessary dependency \`${printManualMemoDependency(dep)}\``, + loc: dep.loc ?? startMemo.depsLoc ?? value.loc, + }); + } } - error.pushDiagnostic(diagnostic); - } else if (extra.length !== 0) { - const diagnostic = CompilerDiagnostic.create({ - category: ErrorCategory.MemoDependencies, - reason: 'Found unnecessary memoization dependencies', - description: - 'Unnecessary dependencies can cause a value to update more often than necessary, ' + - 'causing performance regressions and effects to fire more often than expected', - }); + } + if (suggestion != null) { diagnostic.withDetails({ - kind: 'error', - message: `Unnecessary dependencies ${extra.map(dep => `\`${printManualMemoDependency(dep)}\``).join(', ')}`, - loc: startMemo.depsLoc ?? value.loc, + kind: 'hint', + message: `Inferred dependencies: \`${suggestion.text}\``, }); - error.pushDiagnostic(diagnostic); } + error.pushDiagnostic(diagnostic); } dependencies.clear(); @@ -826,3 +877,14 @@ export function findOptionalPlaces( } return optionals; } + +function isOptionalDependency( + inferredDependency: Extract, + reactive: Set, +): boolean { + return ( + !reactive.has(inferredDependency.identifier.id) && + (isStableType(inferredDependency.identifier) || + isPrimitiveType(inferredDependency.identifier)) + ); +} diff --git a/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidatePreservedManualMemoization.ts b/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidatePreservedManualMemoization.ts index 48cec3cb122..9b1bf223332 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidatePreservedManualMemoization.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidatePreservedManualMemoization.ts @@ -242,6 +242,7 @@ function validateInferredDep( normalizedDep = { root: maybeNormalizedRoot.root, path: [...maybeNormalizedRoot.path, ...dep.path], + loc: maybeNormalizedRoot.loc, }; } else { CompilerError.invariant(dep.identifier.name?.kind === 'named', { @@ -270,6 +271,7 @@ function validateInferredDep( constant: false, }, path: [...dep.path], + loc: GeneratedSource, }; } for (const decl of declsWithinMemoBlock) { @@ -383,6 +385,7 @@ class Visitor extends ReactiveFunctionVisitor { constant: false, }, path: [], + loc: storeTarget.loc, }); } } @@ -413,6 +416,7 @@ class Visitor extends ReactiveFunctionVisitor { constant: false, }, path: [], + loc: lvalue.loc, }); } } diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-exhaustive-deps.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-exhaustive-deps.expect.md deleted file mode 100644 index ed317be118e..00000000000 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-exhaustive-deps.expect.md +++ /dev/null @@ -1,109 +0,0 @@ - -## Input - -```javascript -// @validateExhaustiveMemoizationDependencies -import {useMemo} from 'react'; -import {Stringify} from 'shared-runtime'; - -function Component({x, y, z}) { - const a = useMemo(() => { - return x?.y.z?.a; - // error: too precise - }, [x?.y.z?.a.b]); - const b = useMemo(() => { - return x.y.z?.a; - // ok, not our job to type check nullability - }, [x.y.z.a]); - const c = useMemo(() => { - return x?.y.z.a?.b; - // error: too precise - }, [x?.y.z.a?.b.z]); - const d = useMemo(() => { - return x?.y?.[(console.log(y), z?.b)]; - // ok - }, [x?.y, y, z?.b]); - const e = useMemo(() => { - const e = []; - e.push(x); - return e; - // ok - }, [x]); - const f = useMemo(() => { - return []; - // error: unnecessary - }, [x, y.z, z?.y?.a, UNUSED_GLOBAL]); - const ref1 = useRef(null); - const ref2 = useRef(null); - const ref = z ? ref1 : ref2; - const cb = useMemo(() => { - return () => { - return ref.current; - }; - // error: ref is a stable type but reactive - }, []); - return ; -} - -``` - - -## Error - -``` -Found 4 errors: - -Error: Found missing memoization dependencies - -Missing dependencies can cause a value not to update when those inputs change, resulting in stale UI. - -error.invalid-exhaustive-deps.ts:7:11 - 5 | function Component({x, y, z}) { - 6 | const a = useMemo(() => { -> 7 | return x?.y.z?.a; - | ^^^^^^^^^ Missing dependency `x?.y.z?.a` - 8 | // error: too precise - 9 | }, [x?.y.z?.a.b]); - 10 | const b = useMemo(() => { - -Error: Found missing memoization dependencies - -Missing dependencies can cause a value not to update when those inputs change, resulting in stale UI. - -error.invalid-exhaustive-deps.ts:15:11 - 13 | }, [x.y.z.a]); - 14 | const c = useMemo(() => { -> 15 | return x?.y.z.a?.b; - | ^^^^^^^^^^^ Missing dependency `x?.y.z.a?.b` - 16 | // error: too precise - 17 | }, [x?.y.z.a?.b.z]); - 18 | const d = useMemo(() => { - -Error: Found unnecessary memoization dependencies - -Unnecessary dependencies can cause a value to update more often than necessary, causing performance regressions and effects to fire more often than expected. - -error.invalid-exhaustive-deps.ts:31:5 - 29 | return []; - 30 | // error: unnecessary -> 31 | }, [x, y.z, z?.y?.a, UNUSED_GLOBAL]); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unnecessary dependencies `x`, `y.z`, `z?.y?.a`, `UNUSED_GLOBAL` - 32 | const ref1 = useRef(null); - 33 | const ref2 = useRef(null); - 34 | const ref = z ? ref1 : ref2; - -Error: Found missing memoization dependencies - -Missing dependencies can cause a value not to update when those inputs change, resulting in stale UI. - -error.invalid-exhaustive-deps.ts:37:13 - 35 | const cb = useMemo(() => { - 36 | return () => { -> 37 | return ref.current; - | ^^^ Missing dependency `ref`. Refs, setState functions, and other "stable" values generally do not need to be added as dependencies, but this variable may change over time to point to different values - 38 | }; - 39 | // error: ref is a stable type but reactive - 40 | }, []); -``` - - \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/compile-files-with-exhaustive-deps-violation-in-effects.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/compile-files-with-exhaustive-deps-violation-in-effects.expect.md similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/compile-files-with-exhaustive-deps-violation-in-effects.expect.md rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/compile-files-with-exhaustive-deps-violation-in-effects.expect.md diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/compile-files-with-exhaustive-deps-violation-in-effects.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/compile-files-with-exhaustive-deps-violation-in-effects.js similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/compile-files-with-exhaustive-deps-violation-in-effects.js rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/compile-files-with-exhaustive-deps-violation-in-effects.js diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-dep-on-ref-current-value.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-dep-on-ref-current-value.expect.md new file mode 100644 index 00000000000..ab9b4080e44 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-dep-on-ref-current-value.expect.md @@ -0,0 +1,40 @@ + +## Input + +```javascript +// @validateExhaustiveMemoizationDependencies + +function Component() { + const ref = useRef(null); + const onChange = useCallback(() => { + return ref.current.value; + }, [ref.current.value]); + + return ; +} + +``` + + +## Error + +``` +Found 1 error: + +Error: Found missing/extra memoization dependencies + +Extra dependencies can cause a value to update more often than it should, resulting in performance problems such as excessive renders or effects firing too often. + +error.invalid-dep-on-ref-current-value.ts:7:6 + 5 | const onChange = useCallback(() => { + 6 | return ref.current.value; +> 7 | }, [ref.current.value]); + | ^^^^^^^^^^^^^^^^^ Unnecessary dependency `ref.current.value` + 8 | + 9 | return ; + 10 | } + +Inferred dependencies: `[]` +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-dep-on-ref-current-value.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-dep-on-ref-current-value.js new file mode 100644 index 00000000000..f7a3ee43503 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-dep-on-ref-current-value.js @@ -0,0 +1,10 @@ +// @validateExhaustiveMemoizationDependencies + +function Component() { + const ref = useRef(null); + const onChange = useCallback(() => { + return ref.current.value; + }, [ref.current.value]); + + return ; +} diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-exhaustive-deps-disallow-unused-stable-types.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-exhaustive-deps-disallow-unused-stable-types.expect.md similarity index 68% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-exhaustive-deps-disallow-unused-stable-types.expect.md rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-exhaustive-deps-disallow-unused-stable-types.expect.md index b6d8a467426..30ab558918d 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-exhaustive-deps-disallow-unused-stable-types.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-exhaustive-deps-disallow-unused-stable-types.expect.md @@ -25,18 +25,20 @@ function Component() { ``` Found 1 error: -Error: Found unnecessary memoization dependencies +Error: Found missing/extra memoization dependencies -Unnecessary dependencies can cause a value to update more often than necessary, causing performance regressions and effects to fire more often than expected. +Extra dependencies can cause a value to update more often than it should, resulting in performance problems such as excessive renders or effects firing too often. -error.invalid-exhaustive-deps-disallow-unused-stable-types.ts:11:5 +error.invalid-exhaustive-deps-disallow-unused-stable-types.ts:11:13 9 | return [state]; 10 | // error: `setState` is a stable type, but not actually referenced > 11 | }, [state, setState]); - | ^^^^^^^^^^^^^^^^^ Unnecessary dependencies `setState` + | ^^^^^^^^ Unnecessary dependency `setState` 12 | 13 | return 'oops'; 14 | } + +Inferred dependencies: `[state]` ``` \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-exhaustive-deps-disallow-unused-stable-types.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-exhaustive-deps-disallow-unused-stable-types.js similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-exhaustive-deps-disallow-unused-stable-types.js rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-exhaustive-deps-disallow-unused-stable-types.js diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-exhaustive-deps.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-exhaustive-deps.expect.md new file mode 100644 index 00000000000..7f94c039039 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-exhaustive-deps.expect.md @@ -0,0 +1,204 @@ + +## Input + +```javascript +// @validateExhaustiveMemoizationDependencies +import {useMemo} from 'react'; +import {Stringify} from 'shared-runtime'; + +function Component({x, y, z}) { + const a = useMemo(() => { + return x?.y.z?.a; + // error: too precise + }, [x?.y.z?.a.b]); + const b = useMemo(() => { + return x.y.z?.a; + // ok, not our job to type check nullability + }, [x.y.z.a]); + const c = useMemo(() => { + return x?.y.z.a?.b; + // error: too precise + }, [x?.y.z.a?.b.z]); + const d = useMemo(() => { + return x?.y?.[(console.log(y), z?.b)]; + // ok + }, [x?.y, y, z?.b]); + const e = useMemo(() => { + const e = []; + e.push(x); + return e; + // ok + }, [x]); + const f = useMemo(() => { + return []; + // error: unnecessary + }, [x, y.z, z?.y?.a, UNUSED_GLOBAL]); + const ref1 = useRef(null); + const ref2 = useRef(null); + const ref = z ? ref1 : ref2; + const cb = useMemo(() => { + return () => { + return ref.current; + }; + // error: ref is a stable type but reactive + }, []); + return ; +} + +``` + + +## Error + +``` +Found 5 errors: + +Error: Found missing/extra memoization dependencies + +Missing dependencies can cause a value to update less often than it should, resulting in stale UI. Extra dependencies can cause a value to update more often than it should, resulting in performance problems such as excessive renders or effects firing too often. + +error.invalid-exhaustive-deps.ts:7:11 + 5 | function Component({x, y, z}) { + 6 | const a = useMemo(() => { +> 7 | return x?.y.z?.a; + | ^^^^^^^^^ Missing dependency `x?.y.z?.a` + 8 | // error: too precise + 9 | }, [x?.y.z?.a.b]); + 10 | const b = useMemo(() => { + +error.invalid-exhaustive-deps.ts:9:6 + 7 | return x?.y.z?.a; + 8 | // error: too precise +> 9 | }, [x?.y.z?.a.b]); + | ^^^^^^^^^^^ Overly precise dependency `x?.y.z?.a.b`, use `x?.y.z?.a` instead + 10 | const b = useMemo(() => { + 11 | return x.y.z?.a; + 12 | // ok, not our job to type check nullability + +Inferred dependencies: `[x?.y.z?.a]` + +Error: Found missing/extra memoization dependencies + +Missing dependencies can cause a value to update less often than it should, resulting in stale UI. Extra dependencies can cause a value to update more often than it should, resulting in performance problems such as excessive renders or effects firing too often. + +error.invalid-exhaustive-deps.ts:15:11 + 13 | }, [x.y.z.a]); + 14 | const c = useMemo(() => { +> 15 | return x?.y.z.a?.b; + | ^^^^^^^^^^^ Missing dependency `x?.y.z.a?.b` + 16 | // error: too precise + 17 | }, [x?.y.z.a?.b.z]); + 18 | const d = useMemo(() => { + +error.invalid-exhaustive-deps.ts:17:6 + 15 | return x?.y.z.a?.b; + 16 | // error: too precise +> 17 | }, [x?.y.z.a?.b.z]); + | ^^^^^^^^^^^^^ Overly precise dependency `x?.y.z.a?.b.z`, use `x?.y.z.a?.b` instead + 18 | const d = useMemo(() => { + 19 | return x?.y?.[(console.log(y), z?.b)]; + 20 | // ok + +Inferred dependencies: `[x?.y.z.a?.b]` + +Error: Found missing/extra memoization dependencies + +Extra dependencies can cause a value to update more often than it should, resulting in performance problems such as excessive renders or effects firing too often. + +error.invalid-exhaustive-deps.ts:31:6 + 29 | return []; + 30 | // error: unnecessary +> 31 | }, [x, y.z, z?.y?.a, UNUSED_GLOBAL]); + | ^ Unnecessary dependency `x` + 32 | const ref1 = useRef(null); + 33 | const ref2 = useRef(null); + 34 | const ref = z ? ref1 : ref2; + +error.invalid-exhaustive-deps.ts:31:9 + 29 | return []; + 30 | // error: unnecessary +> 31 | }, [x, y.z, z?.y?.a, UNUSED_GLOBAL]); + | ^^^ Unnecessary dependency `y.z` + 32 | const ref1 = useRef(null); + 33 | const ref2 = useRef(null); + 34 | const ref = z ? ref1 : ref2; + +error.invalid-exhaustive-deps.ts:31:14 + 29 | return []; + 30 | // error: unnecessary +> 31 | }, [x, y.z, z?.y?.a, UNUSED_GLOBAL]); + | ^^^^^^^ Unnecessary dependency `z?.y?.a` + 32 | const ref1 = useRef(null); + 33 | const ref2 = useRef(null); + 34 | const ref = z ? ref1 : ref2; + +error.invalid-exhaustive-deps.ts:31:23 + 29 | return []; + 30 | // error: unnecessary +> 31 | }, [x, y.z, z?.y?.a, UNUSED_GLOBAL]); + | ^^^^^^^^^^^^^ Unnecessary dependency `UNUSED_GLOBAL`. Values declared outside of a component/hook should not be listed as dependencies as the component will not re-render if they change + 32 | const ref1 = useRef(null); + 33 | const ref2 = useRef(null); + 34 | const ref = z ? ref1 : ref2; + +Inferred dependencies: `[]` + +Error: Found missing/extra memoization dependencies + +Extra dependencies can cause a value to update more often than it should, resulting in performance problems such as excessive renders or effects firing too often. + +error.invalid-exhaustive-deps.ts:31:6 + 29 | return []; + 30 | // error: unnecessary +> 31 | }, [x, y.z, z?.y?.a, UNUSED_GLOBAL]); + | ^ Unnecessary dependency `x` + 32 | const ref1 = useRef(null); + 33 | const ref2 = useRef(null); + 34 | const ref = z ? ref1 : ref2; + +error.invalid-exhaustive-deps.ts:31:9 + 29 | return []; + 30 | // error: unnecessary +> 31 | }, [x, y.z, z?.y?.a, UNUSED_GLOBAL]); + | ^^^ Unnecessary dependency `y.z` + 32 | const ref1 = useRef(null); + 33 | const ref2 = useRef(null); + 34 | const ref = z ? ref1 : ref2; + +error.invalid-exhaustive-deps.ts:31:14 + 29 | return []; + 30 | // error: unnecessary +> 31 | }, [x, y.z, z?.y?.a, UNUSED_GLOBAL]); + | ^^^^^^^ Unnecessary dependency `z?.y?.a` + 32 | const ref1 = useRef(null); + 33 | const ref2 = useRef(null); + 34 | const ref = z ? ref1 : ref2; + +error.invalid-exhaustive-deps.ts:31:23 + 29 | return []; + 30 | // error: unnecessary +> 31 | }, [x, y.z, z?.y?.a, UNUSED_GLOBAL]); + | ^^^^^^^^^^^^^ Unnecessary dependency `UNUSED_GLOBAL`. Values declared outside of a component/hook should not be listed as dependencies as the component will not re-render if they change + 32 | const ref1 = useRef(null); + 33 | const ref2 = useRef(null); + 34 | const ref = z ? ref1 : ref2; + +Inferred dependencies: `[]` + +Error: Found missing/extra memoization dependencies + +Missing dependencies can cause a value to update less often than it should, resulting in stale UI. + +error.invalid-exhaustive-deps.ts:37:13 + 35 | const cb = useMemo(() => { + 36 | return () => { +> 37 | return ref.current; + | ^^^ Missing dependency `ref`. Refs, setState functions, and other "stable" values generally do not need to be added as dependencies, but this variable may change over time to point to different values + 38 | }; + 39 | // error: ref is a stable type but reactive + 40 | }, []); + +Inferred dependencies: `[ref]` +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-exhaustive-deps.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-exhaustive-deps.js similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-exhaustive-deps.js rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-exhaustive-deps.js diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-missing-nonreactive-dep-inner-function.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-missing-nonreactive-dep-inner-function.expect.md new file mode 100644 index 00000000000..6d03fb42351 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-missing-nonreactive-dep-inner-function.expect.md @@ -0,0 +1,43 @@ + +## Input + +```javascript +// @validateExhaustiveMemoizationDependencies + +import {useMemo} from 'react'; +import {makeObject_Primitives} from 'shared-runtime'; + +function useHook() { + const object = makeObject_Primitives(); + const fn = useCallback(() => { + const g = () => { + return [object]; + }; + return g; + }); + return fn; +} + +``` + + +## Error + +``` +Found 1 error: + +Error: Found missing/extra memoization dependencies + +Missing dependencies can cause a value to update less often than it should, resulting in stale UI. + +error.invalid-missing-nonreactive-dep-inner-function.ts:10:14 + 8 | const fn = useCallback(() => { + 9 | const g = () => { +> 10 | return [object]; + | ^^^^^^ Missing dependency `object` + 11 | }; + 12 | return g; + 13 | }); +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-missing-nonreactive-dep-inner-function.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-missing-nonreactive-dep-inner-function.js new file mode 100644 index 00000000000..02ba7b84061 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-missing-nonreactive-dep-inner-function.js @@ -0,0 +1,15 @@ +// @validateExhaustiveMemoizationDependencies + +import {useMemo} from 'react'; +import {makeObject_Primitives} from 'shared-runtime'; + +function useHook() { + const object = makeObject_Primitives(); + const fn = useCallback(() => { + const g = () => { + return [object]; + }; + return g; + }); + return fn; +} diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-missing-nonreactive-dep-unmemoized.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-missing-nonreactive-dep-unmemoized.expect.md new file mode 100644 index 00000000000..a6868ef325c --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-missing-nonreactive-dep-unmemoized.expect.md @@ -0,0 +1,43 @@ + +## Input + +```javascript +// @validateExhaustiveMemoizationDependencies + +import {useMemo} from 'react'; +import {makeObject_Primitives, useIdentity} from 'shared-runtime'; + +function useHook() { + // object is non-reactive but not memoized bc the mutation surrounds a hook + const object = makeObject_Primitives(); + useIdentity(); + object.x = 0; + const array = useMemo(() => [object], []); + return array; +} + +``` + + +## Error + +``` +Found 1 error: + +Error: Found missing/extra memoization dependencies + +Missing dependencies can cause a value to update less often than it should, resulting in stale UI. + +error.invalid-missing-nonreactive-dep-unmemoized.ts:11:31 + 9 | useIdentity(); + 10 | object.x = 0; +> 11 | const array = useMemo(() => [object], []); + | ^^^^^^ Missing dependency `object` + 12 | return array; + 13 | } + 14 | + +Inferred dependencies: `[object]` +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-missing-nonreactive-dep-unmemoized.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-missing-nonreactive-dep-unmemoized.js new file mode 100644 index 00000000000..c790ce1daee --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-missing-nonreactive-dep-unmemoized.js @@ -0,0 +1,13 @@ +// @validateExhaustiveMemoizationDependencies + +import {useMemo} from 'react'; +import {makeObject_Primitives, useIdentity} from 'shared-runtime'; + +function useHook() { + // object is non-reactive but not memoized bc the mutation surrounds a hook + const object = makeObject_Primitives(); + useIdentity(); + object.x = 0; + const array = useMemo(() => [object], []); + return array; +} diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-missing-nonreactive-dep.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-missing-nonreactive-dep.expect.md new file mode 100644 index 00000000000..f3423495097 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-missing-nonreactive-dep.expect.md @@ -0,0 +1,40 @@ + +## Input + +```javascript +// @validateExhaustiveMemoizationDependencies + +import {useMemo} from 'react'; +import {makeObject_Primitives} from 'shared-runtime'; + +function useHook() { + const object = makeObject_Primitives(); + const array = useMemo(() => [object], []); + return array; +} + +``` + + +## Error + +``` +Found 1 error: + +Error: Found missing/extra memoization dependencies + +Missing dependencies can cause a value to update less often than it should, resulting in stale UI. + +error.invalid-missing-nonreactive-dep.ts:8:31 + 6 | function useHook() { + 7 | const object = makeObject_Primitives(); +> 8 | const array = useMemo(() => [object], []); + | ^^^^^^ Missing dependency `object` + 9 | return array; + 10 | } + 11 | + +Inferred dependencies: `[object]` +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-missing-nonreactive-dep.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-missing-nonreactive-dep.js new file mode 100644 index 00000000000..bfc81d9dd5b --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-missing-nonreactive-dep.js @@ -0,0 +1,10 @@ +// @validateExhaustiveMemoizationDependencies + +import {useMemo} from 'react'; +import {makeObject_Primitives} from 'shared-runtime'; + +function useHook() { + const object = makeObject_Primitives(); + const array = useMemo(() => [object], []); + return array; +} diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.sketchy-code-exhaustive-deps.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.sketchy-code-exhaustive-deps.expect.md similarity index 78% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.sketchy-code-exhaustive-deps.expect.md rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.sketchy-code-exhaustive-deps.expect.md index 332fee9f06a..0422a07cd87 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.sketchy-code-exhaustive-deps.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.sketchy-code-exhaustive-deps.expect.md @@ -25,9 +25,9 @@ function Component() { ``` Found 1 error: -Error: Found missing memoization dependencies +Error: Found missing/extra memoization dependencies -Missing dependencies can cause a value not to update when those inputs change, resulting in stale UI. +Missing dependencies can cause a value to update less often than it should, resulting in stale UI. error.sketchy-code-exhaustive-deps.ts:8:16 6 | const foo = useCallback( @@ -37,6 +37,8 @@ error.sketchy-code-exhaustive-deps.ts:8:16 9 | }, // eslint-disable-next-line react-hooks/exhaustive-deps 10 | [] 11 | ); + +Inferred dependencies: `[item]` ``` \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.sketchy-code-exhaustive-deps.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.sketchy-code-exhaustive-deps.js similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.sketchy-code-exhaustive-deps.js rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.sketchy-code-exhaustive-deps.js diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps-allow-constant-folded-values.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/exhaustive-deps-allow-constant-folded-values.expect.md similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps-allow-constant-folded-values.expect.md rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/exhaustive-deps-allow-constant-folded-values.expect.md diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps-allow-constant-folded-values.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/exhaustive-deps-allow-constant-folded-values.js similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps-allow-constant-folded-values.js rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/exhaustive-deps-allow-constant-folded-values.js diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps-allow-nonreactive-stable-types-as-extra-deps.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/exhaustive-deps-allow-nonreactive-stable-types-as-extra-deps.expect.md similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps-allow-nonreactive-stable-types-as-extra-deps.expect.md rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/exhaustive-deps-allow-nonreactive-stable-types-as-extra-deps.expect.md diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps-allow-nonreactive-stable-types-as-extra-deps.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/exhaustive-deps-allow-nonreactive-stable-types-as-extra-deps.js similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps-allow-nonreactive-stable-types-as-extra-deps.js rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/exhaustive-deps-allow-nonreactive-stable-types-as-extra-deps.js diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/exhaustive-deps.expect.md similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps.expect.md rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/exhaustive-deps.expect.md diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/exhaustive-deps.js similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps.js rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/exhaustive-deps.js diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-unrelated-mutation-in-depslist.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-unrelated-mutation-in-depslist.expect.md index 7d2125259ae..7831aeac15d 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-unrelated-mutation-in-depslist.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-unrelated-mutation-in-depslist.expect.md @@ -32,9 +32,9 @@ function useFoo(input1) { ``` Found 1 error: -Error: Found missing memoization dependencies +Error: Found missing/extra memoization dependencies -Missing dependencies can cause a value not to update when those inputs change, resulting in stale UI. +Missing dependencies can cause a value to update less often than it should, resulting in stale UI. error.useMemo-unrelated-mutation-in-depslist.ts:18:14 16 | const memoized = useMemo(() => { @@ -44,6 +44,8 @@ error.useMemo-unrelated-mutation-in-depslist.ts:18:14 19 | 20 | return [x, memoized]; 21 | } + +Inferred dependencies: `[x, y]` ``` \ No newline at end of file From 627b583650078514eff22498514682a8522282b1 Mon Sep 17 00:00:00 2001 From: Joseph Savona <6425824+josephsavona@users.noreply.github.com> Date: Tue, 25 Nov 2025 15:39:07 -0800 Subject: [PATCH 4/4] [compiler][snap] Fix for filter mode with nested files, 'error.' prefix (#35215) Fixes some issues i ran into w my recent snap changes: * Correctly match against patterns that contain subdirectories, eg `fbt/fbt-call` * When checking if the input pattern has an extension, only prune known supported extensions. Our convention of `error.` for fixtures that error makes the rest of the test name look like an extension to `path.extname()`. Tested with lots of different patterns including `error.` examples at the top level and in nested directories, etc. --- compiler/packages/snap/src/fixture-utils.ts | 30 +++++++-------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/compiler/packages/snap/src/fixture-utils.ts b/compiler/packages/snap/src/fixture-utils.ts index ebf6a34e1db..fae6afef151 100644 --- a/compiler/packages/snap/src/fixture-utils.ts +++ b/compiler/packages/snap/src/fixture-utils.ts @@ -44,21 +44,6 @@ function stripExtension(filename: string, extensions: Array): string { return filename; } -/** - * Strip all extensions from a filename - * e.g., "foo.expect.md" -> "foo" - */ -function stripAllExtensions(filename: string): string { - let result = filename; - while (true) { - const extension = path.extname(result); - if (extension === '') { - return result; - } - result = path.basename(result, extension); - } -} - export async function readTestFilter(): Promise { if (!(await exists(FILTER_PATH))) { throw new Error(`testfilter file not found at \`${FILTER_PATH}\``); @@ -134,13 +119,15 @@ async function readInputFixtures( // `alias-while` => search for `alias-while{.js,.jsx,.ts,.tsx}` // `alias-while.js` => search as-is // `alias-while.expect.md` => search for `alias-while{.js,.jsx,.ts,.tsx}` - const basename = path.basename(pattern); - const basenameWithoutExt = stripAllExtensions(basename); - const hasExtension = basename !== basenameWithoutExt; + const patternWithoutExt = stripExtension(pattern, [ + ...INPUT_EXTENSIONS, + SNAPSHOT_EXTENSION, + ]); + const hasExtension = pattern !== patternWithoutExt; const globPattern = hasExtension && !pattern.endsWith(SNAPSHOT_EXTENSION) ? pattern - : `${basenameWithoutExt}{${INPUT_EXTENSIONS.join(',')}}`; + : `${patternWithoutExt}{${INPUT_EXTENSIONS.join(',')}}`; return glob.glob(globPattern, { cwd: rootDir, }); @@ -181,7 +168,10 @@ async function readOutputFixtures( await Promise.all( filter.paths.map(pattern => { // Strip all extensions and find matching .expect.md files - const basenameWithoutExt = stripAllExtensions(pattern); + const basenameWithoutExt = stripExtension(pattern, [ + ...INPUT_EXTENSIONS, + SNAPSHOT_EXTENSION, + ]); return glob.glob(`${basenameWithoutExt}${SNAPSHOT_EXTENSION}`, { cwd: rootDir, });