Skip to content

feat(linter): add checkForEach option to useIterableCallbackReturn#8660

Closed
Faizanq wants to merge 1 commit intobiomejs:mainfrom
Faizanq:feat/check-for-each-option
Closed

feat(linter): add checkForEach option to useIterableCallbackReturn#8660
Faizanq wants to merge 1 commit intobiomejs:mainfrom
Faizanq:feat/check-for-each-option

Conversation

@Faizanq
Copy link
Contributor

@Faizanq Faizanq commented Jan 3, 2026

Summary

Adds the checkForEach option to useIterableCallbackReturn rule to match ESLint's array-callback-return behavior.

  • checkForEach defaults to false (matching ESLint)
  • When false: forEach callbacks with return values are allowed
  • When true: forEach callbacks with return values trigger an error

This makes migration from ESLint easier for users.

Test plan

  • Added validForEachDefault.js - verifies forEach with returns is valid by default
  • Added invalidCheckForEach.js with options - verifies forEach with returns errors when enabled
  • All existing tests pass

Closes #8024

…iomejs#8024)

- Added checkForEach option, defaults to false (matching ESLint)
- forEach callbacks with returns are now allowed by default
- Set checkForEach: true to enforce no returns in forEach
@changeset-bot
Copy link

changeset-bot bot commented Jan 3, 2026

⚠️ No Changeset found

Latest commit: f881bbe

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 Jan 3, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 3, 2026

Walkthrough

This change introduces a checkForEach option to the useIterableCallbackReturn lint rule, ported from the ESLint specification. The implementation adds a new boolean field to the rule's options struct with a default value of false. When disabled, forEach callback returns are not validated. The rule logic was updated to skip forEach validation early if the option is false. Test files were reorganised to separate forEach validation scenarios into a dedicated configuration with the option enabled, whilst existing forEach test cases now serve as validation that they remain unvalidated by default.

Pre-merge checks and finishing touches

✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding a checkForEach option to the useIterableCallbackReturn lint rule.
Description check ✅ Passed The description clearly explains the feature, its purpose (ESLint alignment), default behaviour, and includes test plan with issue reference.
Linked Issues check ✅ Passed All requirements from issue #8024 are met: checkForEach option added, defaults to false matching ESLint, controls forEach callback return validation, and includes proper test coverage.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the checkForEach option; test file modifications appropriately reflect the new feature's behaviour.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent 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 87dac09 and f881bbe.

⛔ Files ignored due to path filters (3)
  • crates/biome_js_analyze/tests/specs/suspicious/useIterableCallbackReturn/invalid.js.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/suspicious/useIterableCallbackReturn/invalidCheckForEach.js.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/suspicious/useIterableCallbackReturn/validForEachDefault.js.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (6)
  • crates/biome_js_analyze/src/lint/suspicious/use_iterable_callback_return.rs
  • crates/biome_js_analyze/tests/specs/suspicious/useIterableCallbackReturn/invalid.js
  • crates/biome_js_analyze/tests/specs/suspicious/useIterableCallbackReturn/invalidCheckForEach.js
  • crates/biome_js_analyze/tests/specs/suspicious/useIterableCallbackReturn/invalidCheckForEach.options.json
  • crates/biome_js_analyze/tests/specs/suspicious/useIterableCallbackReturn/validForEachDefault.js
  • crates/biome_rule_options/src/use_iterable_callback_return.rs
💤 Files with no reviewable changes (1)
  • crates/biome_js_analyze/tests/specs/suspicious/useIterableCallbackReturn/invalid.js
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

**/*.rs: Use inline rustdoc documentation for rules, assists, and their options
Use the dbg!() macro for debugging output in Rust tests and code
Use doc tests (doctest) format with code blocks in rustdoc comments; ensure assertions pass in tests

Files:

  • crates/biome_js_analyze/src/lint/suspicious/use_iterable_callback_return.rs
  • crates/biome_rule_options/src/use_iterable_callback_return.rs
🧠 Learnings (23)
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/tests/specs/**/* : Create test files with `invalid` and `valid` prefixes to represent code that should and should not trigger the rule

Applied to files:

  • crates/biome_js_analyze/tests/specs/suspicious/useIterableCallbackReturn/validForEachDefault.js
  • crates/biome_js_analyze/tests/specs/suspicious/useIterableCallbackReturn/invalidCheckForEach.options.json
  • crates/biome_js_analyze/tests/specs/suspicious/useIterableCallbackReturn/invalidCheckForEach.js
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : The first paragraph of rule documentation must be written in a single line to ensure proper rendering in the rules overview table

Applied to files:

  • crates/biome_js_analyze/src/lint/suspicious/use_iterable_callback_return.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Deprecated rules must include a `deprecated` field in the `declare_lint_rule!` macro with an explanation of what rule to use instead

Applied to files:

  • crates/biome_js_analyze/src/lint/suspicious/use_iterable_callback_return.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Invalid code snippets in rule documentation must emit exactly one diagnostic

Applied to files:

  • crates/biome_js_analyze/src/lint/suspicious/use_iterable_callback_return.rs
📚 Learning: 2025-12-22T09:26:56.943Z
Learnt from: ematipico
Repo: biomejs/biome PR: 8537
File: crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs:167-210
Timestamp: 2025-12-22T09:26:56.943Z
Learning: When defining lint rules (declare_lint_rule!), only specify fix_kind if the rule implements an action(...) function. Rules that only emit diagnostics without a code fix should omit fix_kind. This applies to all Rust lint rule definitions under crates/.../src/lint (e.g., crates/biome_js_analyze/src/lint/...).

Applied to files:

  • crates/biome_js_analyze/src/lint/suspicious/use_iterable_callback_return.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Use `declare_lint_rule!` macro with a `version` field set to `next` for new rules

Applied to files:

  • crates/biome_js_analyze/src/lint/suspicious/use_iterable_callback_return.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Use helper functions like `map`, `filter`, and `and_then` to avoid excessive nested `if let` statements

Applied to files:

  • crates/biome_js_analyze/src/lint/suspicious/use_iterable_callback_return.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Implement the `action` function and add `fix_kind` metadata to the rule macro if the rule provides code actions

Applied to files:

  • crates/biome_js_analyze/src/lint/suspicious/use_iterable_callback_return.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Rule names should use the `use` prefix when the rule's sole intention is to mandate a single concept

Applied to files:

  • crates/biome_js_analyze/src/lint/suspicious/use_iterable_callback_return.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Implement custom `Queryable` and `Visitor` types for rules that require deep inspection of child nodes to avoid inefficient traversals

Applied to files:

  • crates/biome_js_analyze/src/lint/suspicious/use_iterable_callback_return.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/biome_rule_options/lib/**/*.rs : Use `Option<_>` wrapper for rule option fields to enable proper merging of configurations

Applied to files:

  • crates/biome_js_analyze/src/lint/suspicious/use_iterable_callback_return.rs
  • crates/biome_rule_options/src/use_iterable_callback_return.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/tests/specs/**/*.jsonc : Use `.jsonc` format for test files containing multiple code snippets, where each snippet is a string in an array

Applied to files:

  • crates/biome_js_analyze/tests/specs/suspicious/useIterableCallbackReturn/invalidCheckForEach.options.json
  • crates/biome_js_analyze/tests/specs/suspicious/useIterableCallbackReturn/invalidCheckForEach.js
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/tests/specs/**/options.json : Create an `options.json` file (formatted as `biome.json`) in test specification folders to apply non-default formatting options to all test files in that folder

Applied to files:

  • crates/biome_js_analyze/tests/specs/suspicious/useIterableCallbackReturn/invalidCheckForEach.options.json
📚 Learning: 2025-08-05T14:43:29.581Z
Learnt from: dyc3
Repo: biomejs/biome PR: 7081
File: packages/@biomejs/biome/configuration_schema.json:7765-7781
Timestamp: 2025-08-05T14:43:29.581Z
Learning: The file `packages/biomejs/biome/configuration_schema.json` is auto-generated and should not be manually edited or reviewed for schema issues; any changes should be made at the code generation source.

Applied to files:

  • crates/biome_js_analyze/tests/specs/suspicious/useIterableCallbackReturn/invalidCheckForEach.options.json
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Biome linter rules must be designed to work across languages, requiring careful naming to indicate intended scope

Applied to files:

  • crates/biome_js_analyze/tests/specs/suspicious/useIterableCallbackReturn/invalidCheckForEach.options.json
📚 Learning: 2025-11-21T01:10:53.059Z
Learnt from: dyc3
Repo: biomejs/biome PR: 8171
File: crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs:125-137
Timestamp: 2025-11-21T01:10:53.059Z
Learning: In the Biome codebase, each lint rule has its own options type declaration (e.g., `type Options = RuleNameOptions`) as part of the codegen process, even if the options struct is empty or unused. This is standard practice and should not be flagged as an issue.

Applied to files:

  • crates/biome_js_analyze/tests/specs/suspicious/useIterableCallbackReturn/invalidCheckForEach.options.json
📚 Learning: 2025-09-25T12:32:59.003Z
Learnt from: arendjr
Repo: biomejs/biome PR: 7593
File: crates/biome_service/src/workspace/server.rs:1306-1306
Timestamp: 2025-09-25T12:32:59.003Z
Learning: In the biomejs/biome project, do not flag compilation errors during code review as they are handled by the existing test infrastructure and CI. Focus on other code quality aspects instead.

Applied to files:

  • crates/biome_js_analyze/tests/specs/suspicious/useIterableCallbackReturn/invalidCheckForEach.options.json
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/biome_rule_options/lib/**/*.rs : Apply `#[serde(deny_unknown_fields)]` to rule option structs to enforce strict configuration validation

Applied to files:

  • crates/biome_rule_options/src/use_iterable_callback_return.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/biome_rule_options/lib/**/*.rs : Rule option types must derive `Deserializable`, `Serialize`, `Deserialize`, and optionally `JsonSchema` traits

Applied to files:

  • crates/biome_rule_options/src/use_iterable_callback_return.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/biome_rule_options/lib/**/*.rs : Apply `#[serde(rename_all = "camelCase")]` to rule option structs to match JSON configuration naming convention

Applied to files:

  • crates/biome_rule_options/src/use_iterable_callback_return.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/biome_rule_options/lib/**/*.rs : Rule options must be defined in the `biome_rule_options` crate with a file named after the rule

Applied to files:

  • crates/biome_rule_options/src/use_iterable_callback_return.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/biome_rule_options/lib/**/*.rs : Implement `biome_deserialize::Merge` for rule option types to define how shared and user configurations are merged

Applied to files:

  • crates/biome_rule_options/src/use_iterable_callback_return.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/biome_rule_options/lib/**/*.rs : Use `Box<[Box<str>]>` instead of `Vec<String>` for collections of strings in rule options to save memory

Applied to files:

  • crates/biome_rule_options/src/use_iterable_callback_return.rs
🔇 Additional comments (7)
crates/biome_rule_options/src/use_iterable_callback_return.rs (2)

4-13: LGTM! Option struct follows Biome conventions.

The option field is correctly wrapped in Option<_> for proper configuration merging, and all required serde attributes and derives are present. Documentation is clear.

Based on learnings, option structs should use Option<_> wrapper and apply #[serde(deny_unknown_fields)] and #[serde(rename_all = "camelCase")], which this implementation does correctly.


15-23: LGTM! Clean accessor implementation.

The default value of false correctly matches ESLint's behaviour, and the accessor method provides a clean way to retrieve the option with a sensible fallback.

crates/biome_js_analyze/tests/specs/suspicious/useIterableCallbackReturn/invalidCheckForEach.options.json (1)

1-15: LGTM! Test configuration correctly enables checkForEach.

The configuration properly sets checkForEach: true to verify that forEach callbacks with return values trigger diagnostics when the option is enabled.

crates/biome_js_analyze/src/lint/suspicious/use_iterable_callback_return.rs (2)

83-97: LGTM! Clear documentation for the new option.

The documentation properly explains the checkForEach option, its default behaviour, and provides a configuration example. Well done.


148-151: LGTM! Correct implementation of the forEach skip logic.

The early return when checkForEach is false (default) properly prevents forEach callbacks from being validated, matching ESLint's default behaviour. When enabled, forEach proceeds to validation where return_value_required: false causes returns with values to be flagged.

crates/biome_js_analyze/tests/specs/suspicious/useIterableCallbackReturn/invalidCheckForEach.js (1)

1-25: LGTM! Comprehensive test coverage for checkForEach enabled.

The test cases cover a good variety of scenarios including arrow functions, function expressions, and different control flow patterns. All should correctly trigger diagnostics when checkForEach: true.

crates/biome_js_analyze/tests/specs/suspicious/useIterableCallbackReturn/validForEachDefault.js (1)

1-27: LGTM! Proper validation of default behaviour.

This test file correctly verifies that with the default setting (checkForEach: false), forEach callbacks with return values don't trigger diagnostics, matching ESLint's behaviour.


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.

@ematipico
Copy link
Member

ematipico commented Jan 3, 2026

Please, next time, comment on the issue. There's already a PR #8289

@ematipico ematipico closed this Jan 3, 2026
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.

📎 Add the checkForEach option to useIterableCallbackReturn

2 participants