Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@matanshavit
Copy link
Contributor

@matanshavit matanshavit commented Nov 3, 2025

Summary

Addresses comments on #7926, which was merged before all comments were addressed.
This should be a refactor only, not change any behavior.

AI assistance notice

I use Claude Code to write most of the code and comments in this pull request. As the human author, I take full responsibility for its contents

Test Plan

Existing unit and snapshot tests pass. No behavior should be changed.

Docs

  • added docstrings to helper functions
  • Corrected incorrect, misleading, and unneeded comments

@changeset-bot
Copy link

changeset-bot bot commented Nov 3, 2025

⚠️ No Changeset found

Latest commit: f15e426

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions github-actions bot added A-Linter Area: linter L-JavaScript Language: JavaScript and super languages labels Nov 3, 2025
@matanshavit matanshavit changed the title refactor(lint): NoParametersOnlyUsedInRecursion refactor(lint): refactor NoParametersOnlyUsedInRecursion Nov 3, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 3, 2025

Walkthrough

This change refactors the no_parameters_only_used_in_recursion lint to use Option-based propagation across helpers. get_function_name now returns Option and callers use ?; helpers like is_recursive_call, is_reference_in_recursive_call, traces_to_parameter and is_recursive_call_with_param_usage return Option<bool> to represent indeterminate paths. Arrow-function name extraction uses AnyFunctionLike and traversal stops at explicit function boundaries. References are iterated directly via binding.all_references(model) instead of pre-collecting. Function-signature and boundary checks were extended to cover TypeScript signature constructs. Diagnostic generation and fixes are preserved.

Possibly related PRs

Suggested labels

A-Diagnostic

Suggested reviewers

  • dyc3

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarises the main change: a refactor of the NoParametersOnlyUsedInRecursion linting rule, which is the sole file modified in the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description check ✅ Passed The description clearly relates to the changeset, explaining this is a refactor addressing prior PR comments with no behaviour changes.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Member

@ematipico ematipico left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for addressing my comments

// Stop searching if we hit a function boundary
// (prevents extracting wrong name from outer scope)
if is_function_like(&ancestor) {
if AnyFunctionLike::cast_ref(&ancestor).is_some() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use can_cast(ancestor.kind())

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, changed

/// Checks if a call expression is a recursive call to the current function.
/// Handles direct calls (`foo()`), method calls (`this.foo()`), and computed members (`this["foo"]()`).
/// Uses a conservative approach to avoid false positives.
fn is_recursive_call(call: &JsCallExpression, function_name: &TokenText) -> bool {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should return Option<bool>, so you can simplify a lot the internal code by removing let-else chain and using the try operator

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand, this is like the other functions that should return Option. Changed.

@codspeed-hq
Copy link

codspeed-hq bot commented Nov 3, 2025

CodSpeed Performance Report

Merging #7970 will not alter performance

Comparing matanshavit:refactor/no-parameters-only-used-in-recursion (f15e426) with main (f102661)

Summary

✅ 58 untouched
⏩ 95 skipped1

Footnotes

  1. 95 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs (1)

475-479: Inconsistent error handling for static member expressions.

Lines 444–469 use .ok()? to propagate None if a sub-expression is unavailable, but lines 475–479 use if let Ok(obj), which silently skips the object if it can't be retrieved. This inconsistency means that a malformed member expression is treated differently from other malformed expressions.

Apply this diff for consistency:

-        if let Some(member_expr) = current_expr.as_js_static_member_expression()
-            && let Ok(obj) = member_expr.object()
-        {
+        if let Some(member_expr) = current_expr.as_js_static_member_expression() {
+            to_check.push(member_expr.object().ok()?);
-            to_check.push(obj);
+            continue;
         }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ae360b4 and 3c16f5d.

📒 Files selected for processing (1)
  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs (13 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{rs,toml}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format Rust and TOML files before committing (e.g., via just f)

Files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Document rules, assists, and their options with inline rustdoc in the Rust source

Files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
🧠 Learnings (20)
📓 Common learnings
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : Prefer transforming Result to Option with .ok()? inside run when Signals is Option, and use let-else when Signals is a Vec/collection
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : Avoid deep indentation by using combinators (map, filter, and_then) rather than nested if-let/unwrap chains
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:23:33.055Z
Learning: Applies to crates/biome_js_type_info/src/{type_info,local_inference,resolver,flattening}.rs : Avoid recursive type structures and cross-module Arcs; represent links between types using TypeReference and TypeData::Reference.
📚 Learning: 2025-10-15T09:23:33.055Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:23:33.055Z
Learning: Applies to crates/biome_js_type_info/src/{type_info,local_inference,resolver,flattening}.rs : Avoid recursive type structures and cross-module Arcs; represent links between types using TypeReference and TypeData::Reference.

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : Avoid deep indentation by using combinators (map, filter, and_then) rather than nested if-let/unwrap chains

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : Prefer conventional naming families when applicable: use<Framework>..., noConstant<Concept>, noDuplicate<Concept>, noEmpty<Concept>, noExcessive<Concept>, noRedundant<Concept>, noUnused<Concept>, noUseless<Concept>, noInvalid<Concept>, useValid<Concept>, noUnknown<Concept>, noMisleading<Concept>, noRestricted<Concept>, noUndeclared<Concept>, noUnsafe<Concept>, useConsistent<Concept>, useShorthand<Concept>

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : Prefer transforming Result to Option with .ok()? inside run when Signals is Option, and use let-else when Signals is a Vec/collection

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : For cross-file analyses, use custom visitors/Queryable to emit matches during main traversal to avoid redundant passes

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/lint/nursery/**/*.rs : Place all new rules in the nursery group

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : When banning globals (e.g., console), check semantic model to avoid flagging locally shadowed variables

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : Use options/full_options/use_options code block modifiers as specified to demonstrate configuration in docs; keep modifier order consistent

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : Avoid avoidable string allocations; compare against &str or TokenText rather than allocating Strings

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : Provide informative diagnostics: explain what the error is, why it triggers, and what to do (prefer a code action or a note)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-09-12T08:06:16.650Z
Learnt from: ematipico
Repo: biomejs/biome PR: 7410
File: crates/biome_js_analyze/src/lint/nursery/no_jsx_props_bind.rs:103-149
Timestamp: 2025-09-12T08:06:16.650Z
Learning: In Biome AST traversal, `ancestors().skip(1)` is a reasonable pattern to skip the current node and prevent false positives when searching for ancestor nodes of the same kind.

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Import and use the `FormatNode` trait for AST nodes

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Do not attempt to fix code; if a mandatory token/node is missing, return `None` instead

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:23:33.055Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:23:33.055Z
Learning: Applies to crates/biome_js_type_info/biome_module_graph/src/js_module_info/collector.rs : Thin (module-level) inference should resolve local and global bindings to TypeReference::Resolved, mark imported bindings as TypeReference::Import, and fall back to TypeReference::Unknown if unresolved.

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : When a token is mandatory and present in the AST, use the AST-provided token (e.g., `node.l_paren_token().format()`) instead of emitting a static token

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Use `dbg_write!` to debug and inspect the emitted IR during formatting

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:23:33.055Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:23:33.055Z
Learning: Applies to crates/biome_js_type_info/biome_module_graph/src/js_module_info/scoped_resolver.rs : Full inference must resolve TypeReference::Import across modules to TypeReference::Resolved when the target is available in the module graph.

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Implement the `Format` trait for your node type and use `JsFormatter` with `write!`/`format_args!` to define formatting

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/**/*.rs : After generation, remove usages of `format_verbatim_node` and implement real formatting with biome_formatter utilities

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: autofix
  • GitHub Check: Documentation
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Check Dependencies
  • GitHub Check: Test Node.js API
🔇 Additional comments (6)
crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs (6)

7-7: LGTM! Necessary imports for the refactor.

The new imports support on-the-fly reference iteration and function boundary detection using AnyFunctionLike.

Also applies to: 10-10


131-144: LGTM! Conservative handling of indeterminate cases.

The .unwrap_or(false) on line 138 treats indeterminate results as "not in recursion", which is appropriately conservative for a lint rule.


257-257: LGTM! Correct use of skip(1) to avoid checking the current node.

Based on learnings.


284-284: LGTM! Using AnyFunctionLike::can_cast as requested.

This addresses the maintainer's feedback from the previous review.


503-519: Conservative argument checking is appropriate.

Line 506's .ok()? means that if any argument can't be parsed, the entire function returns None (indeterminate), rather than checking remaining arguments. This is conservative but appropriate for a lint rule—better to miss flagging some cases than to flag incorrectly.


292-293: LGTM! Clearer documentation.

The updated doc comment better describes the function's purpose.

Comment on lines 324 to 328
return ref_id
.name()
.ok()
.is_some_and(|n| n.text() == function_name.text());
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify text comparison consistency.

Lines 327 and 370 use n.text() and text.text() to compare with function_name.text(), whilst line 346 uses t.text_trimmed(). Since function_name is obtained via text_trimmed() (line 219), ensure consistent comparison semantics across all branches. If the tokens can have different whitespace, the comparisons might not be equivalent.

Run this script to check how function names are extracted and compared:

Also applies to: 346-347, 370-370


🏁 Script executed:

#!/bin/bash
# Check all usages of text() vs text_trimmed() in token comparisons
rg -n "text\(\)|text_trimmed\(\)" -A 2 -B 2 --type rust crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs

Length of output: 2791


Standardise text comparison across all branches.

The grep results confirm the inconsistency. Line 346 correctly uses text_trimmed() to match function_name (derived from token_text_trimmed()), whilst lines 327 and 370 use text() instead. Update lines 327 and 370 to use text_trimmed() for consistent trimmed-to-trimmed comparisons.

🤖 Prompt for AI Agents
crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
around lines 324-328 (and also update the occurrence at line 370): the code
currently compares token texts using ref_id.name().ok().is_some_and(|n| n.text()
== function_name.text()) (and another at line 370); change those comparisons to
use text_trimmed() on both sides (e.g., n.text_trimmed() ==
function_name.text_trimmed()) so that all branches perform trimmed-to-trimmed
comparisons consistently.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these should actually be different, the way they currently are, that trimming isn't necessary here and we should just directly compare to the token. I suggest we reject this comment and keep the code change a refactor, not a functional change.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that trimming isn't necessary here and we should just directly compare to the token

I'm not sure what you mean, but the bot is onto something. Trivia are attached to tokens, so whitespaces and comments actually can interfere

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh ok, that does make sense then. I was looking at function_name and kept thinking it is already trimmed. But that is the exact issue if the left expression is not trimmed.

I made the change to line 323, but on line 355, inner_string_text already uses token_text_trimmed, so I just added a comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the confusion I had is the function_name is already trimmed when generated, let me try to make the code clearer

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok changed. How about we just compare instances of TokenText instead of trying to get the strong text to compare?
example:

name.token_text_trimmed() == *function_name

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that should work 👍

@matanshavit matanshavit requested a review from ematipico November 3, 2025 16:47
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs (1)

315-359: Text comparison inconsistency remains unresolved.

As flagged in previous reviews, lines 323 and 338 compare text_trimmed() with function_name.text(), whilst function_name is derived from token_text_trimmed(). Since trivia (whitespace/comments) attach to tokens, using text() instead of text_trimmed() can cause the comparison to fail incorrectly.

Apply this diff to ensure consistent trimmed-to-trimmed comparisons:

-        return Some(name.text_trimmed() == function_name.text());
+        return Some(name.text_trimmed() == function_name.text_trimmed());

And at line 338:

-        return Some(token.text_trimmed() == function_name.text());
+        return Some(token.text_trimmed() == function_name.text_trimmed());
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d837268 and 0a5bcd7.

📒 Files selected for processing (1)
  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs (10 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{rs,toml}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format Rust and TOML files before committing (e.g., via just f)

Files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Document rules, assists, and their options with inline rustdoc in the Rust source

Files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
🧠 Learnings (12)
📓 Common learnings
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:23:33.055Z
Learning: Applies to crates/biome_js_type_info/src/{type_info,local_inference,resolver,flattening}.rs : Avoid recursive type structures and cross-module Arcs; represent links between types using TypeReference and TypeData::Reference.
📚 Learning: 2025-10-15T09:23:33.055Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:23:33.055Z
Learning: Applies to crates/biome_js_type_info/src/{type_info,local_inference,resolver,flattening}.rs : Avoid recursive type structures and cross-module Arcs; represent links between types using TypeReference and TypeData::Reference.

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:23:33.055Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:23:33.055Z
Learning: Applies to crates/biome_js_type_info/biome_module_graph/src/js_module_info/collector.rs : Thin (module-level) inference should resolve local and global bindings to TypeReference::Resolved, mark imported bindings as TypeReference::Import, and fall back to TypeReference::Unknown if unresolved.

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-09-12T08:06:16.650Z
Learnt from: ematipico
Repo: biomejs/biome PR: 7410
File: crates/biome_js_analyze/src/lint/nursery/no_jsx_props_bind.rs:103-149
Timestamp: 2025-09-12T08:06:16.650Z
Learning: In Biome AST traversal, `ancestors().skip(1)` is a reasonable pattern to skip the current node and prevent false positives when searching for ancestor nodes of the same kind.

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Import and use the `FormatNode` trait for AST nodes

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Do not attempt to fix code; if a mandatory token/node is missing, return `None` instead

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : When a token is mandatory and present in the AST, use the AST-provided token (e.g., `node.l_paren_token().format()`) instead of emitting a static token

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Use `dbg_write!` to debug and inspect the emitted IR during formatting

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:23:33.055Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:23:33.055Z
Learning: Applies to crates/biome_js_type_info/biome_module_graph/src/js_module_info/scoped_resolver.rs : Full inference must resolve TypeReference::Import across modules to TypeReference::Resolved when the target is available in the module graph.

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Implement the `Format` trait for your node type and use `JsFormatter` with `write!`/`format_args!` to define formatting

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/**/*.rs : After generation, remove usages of `format_verbatim_node` and implement real formatting with biome_formatter utilities

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : For non-mandatory tokens, use the provided helper constructors (e.g., `token`, `space_token`, `dynamic_token`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: Documentation
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Test Node.js API
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Check Dependencies
  • GitHub Check: autofix
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_js_analyze)
🔇 Additional comments (6)
crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs (6)

7-7: LGTM!

The additional imports support the Option-based refactoring and improved function boundary detection.

Also applies to: 10-10


131-144: Good refactor to on-the-fly iteration.

The change from pre-collecting all references to iterating directly is cleaner, and using unwrap_or(false) provides a sensible conservative fallback for indeterminate cases.


257-257: LGTM! Proper ancestor traversal pattern.

The skip(1) pattern correctly skips the current node to avoid false positives, and AnyFunctionLike::can_cast provides a clean function boundary check. Based on learnings.

Also applies to: 284-284


292-310: LGTM!

The improved rustdoc clarifies what constitutes a TypeScript signature.


487-501: Early returns skip remaining arguments.

The ? operators at lines 488 and 497 cause the function to return None immediately if any argument fails to process. This means subsequent arguments won't be checked, potentially missing parameter usage.

Verify this matches the intended conservative approach for this refactor.


407-469: Remove the unverified concern about early returns.

The ? operators are intentional. The function signature and calling context (line 497: traces_to_parameter(expr, param_name)?) show that None is expected and properly propagated. Tests exist for this rule and should pass if behaviour were broken.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs (1)

417-462: Inconsistent error handling in the worklist loop.

Lines 427–428, 435–436, 443–445, and 452 use .ok()?, which returns None from the function if extraction fails. However, lines 417–420 (identifier reference) and 458–462 (member expression) silently skip errors and continue with the rest of the worklist.

This means that failing to extract a subexpression from a binary operation aborts the entire analysis (returns "indeterminate"), whilst failing to extract a name or object just skips that item. For conservative, predictable behaviour, consider applying the same strategy across all branches—either propagate None on any extraction error, or handle all errors gracefully and continue.

For consistency, you could apply the ? pattern to the identifier and member cases as well:

 if let Some(ref_id) = current_expr.as_js_reference_identifier() {
-    if ref_id.name().ok().is_some_and(|n| n.text() == param_name) {
+    if ref_id.name().ok()?.text() == param_name {
         // Found direct parameter reference
         return Some(true);
     }
     continue;
 }
 if let Some(member_expr) = current_expr.as_js_static_member_expression() {
-    && let Ok(obj) = member_expr.object()
-{
-    to_check.push(obj);
+    to_check.push(member_expr.object().ok()?);
+    continue;
 }

Alternatively, handle all errors uniformly by continuing the loop (checking what can be checked):

 if let Some(bin_expr) = current_expr.as_js_binary_expression() {
-    to_check.push(bin_expr.left().ok()?);
-    to_check.push(bin_expr.right().ok()?);
+    if let Ok(left) = bin_expr.left() {
+        to_check.push(left);
+    }
+    if let Ok(right) = bin_expr.right() {
+        to_check.push(right);
+    }
     continue;
 }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between db6c4a3 and f74784b.

📒 Files selected for processing (1)
  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs (10 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{rs,toml}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format Rust and TOML files before committing (e.g., via just f)

Files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Document rules, assists, and their options with inline rustdoc in the Rust source

Files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
🧠 Learnings (12)
📓 Common learnings
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:23:33.055Z
Learning: Applies to crates/biome_js_type_info/src/{type_info,local_inference,resolver,flattening}.rs : Avoid recursive type structures and cross-module Arcs; represent links between types using TypeReference and TypeData::Reference.
📚 Learning: 2025-10-15T09:23:33.055Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:23:33.055Z
Learning: Applies to crates/biome_js_type_info/src/{type_info,local_inference,resolver,flattening}.rs : Avoid recursive type structures and cross-module Arcs; represent links between types using TypeReference and TypeData::Reference.

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:23:33.055Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:23:33.055Z
Learning: Applies to crates/biome_js_type_info/biome_module_graph/src/js_module_info/collector.rs : Thin (module-level) inference should resolve local and global bindings to TypeReference::Resolved, mark imported bindings as TypeReference::Import, and fall back to TypeReference::Unknown if unresolved.

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:23:33.055Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:23:33.055Z
Learning: Applies to crates/biome_js_type_info/biome_module_graph/src/js_module_info/scoped_resolver.rs : Full inference must resolve TypeReference::Import across modules to TypeReference::Resolved when the target is available in the module graph.

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-09-12T08:06:16.650Z
Learnt from: ematipico
Repo: biomejs/biome PR: 7410
File: crates/biome_js_analyze/src/lint/nursery/no_jsx_props_bind.rs:103-149
Timestamp: 2025-09-12T08:06:16.650Z
Learning: In Biome AST traversal, `ancestors().skip(1)` is a reasonable pattern to skip the current node and prevent false positives when searching for ancestor nodes of the same kind.

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Import and use the `FormatNode` trait for AST nodes

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Do not attempt to fix code; if a mandatory token/node is missing, return `None` instead

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : When a token is mandatory and present in the AST, use the AST-provided token (e.g., `node.l_paren_token().format()`) instead of emitting a static token

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Use `dbg_write!` to debug and inspect the emitted IR during formatting

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Implement the `Format` trait for your node type and use `JsFormatter` with `write!`/`format_args!` to define formatting

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/**/*.rs : After generation, remove usages of `format_verbatim_node` and implement real formatting with biome_formatter utilities

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : For non-mandatory tokens, use the provided helper constructors (e.g., `token`, `space_token`, `dynamic_token`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: End-to-end tests
  • GitHub Check: Documentation
  • GitHub Check: Check Dependencies
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Test Node.js API
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_js_parser)

@matanshavit
Copy link
Contributor Author

re: coderabbitai nitpick - seems good! I like consistency

@ematipico
Copy link
Member

@matanshavit can you please add a changeset?

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs (1)

486-493: Early return on malformed argument.

Line 487's arg.ok()? causes the entire function to return None if any single argument can't be extracted. If one argument is malformed but others trace to the parameter, we should still return Some(true).

Consider continuing instead of bailing out:

     for arg in arguments.args() {
-        let arg_node = arg.ok()?;
+        let Ok(arg_node) = arg else {
+            continue;
+        };

         // Skip spread arguments (conservative)
         if arg_node.as_js_spread().is_some() {
             continue;
         }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 962d38c and ec80486.

📒 Files selected for processing (1)
  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs (9 hunks)
🧰 Additional context used
🧠 Learnings (12)
📓 Common learnings
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:23:33.055Z
Learning: Applies to crates/biome_js_type_info/src/{type_info,local_inference,resolver,flattening}.rs : Avoid recursive type structures and cross-module Arcs; represent links between types using TypeReference and TypeData::Reference.
📚 Learning: 2025-10-15T09:23:33.055Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:23:33.055Z
Learning: Applies to crates/biome_js_type_info/src/{type_info,local_inference,resolver,flattening}.rs : Avoid recursive type structures and cross-module Arcs; represent links between types using TypeReference and TypeData::Reference.

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:23:33.055Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:23:33.055Z
Learning: Applies to crates/biome_js_type_info/biome_module_graph/src/js_module_info/collector.rs : Thin (module-level) inference should resolve local and global bindings to TypeReference::Resolved, mark imported bindings as TypeReference::Import, and fall back to TypeReference::Unknown if unresolved.

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-09-12T08:06:16.650Z
Learnt from: ematipico
Repo: biomejs/biome PR: 7410
File: crates/biome_js_analyze/src/lint/nursery/no_jsx_props_bind.rs:103-149
Timestamp: 2025-09-12T08:06:16.650Z
Learning: In Biome AST traversal, `ancestors().skip(1)` is a reasonable pattern to skip the current node and prevent false positives when searching for ancestor nodes of the same kind.

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Import and use the `FormatNode` trait for AST nodes

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Do not attempt to fix code; if a mandatory token/node is missing, return `None` instead

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : When a token is mandatory and present in the AST, use the AST-provided token (e.g., `node.l_paren_token().format()`) instead of emitting a static token

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Use `dbg_write!` to debug and inspect the emitted IR during formatting

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:23:33.055Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:23:33.055Z
Learning: Applies to crates/biome_js_type_info/biome_module_graph/src/js_module_info/scoped_resolver.rs : Full inference must resolve TypeReference::Import across modules to TypeReference::Resolved when the target is available in the module graph.

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Implement the `Format` trait for your node type and use `JsFormatter` with `write!`/`format_args!` to define formatting

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/**/*.rs : After generation, remove usages of `format_verbatim_node` and implement real formatting with biome_formatter utilities

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : For non-mandatory tokens, use the provided helper constructors (e.g., `token`, `space_token`, `dynamic_token`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
🧬 Code graph analysis (1)
crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs (1)
crates/biome_js_syntax/src/expr_ext.rs (1)
  • callee (32-37)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: End-to-end tests
  • GitHub Check: Documentation
  • GitHub Check: Check Dependencies
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: autofix
  • GitHub Check: Test Node.js API
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_js_analyze)
🔇 Additional comments (5)
crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs (5)

7-7: LGTM!

Import additions support the refactored Option-based control flow and boundary detection.

Also applies to: 10-10


131-139: LGTM!

On-the-fly reference iteration is more efficient than pre-collection, and unwrap_or_default() correctly treats indeterminate cases as non-recursive.


257-257: LGTM!

Using skip(1) to avoid the current node and AnyFunctionLike::can_cast for boundary detection are idiomatic Biome patterns. Based on learnings.

Also applies to: 284-284


315-358: LGTM!

The Option return type correctly represents three states: definitely recursive (Some(true)), definitely not recursive (Some(false)), and indeterminate (None). The conservative approach is appropriate for a lint rule.


377-381: LGTM!

The if let Some(true) pattern correctly addresses the previous review comment—now the loop continues checking other ancestors when is_recursive_call_with_param_usage returns None or Some(false).

@dyc3
Copy link
Contributor

dyc3 commented Nov 11, 2025

@ematipico this is just an internal refactor. none of the tests changed. this doesn't need a changeset, unless I missed something?

…ecursion

Replace early-return error propagation with local error handling in
traces_to_parameter and is_recursive_call_with_param_usage to skip
malformed AST nodes instead of failing the entire analysis.
@matanshavit
Copy link
Contributor Author

It's possible some edge cases changed. It might be a lot of new test code to test for every single difference of semantics. It seems excessive to do that at this point, but correct me if we need more compound expression testing (like where a rule violation is contained in a larger expression that is malformed).
I can create a changeset regardless, just in case.

"@biomejs/biome": patch
---

refactor NoParametersOnlyUsedInRecursion and refine to accurately lint in valid subexpressions in malformed expressions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be past tense, and it's not really clear to users what changed and how it affects them. does it fix something?

@ematipico
Copy link
Member

Ah sorry. The PR description is basically wrong and points to the wrong PR

@matanshavit
Copy link
Contributor Author

My bad on pr description, linked correct old pr

@ematipico
Copy link
Member

Happy to merge once the conflicts are resolved

@dyc3 dyc3 merged commit 5cd3d27 into biomejs:main Nov 12, 2025
17 checks passed
@matanshavit matanshavit deleted the refactor/no-parameters-only-used-in-recursion branch November 12, 2025 14:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Linter Area: linter L-JavaScript Language: JavaScript and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants