From 26af302fc4717c47a35b2079ac7397ab3f031c4e Mon Sep 17 00:00:00 2001 From: camc314 <18101008+camc314@users.noreply.github.com> Date: Tue, 16 Sep 2025 10:23:56 +0000 Subject: [PATCH] fix(linter/exhaustive-deps): check stable value is on lhs of assignment expr (#13815) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit we were not checking that the value was assigned to just that it’s parent was an assignment expression --- .../oxc_linter/src/rules/react/exhaustive_deps.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/crates/oxc_linter/src/rules/react/exhaustive_deps.rs b/crates/oxc_linter/src/rules/react/exhaustive_deps.rs index 940e0b5961ef6..a62578ccd8df1 100644 --- a/crates/oxc_linter/src/rules/react/exhaustive_deps.rs +++ b/crates/oxc_linter/src/rules/react/exhaustive_deps.rs @@ -1074,10 +1074,15 @@ fn is_stable_value<'a, 'b>( ctx.scoping().get_reference(ident_reference_id).symbol_id().unwrap(), ) .any(|reference| { - matches!( - ctx.nodes().parent_kind(reference.node_id()), - AstKind::AssignmentExpression(_) - ) + if let AstKind::AssignmentExpression(assignment_expression) = + ctx.nodes().parent_kind(reference.node_id()) + { + assignment_expression.left.span().contains_inclusive( + ctx.nodes().get_node(reference.node_id()).span(), + ) + } else { + false + } }) { return true; @@ -2600,6 +2605,7 @@ fn test() { r"function MyComponent(props) { useEffect(() => { console.log((props.foo).bar) }, [props.foo!.bar]) }", r"function MyComponent(props) { const external = {}; const y = useMemo(() => { const z = foo(); return z; }, []) }", r#"function Test() { const [state, setState] = useState(); useEffect(() => { console.log("state", state); }); }"#, + "function Test() { const [foo, setFoo] = useState(true); _setFoo = setFoo; useEffect(() => { setFoo(false) }, []); }", ]; let fail = vec![