From b3f9a2dffd218d60c48c7f21e7081daadbad0632 Mon Sep 17 00:00:00 2001 From: Carson McManus Date: Fri, 31 May 2024 08:59:34 -0400 Subject: [PATCH 1/2] fix(lint/useJsxKeyInIterable): fix a false positive when key is in the return statement, but not any variable declarations --- .../correctness/use_jsx_key_in_iterable.rs | 22 +++++++++++++++++++ .../correctness/useJsxKeyInIterable/valid.jsx | 5 +++++ .../useJsxKeyInIterable/valid.jsx.snap | 5 +++++ 3 files changed, 32 insertions(+) diff --git a/crates/biome_js_analyze/src/lint/correctness/use_jsx_key_in_iterable.rs b/crates/biome_js_analyze/src/lint/correctness/use_jsx_key_in_iterable.rs index fa6d61a509cc..276baac0730e 100644 --- a/crates/biome_js_analyze/src/lint/correctness/use_jsx_key_in_iterable.rs +++ b/crates/biome_js_analyze/src/lint/correctness/use_jsx_key_in_iterable.rs @@ -184,6 +184,28 @@ fn handle_function_body( model: &SemanticModel, is_inside_jsx: bool, ) -> Vec { + // if the return statement definitely has a key prop, don't need to check the rest of the function + let return_statement = node + .statements() + .iter() + .find_map(|statement| statement.as_js_return_statement().cloned()); + let is_return_component = return_statement + .as_ref() + .and_then(|ret| { + let returned_value = ret.argument()?; + Some(ReactComponentExpression::can_cast( + returned_value.syntax().kind(), + )) + }) + .unwrap_or(false); + let ranges = return_statement.and_then(|ret| { + let returned_value = ret.argument()?; + handle_potential_react_component(returned_value, model, is_inside_jsx) + }); + if ranges.is_none() && is_return_component { + return vec![]; + } + node.statements() .iter() .filter_map(|statement| { diff --git a/crates/biome_js_analyze/tests/specs/correctness/useJsxKeyInIterable/valid.jsx b/crates/biome_js_analyze/tests/specs/correctness/useJsxKeyInIterable/valid.jsx index 8d7a218714e0..e1953f741ba7 100644 --- a/crates/biome_js_analyze/tests/specs/correctness/useJsxKeyInIterable/valid.jsx +++ b/crates/biome_js_analyze/tests/specs/correctness/useJsxKeyInIterable/valid.jsx @@ -91,3 +91,8 @@ React.Children.map(c => React.cloneElement(c, {key: c})); const div =
{x}
; return div; }); + +[].map((item) => { + const node = ; + return {node}; +}) diff --git a/crates/biome_js_analyze/tests/specs/correctness/useJsxKeyInIterable/valid.jsx.snap b/crates/biome_js_analyze/tests/specs/correctness/useJsxKeyInIterable/valid.jsx.snap index 7d3ab368c072..640a37a6a66a 100644 --- a/crates/biome_js_analyze/tests/specs/correctness/useJsxKeyInIterable/valid.jsx.snap +++ b/crates/biome_js_analyze/tests/specs/correctness/useJsxKeyInIterable/valid.jsx.snap @@ -98,4 +98,9 @@ React.Children.map(c => React.cloneElement(c, {key: c})); return div; }); +[].map((item) => { + const node = ; + return {node}; +}) + ``` From 9f2def5f2d789cdded87f721e8e05a141fbef2c2 Mon Sep 17 00:00:00 2001 From: Carson McManus Date: Fri, 31 May 2024 20:04:02 -0400 Subject: [PATCH 2/2] Update crates/biome_js_analyze/src/lint/correctness/use_jsx_key_in_iterable.rs Co-authored-by: Emanuele Stoppa --- .../src/lint/correctness/use_jsx_key_in_iterable.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/biome_js_analyze/src/lint/correctness/use_jsx_key_in_iterable.rs b/crates/biome_js_analyze/src/lint/correctness/use_jsx_key_in_iterable.rs index 276baac0730e..821919f1f9f9 100644 --- a/crates/biome_js_analyze/src/lint/correctness/use_jsx_key_in_iterable.rs +++ b/crates/biome_js_analyze/src/lint/correctness/use_jsx_key_in_iterable.rs @@ -197,7 +197,7 @@ fn handle_function_body( returned_value.syntax().kind(), )) }) - .unwrap_or(false); + .unwrap_or_default(); let ranges = return_statement.and_then(|ret| { let returned_value = ret.argument()?; handle_potential_react_component(returned_value, model, is_inside_jsx)