feat(lint/nursery): new rule - noInvertedTernary#9312
feat(lint/nursery): new rule - noInvertedTernary#9312js2me wants to merge 4 commits intobiomejs:mainfrom
Conversation
🦋 Changeset detectedLatest commit: 646c8e9 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 |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review infoConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (2)
WalkthroughAdds a new ESLint-style lint rule Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs). 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.
Actionable comments posted: 2
🧹 Nitpick comments (1)
crates/biome_rule_options/src/no_inverted_ternary.rs (1)
3-6: Add a short rustdoc block for the options type.The struct is correct; it just needs inline docs to match repository convention for rule options.
📝 Suggested patch
+/// Options for `noInvertedTernary`. +/// +/// This rule currently has no configurable options. pub struct NoInvertedTernaryOptions {}As per coding guidelines: "Use inline rustdoc documentation for rules, assists, and their options".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/biome_rule_options/src/no_inverted_ternary.rs` around lines 3 - 6, Add an inline rustdoc comment above the NoInvertedTernaryOptions struct describing what this options type controls (e.g., options for the "no inverted ternary" lint/rule), include a short one-line summary and, if applicable, list any fields or default behavior; place the doc comment (/// ...) directly above pub struct NoInvertedTernaryOptions {} to match repository convention for rule options.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.changeset/cuddly-cougars-hope.md:
- Line 5: Update the changeset note for the new rule "noInvertedTernary" to be
user-facing: describe in one sentence what patterns the rule catches (e.g.,
ternary expressions with inverted condition/result order that reduce
readability), explain the intended fix, and include one inline invalid example
such as `const x = condition ? falseValue : trueValue;` (or a short code block)
showing the problematic inverted ternary; ensure the changeset text is clear for
end users and replaces the minimal "new rule noInvertedTernary" line with this
expanded description.
In `@crates/biome_js_analyze/src/lint/nursery/no_inverted_ternary.rs`:
- Around line 56-57: The current code casts node.test() directly to a
JsBinaryExpression (via test_expression.as_js_binary_expression()), which fails
for parenthesised tests like `(a !== b) ? c : d`; update both run() and action()
to unwrap parenthesised expressions first by calling .inner_expression() on the
test_expression before attempting .as_js_binary_expression(), and do the same
for the similar usage around the other occurrence (the test variable at lines
83-84) so parenthesised binary tests are correctly detected and handled.
---
Nitpick comments:
In `@crates/biome_rule_options/src/no_inverted_ternary.rs`:
- Around line 3-6: Add an inline rustdoc comment above the
NoInvertedTernaryOptions struct describing what this options type controls
(e.g., options for the "no inverted ternary" lint/rule), include a short
one-line summary and, if applicable, list any fields or default behavior; place
the doc comment (/// ...) directly above pub struct NoInvertedTernaryOptions {}
to match repository convention for rule options.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (3)
crates/biome_diagnostics_categories/src/categories.rsis excluded by!**/categories.rsand included by**crates/biome_js_analyze/tests/specs/nursery/noInvertedTernary/invalid.js.snapis excluded by!**/*.snapand included by**crates/biome_js_analyze/tests/specs/nursery/noInvertedTernary/valid.js.snapis excluded by!**/*.snapand included by**
📒 Files selected for processing (8)
.changeset/cuddly-cougars-hope.mdcrates/biome_js_analyze/src/lint/correctness/use_exhaustive_dependencies.rscrates/biome_js_analyze/src/lint/nursery/no_inverted_ternary.rscrates/biome_js_analyze/tests/specs/nursery/noInvertedTernary/invalid.jscrates/biome_js_analyze/tests/specs/nursery/noInvertedTernary/valid.jscrates/biome_json_analyze/src/lint/nursery/use_required_scripts.rscrates/biome_rule_options/src/lib.rscrates/biome_rule_options/src/no_inverted_ternary.rs
| "@biomejs/biome": patch | ||
| --- | ||
|
|
||
| new rule noInvertedTernary |
There was a problem hiding this comment.
Please expand the changeset note for end users.
new rule noInvertedTernary is a bit too minimal for release notes; include what it catches and one invalid example.
✍️ Suggested rewrite
-new rule noInvertedTernary
+Add the nursery rule `noInvertedTernary`, which flags inverted ternaries like
+`a !== b ? x : y` and auto-fixes them to `a === b ? y : x`.As per coding guidelines: "Create changeset files ... with ... end-user-focused descriptions". Based on learnings: "For new lint rules in changesets, show an example of invalid case in inline code or code block".
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| new rule noInvertedTernary | |
| Add the nursery rule `noInvertedTernary`, which flags inverted ternaries like | |
| `a !== b ? x : y` and auto-fixes them to `a === b ? y : x`. |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.changeset/cuddly-cougars-hope.md at line 5, Update the changeset note for
the new rule "noInvertedTernary" to be user-facing: describe in one sentence
what patterns the rule catches (e.g., ternary expressions with inverted
condition/result order that reduce readability), explain the intended fix, and
include one inline invalid example such as `const x = condition ? falseValue :
trueValue;` (or a short code block) showing the problematic inverted ternary;
ensure the changeset text is clear for end users and replaces the minimal "new
rule noInvertedTernary" line with this expanded description.
There was a problem hiding this comment.
Seems very related to https://biomejs.dev/linter/rules/no-negation-else/, could be a feature in that rule. (Does already cover != & !== for if statements & full negative in ternaries)
Also some generated schema data is missing.
| pub NoInvertedTernary { | ||
| version: "next", | ||
| name: "noInvertedTernary", | ||
| language: "js", | ||
| recommended: false, | ||
| fix_kind: FixKind::Safe, | ||
| } |
There was a problem hiding this comment.
Are there existing eslint rules that do this? If so, add them as rule sources
There was a problem hiding this comment.
https://eslint.org/docs/latest/rules/no-negated-condition does, which we already "implemented" (https://biomejs.dev/linter/rules/no-negation-else/), but our implementation does not seem to cover this yet. Created #9351
| }, | ||
| ) | ||
| .note(markup! { | ||
| "Use an equality check in the test and swap the two branches for better readability." |
There was a problem hiding this comment.
Follow the rule pillars. The messages must say:
- What the error is (in
diagnostic) - Why it is an error (in
diagnostic) - How to fix the error (action message)
|
|
||
| Some(JsRuleAction::new( | ||
| ctx.metadata().action_category(ctx.category(), ctx.group()), | ||
| Applicability::Always, |
There was a problem hiding this comment.
| Applicability::Always, | |
| ctx.metadata().applicability(), |
| /// ### Valid | ||
| /// | ||
| /// ```js | ||
| /// const value = i === data.depth - 1 ? 0 : 18; | ||
| /// ``` | ||
| /// | ||
| /// ```js | ||
| /// const result = foo === bar ? second : first; | ||
| /// ``` |
There was a problem hiding this comment.
nit: these valid cases can be combined
|
Will be covered by noNegationElse with #9351 |
|
Thank you, this thing is really useful |
This PR was written primarily by GPT-5.3 Codex
Summary
Added a new nursery lint rule:
noInvertedTernary.The rule reports inverted ternary conditions such as
A !== B ? C : D(andA != B ? C : D) and provides an auto-fix that rewrites them to the direct form:A === B ? D : C(orA == B ? D : C).This improves readability by avoiding negated ternary tests.
Also added rule tests (
valid/invalid) and updated snapshots.Test Plan
cargo test -p biome_js_analyze no_inverted_ternary -- --nocaptureINSTA_UPDATE=always cargo test -p biome_js_analyze no_inverted_ternaryDocs
invalidandvalidcases).