-
-
Notifications
You must be signed in to change notification settings - Fork 760
fix(noParametersOnlyUsedInRecursion): compare bindings for recursion detection #8026
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…detection Compare function bindings in addition to names for recursion detection. This prevents false positives when a method has the same name as an outer function but calls the outer function (not itself).
🦋 Changeset detectedLatest commit: a83d962 The changes in this PR will be included in the next version bump. This PR includes changesets to release 13 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
CodSpeed Performance ReportMerging #8026 will not alter performanceComparing Summary
Footnotes
|
WalkthroughThe PR updates the noParametersOnlyUsedInRecursion lint to use the semantic model and binding comparison for recursion detection. It adds Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (5 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ 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)
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. Comment |
There was a problem hiding this 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
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
crates/biome_js_analyze/tests/specs/nursery/noParametersOnlyUsedInRecursion/valid.js.snapis excluded by!**/*.snapand included by**
📒 Files selected for processing (2)
crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs(8 hunks)crates/biome_js_analyze/tests/specs/nursery/noParametersOnlyUsedInRecursion/valid.js(1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 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
🧬 Code graph analysis (2)
crates/biome_js_analyze/tests/specs/nursery/noParametersOnlyUsedInRecursion/valid.js (1)
crates/biome_js_analyze/tests/specs/nursery/noParametersOnlyUsedInRecursion/invalid.js (1)
obj(46-51)
crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs (1)
crates/biome_rowan/src/ast/mod.rs (1)
cast_ref(143-152)
crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
Show resolved
Hide resolved
crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs
Outdated
Show resolved
Hide resolved
| return false; | ||
| } | ||
|
|
||
| // Try to resolve the binding of the reference |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // Try to resolve the binding of the reference |
Make sure you leave comments that are useful
| // Try to resolve the binding of the reference | ||
| let called_binding = model.binding(&ref_id); | ||
|
|
||
| // Compare bindings |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // Compare bindings |
| // Simple identifier: foo() | ||
| if let Some(ref_id) = expr.as_js_reference_identifier() { | ||
| return ref_id.name().ok().is_some_and(|n| n.text() == name.text()); | ||
| // First check for a matching name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // First check for a matching name |
|
Also, changeset is missing... |
There was a problem hiding this 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 (2)
crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs (2)
258-310: Solid binding resolution logic.The function correctly handles all function types, including the tricky arrow-function case by walking up ancestors. The binding comparison for assignments (lines 293-296) is well-explained.
One minor point: the comment at lines 293-296 is quite detailed. Whilst accurate, consider whether a more concise version might suffice—something like "Resolve assignment target to its binding via model.binding()."
324-328: Useskip(1)for consistency.As noted in earlier feedback, this manual check can be replaced with
skip(1)on the iterator, matching the approach inget_function_binding(line 276).Apply this diff:
- for ancestor in arrow_syntax.ancestors() { - // Skip the arrow function node itself - if ancestor == *arrow_syntax { - continue; - } + for ancestor in arrow_syntax.ancestors().skip(1) {
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs(8 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 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
🧬 Code graph analysis (1)
crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs (2)
crates/biome_rowan/src/ast/mod.rs (1)
cast_ref(143-152)crates/biome_js_formatter/src/utils/assignment_like.rs (1)
left(355-374)
⏰ 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). (5)
- GitHub Check: Test Node.js API
- GitHub Check: autofix
- GitHub Check: Bench (biome_js_parser)
- GitHub Check: Bench (biome_js_formatter)
- GitHub Check: Bench (biome_js_analyze)
🔇 Additional comments (4)
crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs (4)
129-131: LGTM!Clean addition to retrieve the function binding for semantic comparison.
415-441: Excellent binding-aware recursion detection.The four-case logic correctly addresses the false positive:
- Case
(None, Some)at lines 429-431 is the key fix, preventing methods from being flagged when they call outer functions sharing the same name.- The fallback to name comparison for
(None, None)maintains backwards compatibility for method self-calls.The early name check (lines 415-418) is a sensible optimisation.
492-514: Correct parameter threading.The signature updates and call sites properly thread
modelandparent_function_bindingthrough the recursion analysis chain.
624-632: Correct parameter threading.The updated signature and call to
is_recursive_callcorrectly pass the semantic context through.
8930f0d to
4af7f8d
Compare
Summary
Compare function bindings in addition to names for recursion detection. This prevents false positives when a method has the same name as an outer function but calls the outer function (not itself). Fixes #8004
related - #7970 refactors and additional comments that were requested for the rule file
AI assistance notice
This PR was written primarily by Claude Code, with changes from the author. As the human author, I have reviewed the code thoroughly and take full responsibility for its contents.
Test Plan
Added a valid test and snapshot for the example shown in the issue. The test fails without the production change, confirming the issue, and passes after the production file change, confirming the solution.
Docs
Doc comment on new method for function bindings