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 55bcd0bc5ce8..9fb360cf8a5a 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 bcfc53413ab4..0138e52ef60e 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 ca2f6e00a5d0..7330b63ddce4 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 b3a68fc0134b..5035fa9260f0 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 19af0ed08014..48cec3cb1220 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 407fdcb0488f..636bc53a172e 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 5ed1a9157bdf..49cf3364b1c4 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 000000000000..b6d8a4674267 --- /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 000000000000..2bb03c366113 --- /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 000000000000..bda2b0356250 --- /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 000000000000..6ee141cb3ae0 --- /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 cf36d6ed6730..f23cf84e504f 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 b0c013952692..bfbc0ab5056a 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 43b3b599e198..16169a74d716 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 662162ed6440..e9d11525e2c2 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 92bfe913d7e9..fc5ba4038170 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 e9475a070b88..8a3d0fac9637 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 5bdeeaee1a8e..9f0653d9d382 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 9994a6536f41..c3bc1d162385 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 888bdbcb8b93..686e87440776 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 ce8e7b422329..8c2b57cbad5f 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 6b005c0e0461..9448a284dd63 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 ed9f73a01637..df3524de027e 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 331e551596b7..b9344d663b90 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 be22558e3c71..c41500965080 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 861dd92cf55c..682c81191109 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 9b7883f61722..a812cfac3ad6 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 2388488eb9e3..d08f3f2f6f4a 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 22e2f41f7999..2558d10d19cb 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 71c133b0edcf..60ab46e4eb47 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 fbde27f77e62..2c2f725ec84b 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 bd67fe2a9d15..f0e0b584e9fc 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 92c0d5ab1a09..332fee9f06af 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 ebfb84375e2e..3739c0cc8412 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 2e95c6378970..ea2842d0b387 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 a08b1708fcd5..c8dd66f67f1c 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 be31341d15d2..618e1fb2883b 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 c71723f4964f..a59fda33df06 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 0ead4d68f582..4257f9b6047d 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 16af7ef85d15..bcc2fba97880 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 1524de192d79..301eee10da05 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 9130f13c15c7..c5fcdf146edf 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 4c5461f6f343..535f98e574f3 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 ceddbefdd1b7..381c2d4c5657 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 32d454712f39..c5cfff1cf714 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 6cb2e44a2b46..6d0546289c28 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 c6737d78a1b6..44e70351691b 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 d70bd138113a..8095a7af8f13 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 98128b1e506f..e7b0fe8e75ee 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 3190c0e7c7c4..2ac414570d8d 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 012aec12b366..a392cb1137f9 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 a542514109ea..33ba3a106ff1 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 eec95683aa2a..25e4a3843cf3 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 dbcb7303778c..bd2548f672b1 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 53a99470a924..92e1a1c3b8ec 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 5d61126ee978..c40d192468eb 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 9cb71732a099..0f7eebb877c4 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 1e997906428f..ada8679f2510 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 81c53c901679..5a3388fd8e83 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 cb282549f068..a4a2279810cc 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 a51aaf5367ce..9885ef17c104 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 6d2f17853163..f343cc2afa27 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 fd7f2b0cda05..4222c0dfe2cb 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 03ca2ef583ae..ece6a2dc1351 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 6c45eb8bfaf8..a9f6e8805f3f 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 f360a8213259..861c413386df 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 f29be3d405b4..4a65f8a4e291 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 061af52723e0..01a87a225998 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 ce3e3734e98c..2d3f46998661 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 7c4daae371f1..7b9c6e54da75 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 3eb8e6cb2623..ca650005c797 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 8238e1b74d0e..826e79f526da 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 f742006ea12b..9d45c500d28b 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 b6f64482a25e..98c697d22084 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 506a20792e90..ba1cc7e545e2 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 f87c68f9f1ce..0c1f02778c60 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 11a7de33481a..7c1539a8cd80 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 e61c721034b3..31baea97a4f3 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 00cc3fb83958..6b707f3fe3bb 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 9c5b851ab6e4..5bd9603c49db 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 1c86ef5a927f..293b35629ffd 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 658c20f810cd..6109e8033ac7 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 8ed05bcaf401..7d2125259ae8 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 9d02bff8b4c0..7bb7de6ea2a0 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 1bf54a5aa537..1513065f2cf0 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 3f1607a4f302..cccbe2d31f28 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 ab60de9a0ebc..78dfa1e658c5 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 a046c76b0477..87cd57e917ed 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 1e8b509551a7..0f8836d2030b 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 6d9183915467..0eb58ef85e06 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 825df4ce0850..640b9b8b9e6b 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 db5ff86ed235..1b94677c78d4 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 698fbeb2ca05..9831fcfdec99 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 448c2133301a..78a7b36eba69 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 d5d36490dfbb..170593c486a6 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 f139b540b387..81d7a48aa750 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 0e640f130d3d..5cabcdf7676d 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 85a27553d711..d20b74d04b60 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 619f8129451b..7602807972d3 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 27dbb57698ae..11025151911b 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 6522bdae9d36..2ca2e7c71556 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 2a805aa77757..3d146ba3e616 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 7037e9ee3d21..3565dfd39b9f 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 58b2c9762b29..7af90abc7b85 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 673380de119c..9838cd9456d6 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 d208ce4fb74d..735120f90009 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 eae6a75854e0..673493c313b5 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 bb0518c25fdf..3a8a7393f511 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 917f7b75ab77..05799ccfa3b6 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 1d4761e447b2..bd8c1b994e16 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 7075ecaac53c..81794651893a 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 6cf8820e9844..1b8f59e45e85 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 aa43a8d18867..a4baa811b5f1 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 9ca367e8a8ea..19102267cc19 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 de3026e4e587..0a4bbac2e080 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 2a419a6415d6..a55ca6e37139 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 a3e2bab77e24..98308be1f820 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 6eb085435ddd..da6b14a0c97f 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 132fcb30a2b4..89b87f2d591b 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 a1d176728d20..ea6e43029ce9 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 6c8405d0d190..c0984e32193d 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 25edfe4e6506..40642ebb2d5d 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 a39f3b2826e4..ba5ab1cb2f46 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 479b1b2c8230..c433cd2dfca8 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 4f9f5f39c148..a557a2781977 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 6a0ba2926506..87784e39841d 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 ca3c838d88af..baecabc252bc 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 dda4a25e9f0e..e47257406247 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 242a19838264..85c63f7470cf 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 f944aa454d88..aa195e650a64 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 a432c27d9b25..1f05ae7d6a36 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 8b4de101cacc..b7f36a1aa9f4 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 e1a766e99a30..316174846642 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 bf110b75dc83..cb6282de2919 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 dab1cefd0c60..b51cc5fb5f18 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 e0525518c968..0d265a7c2965 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 d122dcc7a3e7..02890978ad19 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 296589b6eb5c..8f1d7a7e0653 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 71cea731cab5..e2a60ab6baf1 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 652e675cfd15..c9001a563746 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 481543499bc8..a55a487d9b7f 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 34529a210808..783ad2c12fab 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 7df73db402f8..01a7b6b25e3f 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 9fb360cf8a5a..3e4cbb93b444 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 0138e52ef60e..647562aee591 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 5035fa9260f0..2e6217bb51a5 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 48cec3cb1220..9b1bf223332c 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 ed317be118e1..000000000000 --- 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 000000000000..ab9b4080e44b --- /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 000000000000..f7a3ee43503a --- /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 b6d8a4674267..30ab558918dd 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 000000000000..7f94c0390397 --- /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 000000000000..6d03fb423511 --- /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 000000000000..02ba7b840614 --- /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 000000000000..a6868ef325c3 --- /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 000000000000..c790ce1daee2 --- /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 000000000000..f3423495097d --- /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 000000000000..bfc81d9dd5bd --- /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 332fee9f06af..0422a07cd87c 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 7d2125259ae8..7831aeac15d9 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 ebf6a34e1dbc..fae6afef1519 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, });