Skip to content

fix(lint): preserve ternary branch comments in noNegationElse#9630

Merged
dyc3 merged 10 commits intobiomejs:mainfrom
raashish1601:contributor-06/no-negation-else-ternary-comments
Mar 28, 2026
Merged

fix(lint): preserve ternary branch comments in noNegationElse#9630
dyc3 merged 10 commits intobiomejs:mainfrom
raashish1601:contributor-06/no-negation-else-ternary-comments

Conversation

@raashish1601
Copy link
Copy Markdown

Summary

  • preserve branch comments when style/noNegationElse inverts ternary expressions
  • swap the ? / : trivia alongside the consequent and alternate expressions
  • update the existing spec snapshot to lock in the corrected fixer output

Testing

  • cargo test -p biome_js_analyze --test spec_tests no_negation_else

Closes #9629.

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 27, 2026

🦋 Changeset detected

Latest commit: 7a0ae0e

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 13 packages
Name Type
@biomejs/biome Patch
@biomejs/cli-win32-x64 Patch
@biomejs/cli-win32-arm64 Patch
@biomejs/cli-darwin-x64 Patch
@biomejs/cli-darwin-arm64 Patch
@biomejs/cli-linux-x64 Patch
@biomejs/cli-linux-arm64 Patch
@biomejs/cli-linux-x64-musl Patch
@biomejs/cli-linux-arm64-musl Patch
@biomejs/wasm-web Patch
@biomejs/wasm-bundler Patch
@biomejs/wasm-nodejs Patch
@biomejs/backend-jsonrpc Patch

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

@github-actions github-actions bot added A-Linter Area: linter L-JavaScript Language: JavaScript and super languages labels Mar 27, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 27, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

The ternary (JsConditionalExpression) fixer in noNegationElse now mutates the existing node in-place instead of rebuilding it. It extracts consequent, alternate, and the ?/: tokens, splits trailing trivia on branch end tokens into kept/suffix pieces, swaps branches and reattaches trivia to the opposite branch nodes, transfers trailing trivia between ? and : via token-level cloning/replacement, explicitly sets leading trivia on the conditional’s first token, and uses replace_node_discard_trivia. No changes to the JsIfStatement action.

Possibly related PRs

Suggested reviewers

  • dyc3
  • ematipico
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarises the core fix: preserving ternary branch comments in the noNegationElse linter rule.
Description check ✅ Passed The description clearly relates to the changeset, detailing the preservation of branch comments and trivia swapping when inverting ternary expressions.
Linked Issues check ✅ Passed The PR directly addresses issue #9629 by implementing trivia preservation when swapping ternary branches, ensuring comments remain attached to their logical branches.
Out of Scope Changes check ✅ Passed All changes are scoped to the noNegationElse fixer, test cases, and related changeset documentation—no unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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
Copy Markdown
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.

🧹 Nitpick comments (1)
crates/biome_js_analyze/src/lint/style/no_negation_else.rs (1)

109-113: Consider cloning colon_token for consistent trivia preservation.

The new_question_mark_token is created by cloning the original token (preserving its leading trivia), but new_colon_token uses make::token_decorated_with_space, which discards any original leading trivia on :. This could alter spacing in edge cases like a : bb : a.

For consistency:

✨ Suggested tweak
-let new_colon_token = make::token_decorated_with_space(T![:])
+let new_colon_token = colon_token
+    .clone()
     .with_trailing_trivia_pieces(question_mark_token.trailing_trivia().pieces());
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_js_analyze/src/lint/style/no_negation_else.rs` around lines 109
- 113, new_colon_token currently discards the original colon_token's leading
trivia by using make::token_decorated_with_space; instead clone colon_token
(similar to how new_question_mark_token clones question_mark_token) and set its
leading/trailing trivia appropriately so the original spacing is preserved.
Locate the variables question_mark_token, colon_token, new_question_mark_token
and new_colon_token and replace the make::token_decorated_with_space
construction with a colon_token.clone() (or equivalent clone method) then apply
with_leading_trivia_pieces/with_trailing_trivia_pieces to mirror how
new_question_mark_token is constructed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@crates/biome_js_analyze/src/lint/style/no_negation_else.rs`:
- Around line 109-113: new_colon_token currently discards the original
colon_token's leading trivia by using make::token_decorated_with_space; instead
clone colon_token (similar to how new_question_mark_token clones
question_mark_token) and set its leading/trailing trivia appropriately so the
original spacing is preserved. Locate the variables question_mark_token,
colon_token, new_question_mark_token and new_colon_token and replace the
make::token_decorated_with_space construction with a colon_token.clone() (or
equivalent clone method) then apply
with_leading_trivia_pieces/with_trailing_trivia_pieces to mirror how
new_question_mark_token is constructed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3a3a153c-6b3f-4244-b36b-9cad6a753f03

📥 Commits

Reviewing files that changed from the base of the PR and between 13b3261 and 37e3707.

⛔ Files ignored due to path filters (1)
  • crates/biome_js_analyze/tests/specs/style/noNegationElse/invalid.js.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (1)
  • crates/biome_js_analyze/src/lint/style/no_negation_else.rs

Copy link
Copy Markdown
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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/biome_js_analyze/src/lint/style/no_negation_else.rs`:
- Around line 111-135: The code currently discards the alternate slot's suffix
returned by split_trailing_trivia, causing loss of spacing/newline after a moved
branch; capture both parts (e.g., let (alternate_trailing, alternate_suffix) =
split_trailing_trivia(...)) and when swapping attach the saved alternate_suffix
to the node that becomes the new alternate (use with_trailing_trivia_pieces for
the final mutation.replace_node_discard_trivia call instead of reusing
consequent_trailing), ensuring you still build new_consequent_trailing from
alternate_trailing and consequent_suffix as before; update usages of
alternate_trailing/alternate_suffix in replace_node_discard_trivia and
with_trailing_trivia_pieces to preserve the original suffix.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 61c87fea-dbd2-4e26-aecf-a06fa611ef9d

📥 Commits

Reviewing files that changed from the base of the PR and between e6609a9 and 356b5f5.

⛔ Files ignored due to path filters (1)
  • crates/biome_js_analyze/tests/specs/style/noNegationElse/invalid.js.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (2)
  • crates/biome_js_analyze/src/lint/style/no_negation_else.rs
  • crates/biome_js_analyze/tests/specs/style/noNegationElse/invalid.js
✅ Files skipped from review due to trivial changes (1)
  • crates/biome_js_analyze/tests/specs/style/noNegationElse/invalid.js

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Mar 27, 2026

Merging this PR will not alter performance

✅ 58 untouched benchmarks
⏩ 168 skipped benchmarks1


Comparing raashish1601:contributor-06/no-negation-else-ternary-comments (7a0ae0e) with main (599dd04)2

Open in CodSpeed

Footnotes

  1. 168 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.

  2. No successful run was found on main (13b3261) during the generation of this report, so 599dd04 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@dyc3 dyc3 added the M-Likely Agent This was likely an automated PR without a human in the loop label Mar 27, 2026
Copy link
Copy Markdown
Contributor

@dyc3 dyc3 left a comment

Choose a reason for hiding this comment

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

I can see that this fixes the issue, but I'm seeing a lot of cloning and .collect()/.to_vec(). These can cause performance problems, can we avoid them?

@dyc3 dyc3 merged commit 1dd4a56 into biomejs:main Mar 28, 2026
18 checks passed
@github-actions github-actions bot mentioned this pull request Mar 28, 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 M-Likely Agent This was likely an automated PR without a human in the loop

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐛 noNegationElse improperly handles comments in ternaries

2 participants