-
-
Notifications
You must be signed in to change notification settings - Fork 808
feat(lint): implement noIncrementDecrement
#7859
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
🦋 Changeset detectedLatest commit: 53cbe69 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 #7859 will not alter performanceComparing Summary
Footnotes
|
WalkthroughThis pull request introduces the Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro ⛔ Files ignored due to path filters (3)
📒 Files selected for processing (6)
🧰 Additional context used📓 Path-based instructions (2)**/*.{rs,toml}📄 CodeRabbit inference engine (CONTRIBUTING.md)
Files:
**/*.rs📄 CodeRabbit inference engine (CONTRIBUTING.md)
Files:
🧠 Learnings (2)📚 Learning: 2025-08-05T14:43:29.581ZApplied to files:
📚 Learning: 2025-10-24T21:24:58.631ZApplied to files:
🧬 Code graph analysis (2)crates/biome_js_analyze/src/lint/nursery/no_increment_decrement.rs (2)
crates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/invalid.js (2)
⏰ 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)
🔇 Additional comments (10)
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: 0
🧹 Nitpick comments (5)
.changeset/cool-drinks-dress.md (1)
1-5: Polish wording; confirm version bump.Tiny grammar fix and clearer split into two sentences. Also, is “patch” the intended bump for introducing a new rule?
-Added the nursery rule [`noIncrementDecrement`](https://biomejs.dev/linter/rules/no-increment-decrement/), disallows the usage of the unary operators ++ and --. +Added the nursery rule [`noIncrementDecrement`](https://biomejs.dev/linter/rules/no-increment-decrement/). It disallows the usage of the unary operators ++ and --.As per coding guidelines
crates/biome_rule_options/src/no_increment_decrement.rs (1)
1-9: Options struct looks solid; add a top-level rustdoc.Serde/camelCase and deny_unknown_fields are spot-on. Consider a brief struct doc for rustdoc.
-#[serde(rename_all = "camelCase", deny_unknown_fields, default)] +#[serde(rename_all = "camelCase", deny_unknown_fields, default)] +/// Options for the `noIncrementDecrement` rule. pub struct NoIncrementDecrementOptions {Based on learnings
crates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/invalid.js (1)
1-21: Add a couple more invalid shapes (properties/indexing).To harden coverage, add cases like:
const obj = { c: 0 }; obj.c++; const arr = [0]; arr[0]++; (getter()).field--;These ensure member/indexed updates also trigger diagnostics.
crates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/allowForLoopAfterthoughts.js (1)
18-21: Please add a valid multi-afterthought example with the option.Include this to ensure comma/sequence updates are accepted:
// Valid for (let i = 0, j = 10; i < j; i++, j--) { doSomething(i, j); }crates/biome_js_analyze/src/lint/nursery/no_increment_decrement.rs (1)
166-180: Optional: offer a quick fix to+= 1/-= 1.Consider adding a safe code action to replace
x++→x += 1and--x→x -= 1, preserving pre/post semantics where feasible.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (9)
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rsis excluded by!**/migrate/eslint_any_rule_to_biome.rsand included by**crates/biome_configuration/src/analyzer/linter/rules.rsis excluded by!**/rules.rsand included by**crates/biome_diagnostics_categories/src/categories.rsis excluded by!**/categories.rsand included by**crates/biome_js_analyze/src/lint/nursery.rsis excluded by!**/nursery.rsand included by**crates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/allowForLoopAfterthoughts.js.snapis excluded by!**/*.snapand included by**crates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/invalid.js.snapis excluded by!**/*.snapand included by**crates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/valid.js.snapis excluded by!**/*.snapand included by**packages/@biomejs/backend-jsonrpc/src/workspace.tsis excluded by!**/backend-jsonrpc/src/workspace.tsand included by**packages/@biomejs/biome/configuration_schema.jsonis excluded by!**/configuration_schema.jsonand included by**
📒 Files selected for processing (8)
.changeset/cool-drinks-dress.md(1 hunks)crates/biome_js_analyze/src/lint/nursery/no_increment_decrement.rs(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/allowForLoopAfterthoughts.js(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/allowForLoopAfterthoughts.options.json(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/invalid.js(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/valid.js(1 hunks)crates/biome_rule_options/src/lib.rs(1 hunks)crates/biome_rule_options/src/no_increment_decrement.rs(1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
.changeset/*.md
📄 CodeRabbit inference engine (CONTRIBUTING.md)
.changeset/*.md: In changesets, only use #### or ##### headers; other header levels are not allowed
Changesets should cover user-facing changes only; internal changes do not need changesets
Use past tense for what you did and present tense for current Biome behavior in changesets
When fixing a bug in a changeset, start with an issue link (e.g., “Fixed #1234: …”)
When referencing a rule or assist in a changeset, include a link to its page on the website
Include code blocks in changesets when applicable to illustrate changes
End every sentence in a changeset with a period
Files:
.changeset/cool-drinks-dress.md
crates/biome_*/**
📄 CodeRabbit inference engine (CLAUDE.md)
Place core crates under /crates/biome_*/
Files:
crates/biome_rule_options/src/lib.rscrates/biome_rule_options/src/no_increment_decrement.rscrates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/allowForLoopAfterthoughts.jscrates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/valid.jscrates/biome_js_analyze/src/lint/nursery/no_increment_decrement.rscrates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/invalid.jscrates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/allowForLoopAfterthoughts.options.json
**/*.rs
📄 CodeRabbit inference engine (CONTRIBUTING.md)
**/*.rs: Format Rust files before committing (e.g., viajust fwhich formats Rust)
Document rules, assists, and options with inline rustdoc in source
Files:
crates/biome_rule_options/src/lib.rscrates/biome_rule_options/src/no_increment_decrement.rscrates/biome_js_analyze/src/lint/nursery/no_increment_decrement.rs
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**
📄 CodeRabbit inference engine (CLAUDE.md)
Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}
Files:
crates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/allowForLoopAfterthoughts.jscrates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/valid.jscrates/biome_js_analyze/src/lint/nursery/no_increment_decrement.rscrates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/invalid.jscrates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/allowForLoopAfterthoughts.options.json
**/tests/**
📄 CodeRabbit inference engine (CLAUDE.md)
Place test files under a tests/ directory in each crate
Files:
crates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/allowForLoopAfterthoughts.jscrates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/valid.jscrates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/invalid.jscrates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/allowForLoopAfterthoughts.options.json
🧠 Learnings (5)
📚 Learning: 2025-10-24T21:24:58.631Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.631Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Place per-rule options types in biome_rule_options crate under lib/, one file per rule
Applied to files:
crates/biome_rule_options/src/lib.rs
📚 Learning: 2025-10-24T21:24:58.631Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.631Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Derive Serialize, Deserialize, and Deserializable for rule options; add #[serde(rename_all = "camelCase", deny_unknown_fields, default)]
Applied to files:
crates/biome_rule_options/src/no_increment_decrement.rs
📚 Learning: 2025-10-24T21:24:58.631Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.631Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : When schema feature is enabled, derive schemars::JsonSchema for options and related enums
Applied to files:
crates/biome_rule_options/src/no_increment_decrement.rs
📚 Learning: 2025-10-24T21:24:58.631Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.631Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : In declare_lint_rule! macros, set version: "next"
Applied to files:
crates/biome_js_analyze/src/lint/nursery/no_increment_decrement.rs
📚 Learning: 2025-08-05T14:43:29.581Z
Learnt from: dyc3
PR: biomejs/biome#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/nursery/noIncrementDecrement/allowForLoopAfterthoughts.options.json
🧬 Code graph analysis (2)
crates/biome_rule_options/src/no_increment_decrement.rs (1)
packages/@biomejs/backend-jsonrpc/src/workspace.ts (1)
NoIncrementDecrementOptions(8263-8268)
crates/biome_js_analyze/src/lint/nursery/no_increment_decrement.rs (1)
packages/@biomejs/backend-jsonrpc/src/workspace.ts (1)
NoIncrementDecrementOptions(8263-8268)
⏰ 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). (13)
- GitHub Check: Test (depot-ubuntu-24.04-arm-16)
- GitHub Check: Documentation
- GitHub Check: Test (depot-windows-2022-16)
- GitHub Check: Lint project (depot-windows-2022)
- GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
- GitHub Check: Check Dependencies
- GitHub Check: Test Node.js API
- GitHub Check: autofix
- GitHub Check: Bench (biome_js_analyze)
- GitHub Check: Bench (biome_js_parser)
- GitHub Check: Bench (biome_js_formatter)
- GitHub Check: Check JS Files
- GitHub Check: Bench (biome_configuration)
🔇 Additional comments (5)
crates/biome_rule_options/src/lib.rs (1)
107-107: Alphabetical placement looks right; please regen.Module sits correctly between no_important_styles and no_inferrable_types. As this file is generated, ensure the codegen source emits this too to avoid drift.
crates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/valid.js (1)
1-16: Nice baseline coverage.Covers non-diagnostic update patterns well. No changes requested.
crates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/allowForLoopAfterthoughts.options.json (1)
1-15: Config wiring looks correct.Key matches the camelCase option and the rule path. All good.
crates/biome_js_analyze/src/lint/nursery/no_increment_decrement.rs (2)
87-131: Docs and behaviour must align.The docs list
for (let i = 0, j = l; i < l; i++, j--) {}as valid with the option, which conflicts with current run() logic. After applying the fix above, the example will match behaviour.
152-164: Fix has a scope issue: would incorrectly allow nested operators.The proposed ancestors() check is too broad. It would allow
j = i++in the afterthought, but the existing test (allowForLoopAfterthoughts.jsline 8) expects that to error.The option should allow only standalone
++/--in afterthoughts, not nested in assignments. The fix should either:
- Check if parent is a SequenceExpression (the specific case for
i++, j--), or- Only allow direct children of the update expression
Add the sequence test case
for (...; ...; i++, j--)to confirm the fix works without breaking the assignment case.
c12501c to
cafbc37
Compare
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: 2
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (9)
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rsis excluded by!**/migrate/eslint_any_rule_to_biome.rsand included by**crates/biome_configuration/src/analyzer/linter/rules.rsis excluded by!**/rules.rsand included by**crates/biome_diagnostics_categories/src/categories.rsis excluded by!**/categories.rsand included by**crates/biome_js_analyze/src/lint/nursery.rsis excluded by!**/nursery.rsand included by**crates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/allowForLoopAfterthoughts.js.snapis excluded by!**/*.snapand included by**crates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/invalid.js.snapis excluded by!**/*.snapand included by**crates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/valid.js.snapis excluded by!**/*.snapand included by**packages/@biomejs/backend-jsonrpc/src/workspace.tsis excluded by!**/backend-jsonrpc/src/workspace.tsand included by**packages/@biomejs/biome/configuration_schema.jsonis excluded by!**/configuration_schema.jsonand included by**
📒 Files selected for processing (8)
.changeset/cool-drinks-dress.md(1 hunks)crates/biome_js_analyze/src/lint/nursery/no_increment_decrement.rs(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/allowForLoopAfterthoughts.js(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/allowForLoopAfterthoughts.options.json(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/invalid.js(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/valid.js(1 hunks)crates/biome_rule_options/src/lib.rs(1 hunks)crates/biome_rule_options/src/no_increment_decrement.rs(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- crates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/valid.js
🚧 Files skipped from review as they are similar to previous changes (5)
- crates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/allowForLoopAfterthoughts.js
- crates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/invalid.js
- crates/biome_js_analyze/tests/specs/nursery/noIncrementDecrement/allowForLoopAfterthoughts.options.json
- crates/biome_rule_options/src/lib.rs
- .changeset/cool-drinks-dress.md
🧰 Additional context used
📓 Path-based instructions (3)
crates/biome_*/**
📄 CodeRabbit inference engine (CLAUDE.md)
Place core crates under /crates/biome_*/
Files:
crates/biome_rule_options/src/no_increment_decrement.rscrates/biome_js_analyze/src/lint/nursery/no_increment_decrement.rs
**/*.rs
📄 CodeRabbit inference engine (CONTRIBUTING.md)
**/*.rs: Format Rust files before committing (e.g., viajust fwhich formats Rust)
Document rules, assists, and options with inline rustdoc in source
Files:
crates/biome_rule_options/src/no_increment_decrement.rscrates/biome_js_analyze/src/lint/nursery/no_increment_decrement.rs
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**
📄 CodeRabbit inference engine (CLAUDE.md)
Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}
Files:
crates/biome_js_analyze/src/lint/nursery/no_increment_decrement.rs
🧠 Learnings (1)
📚 Learning: 2025-10-24T21:24:58.631Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.631Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Derive Serialize, Deserialize, and Deserializable for rule options; add #[serde(rename_all = "camelCase", deny_unknown_fields, default)]
Applied to files:
crates/biome_rule_options/src/no_increment_decrement.rs
🧬 Code graph analysis (2)
crates/biome_rule_options/src/no_increment_decrement.rs (1)
packages/@biomejs/backend-jsonrpc/src/workspace.ts (1)
NoIncrementDecrementOptions(8263-8268)
crates/biome_js_analyze/src/lint/nursery/no_increment_decrement.rs (1)
packages/@biomejs/backend-jsonrpc/src/workspace.ts (1)
NoIncrementDecrementOptions(8263-8268)
⏰ 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). (14)
- GitHub Check: Test (depot-ubuntu-24.04-arm-16)
- GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
- GitHub Check: Check Dependencies
- GitHub Check: End-to-end tests
- GitHub Check: Documentation
- GitHub Check: Test (depot-windows-2022-16)
- GitHub Check: Lint project (depot-windows-2022)
- GitHub Check: Check JS Files
- GitHub Check: Bench (biome_js_formatter)
- GitHub Check: Bench (biome_js_parser)
- GitHub Check: Bench (biome_js_analyze)
- GitHub Check: Test Node.js API
- GitHub Check: Bench (biome_configuration)
- GitHub Check: autofix
🔇 Additional comments (4)
crates/biome_rule_options/src/no_increment_decrement.rs (1)
1-9: LGTM!The options struct is correctly implemented with all required derives and serde attributes. Matches the retrieved learnings and coding guidelines perfectly.
crates/biome_js_analyze/src/lint/nursery/no_increment_decrement.rs (3)
1-8: LGTM!Imports are clean and appropriate for the rule implementation.
142-144: LGTM!Node union correctly captures both pre and post update expressions.
166-181: LGTM!Diagnostic message is clear and provides helpful alternatives. The note about automatic semicolon insertion explains the rationale well.
crates/biome_js_analyze/src/lint/nursery/no_increment_decrement.rs
Outdated
Show resolved
Hide resolved
cafbc37 to
44911bb
Compare
|
I kinda like eslint's original name, which for us would be |
I liked it too, but kind of hints towards only
|
dyc3
left a 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.
Looking good, nice and simple :)
| /// Allows unary operators ++ and -- in the afterthought (final expression) of a for loop. | ||
| pub allow_for_loop_afterthoughts: bool, |
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.
We generally don't add options for new rules, because we want to have concrete use cases and/or actual user demand.
What's the source rule's default behavior for this? I would imagine it would be true. In any case we should adhere to the default behavior of the eslint rule.
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.
The option originates from the Eslint rule, which by default uses false. The implementation into biome is written in a way it uses unset/null as false, so false as default as well
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.
Even if the source rule has options, we still generally don't implement options on the first iteration of a rule.
But this is not necessarily a hard rule. I can see that the actual logic of this option is pretty trivial so I'm fine with leaving it in here.
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.
Ahhh okay, TIL. Thanks :)
Summary
Port Eslint's
no-plusplusTest Plan
Docs