fix(css_formatter): preserve pseudo function comments - #11285
Conversation
🦋 Changeset detectedLatest commit: 88636a2 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 |
✅ Organic activityNo automation signals detected in the analyzed events. This is an automated analysis by AgentScan |
WalkthroughThe CSS formatter now preserves comments at CSS and SCSS pseudo-function boundaries. It attaches comments before opening parentheses to the function name, comments inside non-empty functions to following arguments, and comments in empty functions as dangling comments. CSS and SCSS pseudo-function formatters now handle empty and non-empty contents separately. SCSS interpolation utilities use a shared crate-visible module. New fixtures cover CSS, SCSS, pseudo-elements, pseudo-classes, and selector interpolation. Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@crates/biome_css_formatter/src/comments.rs`:
- Around line 405-416: Extend the is_empty_function check in the
comment-placement logic to recognize empty CssPseudoClassFunction nodes,
alongside the existing SCSS functions and CssPseudoElementFunction, so internal
comments in :where(/* comment */) remain dangling. Add a CSS formatter snapshot
test covering an empty functional pseudo-class with an internal comment.
🪄 Autofix
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 Plus
Run ID: 07d69acc-086b-45ef-9326-e718274afda6
⛔ Files ignored due to path filters (4)
crates/biome_css_formatter/tests/specs/css/pseudo/pseudo_element_selector.css.snapis excluded by!**/*.snapand included by**crates/biome_css_formatter/tests/specs/css/selectors/pseudo_class/pseudo_class_function_comments.css.snapis excluded by!**/*.snapand included by**crates/biome_css_formatter/tests/specs/prettier/css/comments/selectors.css.snapis excluded by!**/*.snapand included by**crates/biome_css_formatter/tests/specs/scss/selector/interpolation.scss.snapis excluded by!**/*.snapand included by**
📒 Files selected for processing (14)
.changeset/fast-boxes-bow.mdcrates/biome_css_formatter/src/comments.rscrates/biome_css_formatter/src/css/pseudo/pseudo_element_function.rscrates/biome_css_formatter/src/scss/auxiliary/interpolated_string.rscrates/biome_css_formatter/src/scss/auxiliary/string_text.rscrates/biome_css_formatter/src/scss/pseudo/interpolated_pseudo_class_function.rscrates/biome_css_formatter/src/scss/pseudo/interpolated_pseudo_element_function.rscrates/biome_css_formatter/src/utils/mod.rscrates/biome_css_formatter/src/utils/scss_interpolated_string.rscrates/biome_css_formatter/src/utils/scss_interpolated_string/quotes.rscrates/biome_css_formatter/src/utils/scss_interpolated_string/raw_interpolation.rscrates/biome_css_formatter/tests/specs/css/pseudo/pseudo_element_selector.csscrates/biome_css_formatter/tests/specs/css/selectors/pseudo_class/pseudo_class_function_comments.csscrates/biome_css_formatter/tests/specs/scss/selector/interpolation.scss
| // Empty functions have no argument node that can own the comment. | ||
| let is_empty_function = ScssInterpolatedPseudoClassFunction::cast_ref(&function) | ||
| .is_some_and(|function| function.arguments().is_none()) | ||
| || ScssInterpolatedPseudoElementFunction::cast_ref(&function) | ||
| .is_some_and(|function| function.arguments().is_none()) | ||
| || CssPseudoElementFunction::cast_ref(&function) | ||
| .is_some_and(|function| function.items().is_empty()); | ||
|
|
||
| if is_empty_function { | ||
| CommentPlacement::dangling(function, comment) | ||
| } else { | ||
| CommentPlacement::leading(name.into_syntax(), comment) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Handle empty CSS pseudo-classes.
Line 405 checks empty SCSS pseudo-functions and CSS pseudo-elements, but not empty CSS pseudo-classes. Therefore :where(/* comment */) falls through to leading(name, comment) and can move the comment before the function name again.
Include the CSS functional pseudo-class node in this check. Add a CSS snapshot case for an empty functional pseudo-class with an internal comment.
As per coding guidelines, all code changes must include appropriate tests.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@crates/biome_css_formatter/src/comments.rs` around lines 405 - 416, Extend
the is_empty_function check in the comment-placement logic to recognize empty
CssPseudoClassFunction nodes, alongside the existing SCSS functions and
CssPseudoElementFunction, so internal comments in :where(/* comment */) remain
dangling. Add a CSS formatter snapshot test covering an empty functional
pseudo-class with an internal comment.
Source: Coding guidelines
Merging this PR will not alter performance
Comparing Footnotes
|
This PR contains the following updates: | Package | Type | Update | Change | Pending | |---|---|---|---|---| | [@biomejs/biome](https://biomejs.dev) ([source](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome)) | imports | patch | [`2.5.7` -> `2.5.8`](https://renovatebot.com/diffs/npm/@biomejs%2fbiome/2.5.7/2.5.8) | `2.5.9` | --- ### Release Notes <details> <summary>biomejs/biome (@​biomejs/biome)</summary> ### [`v2.5.8`](https://github.com/biomejs/biome/blob/HEAD/packages/@​biomejs/biome/CHANGELOG.md#258) [Compare Source](https://github.com/biomejs/biome/compare/@biomejs/biome@2.5.7...@biomejs/biome@2.5.8) ##### Patch Changes - [#​10710](biomejs/biome#10710) [`0a0fbc1`](biomejs/biome@0a0fbc1) Thanks [@​dyc3](https://github.com/dyc3)! - Added a new nursery rule [`useReactCompiler`](https://biomejs.dev/linter/rules/use-react-compiler/), which reports diagnostics from React Compiler lint mode. - [#​11251](biomejs/biome#11251) [`ea9dd8a`](biomejs/biome@ea9dd8a) Thanks [@​dyc3](https://github.com/dyc3)! - Improved performance of [`noImportCycles`](https://biomejs.dev/linter/rules/no-import-cycles/). - [#​11247](biomejs/biome#11247) [`52b44d6`](biomejs/biome@52b44d6) Thanks [@​dyc3](https://github.com/dyc3)! - Added the nursery rule [`noSvelteLegacyConst`](https://biomejs.dev/linter/rules/no-svelte-legacy-const/), which disallows legacy Svelte `{@const}` tags and recommends declaration tags with `$derived()`. Invalid: ```svelte {#each boxes as box} {@const area = box.width * box.height} <p>{area}</p> {/each} ``` Valid: ```svelte {#each boxes as box} {const area = $derived(box.width * box.height)} <p>{area}</p> {/each} ``` - [#​11252](biomejs/biome#11252) [`d5f5704`](biomejs/biome@d5f5704) Thanks [@​Turtle-Hwan](https://github.com/Turtle-Hwan)! - Fixed [#​11250](biomejs/biome#11250): [`useAwait`](https://biomejs.dev/linter/rules/use-await/) no longer reports async functions that contain an `await using` declaration. - [#​11143](biomejs/biome#11143) [`6be7be1`](biomejs/biome@6be7be1) Thanks [@​vznh](https://github.com/vznh)! - Fixed [#​11017](biomejs/biome#11017): [`noUselessUndefined`](https://biomejs.dev/linter/rules/no-useless-undefined/) no longer reports `return undefined` when the enclosing function has a return type annotation other than `undefined` or `void`. - [#​11234](biomejs/biome#11234) [`caefe39`](biomejs/biome@caefe39) Thanks [@​subotac](https://github.com/subotac)! - Fixed [#​11228](biomejs/biome#11228): CSS block comments between a declaration colon and value now preserve their source indentation. ```diff :root { --font-stack: -/* comment */ + /* comment */ system-ui; } ``` - [#​11285](biomejs/biome#11285) [`bca1f73`](biomejs/biome@bca1f73) Thanks [@​denbezrukov](https://github.com/denbezrukov)! - Fixed [#​11280](biomejs/biome#11280): CSS formatting keeps comments inside functional pseudo-classes and pseudo-elements instead of moving them before the function name. ```diff -:/* comment */ where(div) {} +:where(/* comment */ div) {} ``` - [#​11080](biomejs/biome#11080) [`af16a0b`](biomejs/biome@af16a0b) Thanks [@​dyc3](https://github.com/dyc3)! - HTML `style` attribute values are now parsed as CSS. All Biome CSS lint rules are applied to the `style` attributes. - [#​11195](biomejs/biome#11195) [`6a85588`](biomejs/biome@6a85588) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed Svelte files failing to parse when an expression begins with an object literal. Now the following snippet is correctly parsed: ```svelte <p>{{ a: true }}</p> <div class={{ active: isActive }}></div> ``` - [#​11173](biomejs/biome#11173) [`481d008`](biomejs/biome@481d008) Thanks [@​Austin1serb](https://github.com/Austin1serb)! - Fixed [#​10242](biomejs/biome#10242): JavaScript GritQL patterns with multiple metavariables now match snippets consistently in WebAssembly. - [#​11187](biomejs/biome#11187) [`23c0369`](biomejs/biome@23c0369) Thanks [@​ematipico](https://github.com/ematipico)! - Added the nursery rule [`noInvalidPropertyInitValue`](https://biomejs.dev/linter/rules/no-invalid-property-init-value/), which reports an `@property` whose `initial-value` does not match its `syntax` descriptor. For example, the following declaration triggers the rule because `red` is not a `<length>`: ```css @Property --size { syntax: "<length>"; inherits: false; initial-value: red; } ``` - [#​11272](biomejs/biome#11272) [`73896e6`](biomejs/biome@73896e6) Thanks [@​ematipico](https://github.com/ematipico)! - Improved the diagnostic emitted by [`noRootType`](https://biomejs.dev/linter/rules/no-root-type). - [#​11240](biomejs/biome#11240) [`bd0b68d`](biomejs/biome@bd0b68d) Thanks [@​ematipico](https://github.com/ematipico)! - Fixed [#​11223](biomejs/biome#11223): Improved the performance of [`noMisusedPromises`](https://biomejs.dev/linter/rules/no-misused-promises/) when analyzing async class methods that call other methods through `this`. - [#​11172](biomejs/biome#11172) [`4a0bc5c`](biomejs/biome@4a0bc5c) Thanks [@​saberoueslati](https://github.com/saberoueslati)! - Fixed [#​10806](biomejs/biome#10806): [`noUselessFragments`](https://biomejs.dev/linter/rules/no-useless-fragments/) no longer causes Biome to panic when its unsafe fix removes a fragment used as a JSX attribute value. - [#​11227](biomejs/biome#11227) [`4d603b0`](biomejs/biome@4d603b0) Thanks [@​saberoueslati](https://github.com/saberoueslati)! - Fixed [#​11178](biomejs/biome#11178): [`noUndeclaredVariables`](https://biomejs.dev/linter/rules/no-undeclared-variables/) no longer reports Vue's built-in instance properties, such as `$slots` and `$attrs`, in template expressions or `$event` in inline event-handler expressions. The instance properties are still reported inside `<script setup>`, where they are not defined. - [#​11187](biomejs/biome#11187) [`23c0369`](biomejs/biome@23c0369) Thanks [@​ematipico](https://github.com/ematipico)! - Fixed CSS parsing of registered custom properties: Biome now correctly validates the `syntax` descriptor of `@property` rules. </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate CLI](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4zMC4zIiwidXBkYXRlZEluVmVyIjoiNDQuMzAuMyIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==--> Reviewed-on: https://git.oirnoir.dev/OIRNOIR/YouTube-Helper-Client/pulls/17
This PR contains the following updates: | Package | Type | Update | Change | Pending | |---|---|---|---|---| | [@biomejs/biome](https://biomejs.dev) ([source](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome)) | imports | patch | [`2.5.7` -> `2.5.8`](https://renovatebot.com/diffs/npm/@biomejs%2fbiome/2.5.7/2.5.8) | `2.5.9` | --- ### Release Notes <details> <summary>biomejs/biome (@​biomejs/biome)</summary> ### [`v2.5.8`](https://github.com/biomejs/biome/blob/HEAD/packages/@​biomejs/biome/CHANGELOG.md#258) [Compare Source](https://github.com/biomejs/biome/compare/@biomejs/biome@2.5.7...@biomejs/biome@2.5.8) ##### Patch Changes - [#​10710](biomejs/biome#10710) [`0a0fbc1`](biomejs/biome@0a0fbc1) Thanks [@​dyc3](https://github.com/dyc3)! - Added a new nursery rule [`useReactCompiler`](https://biomejs.dev/linter/rules/use-react-compiler/), which reports diagnostics from React Compiler lint mode. - [#​11251](biomejs/biome#11251) [`ea9dd8a`](biomejs/biome@ea9dd8a) Thanks [@​dyc3](https://github.com/dyc3)! - Improved performance of [`noImportCycles`](https://biomejs.dev/linter/rules/no-import-cycles/). - [#​11247](biomejs/biome#11247) [`52b44d6`](biomejs/biome@52b44d6) Thanks [@​dyc3](https://github.com/dyc3)! - Added the nursery rule [`noSvelteLegacyConst`](https://biomejs.dev/linter/rules/no-svelte-legacy-const/), which disallows legacy Svelte `{@const}` tags and recommends declaration tags with `$derived()`. Invalid: ```svelte {#each boxes as box} {@const area = box.width * box.height} <p>{area}</p> {/each} ``` Valid: ```svelte {#each boxes as box} {const area = $derived(box.width * box.height)} <p>{area}</p> {/each} ``` - [#​11252](biomejs/biome#11252) [`d5f5704`](biomejs/biome@d5f5704) Thanks [@​Turtle-Hwan](https://github.com/Turtle-Hwan)! - Fixed [#​11250](biomejs/biome#11250): [`useAwait`](https://biomejs.dev/linter/rules/use-await/) no longer reports async functions that contain an `await using` declaration. - [#​11143](biomejs/biome#11143) [`6be7be1`](biomejs/biome@6be7be1) Thanks [@​vznh](https://github.com/vznh)! - Fixed [#​11017](biomejs/biome#11017): [`noUselessUndefined`](https://biomejs.dev/linter/rules/no-useless-undefined/) no longer reports `return undefined` when the enclosing function has a return type annotation other than `undefined` or `void`. - [#​11234](biomejs/biome#11234) [`caefe39`](biomejs/biome@caefe39) Thanks [@​subotac](https://github.com/subotac)! - Fixed [#​11228](biomejs/biome#11228): CSS block comments between a declaration colon and value now preserve their source indentation. ```diff :root { --font-stack: -/* comment */ + /* comment */ system-ui; } ``` - [#​11285](biomejs/biome#11285) [`bca1f73`](biomejs/biome@bca1f73) Thanks [@​denbezrukov](https://github.com/denbezrukov)! - Fixed [#​11280](biomejs/biome#11280): CSS formatting keeps comments inside functional pseudo-classes and pseudo-elements instead of moving them before the function name. ```diff -:/* comment */ where(div) {} +:where(/* comment */ div) {} ``` - [#​11080](biomejs/biome#11080) [`af16a0b`](biomejs/biome@af16a0b) Thanks [@​dyc3](https://github.com/dyc3)! - HTML `style` attribute values are now parsed as CSS. All Biome CSS lint rules are applied to the `style` attributes. - [#​11195](biomejs/biome#11195) [`6a85588`](biomejs/biome@6a85588) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed Svelte files failing to parse when an expression begins with an object literal. Now the following snippet is correctly parsed: ```svelte <p>{{ a: true }}</p> <div class={{ active: isActive }}></div> ``` - [#​11173](biomejs/biome#11173) [`481d008`](biomejs/biome@481d008) Thanks [@​Austin1serb](https://github.com/Austin1serb)! - Fixed [#​10242](biomejs/biome#10242): JavaScript GritQL patterns with multiple metavariables now match snippets consistently in WebAssembly. - [#​11187](biomejs/biome#11187) [`23c0369`](biomejs/biome@23c0369) Thanks [@​ematipico](https://github.com/ematipico)! - Added the nursery rule [`noInvalidPropertyInitValue`](https://biomejs.dev/linter/rules/no-invalid-property-init-value/), which reports an `@property` whose `initial-value` does not match its `syntax` descriptor. For example, the following declaration triggers the rule because `red` is not a `<length>`: ```css @Property --size { syntax: "<length>"; inherits: false; initial-value: red; } ``` - [#​11272](biomejs/biome#11272) [`73896e6`](biomejs/biome@73896e6) Thanks [@​ematipico](https://github.com/ematipico)! - Improved the diagnostic emitted by [`noRootType`](https://biomejs.dev/linter/rules/no-root-type). - [#​11240](biomejs/biome#11240) [`bd0b68d`](biomejs/biome@bd0b68d) Thanks [@​ematipico](https://github.com/ematipico)! - Fixed [#​11223](biomejs/biome#11223): Improved the performance of [`noMisusedPromises`](https://biomejs.dev/linter/rules/no-misused-promises/) when analyzing async class methods that call other methods through `this`. - [#​11172](biomejs/biome#11172) [`4a0bc5c`](biomejs/biome@4a0bc5c) Thanks [@​saberoueslati](https://github.com/saberoueslati)! - Fixed [#​10806](biomejs/biome#10806): [`noUselessFragments`](https://biomejs.dev/linter/rules/no-useless-fragments/) no longer causes Biome to panic when its unsafe fix removes a fragment used as a JSX attribute value. - [#​11227](biomejs/biome#11227) [`4d603b0`](biomejs/biome@4d603b0) Thanks [@​saberoueslati](https://github.com/saberoueslati)! - Fixed [#​11178](biomejs/biome#11178): [`noUndeclaredVariables`](https://biomejs.dev/linter/rules/no-undeclared-variables/) no longer reports Vue's built-in instance properties, such as `$slots` and `$attrs`, in template expressions or `$event` in inline event-handler expressions. The instance properties are still reported inside `<script setup>`, where they are not defined. - [#​11187](biomejs/biome#11187) [`23c0369`](biomejs/biome@23c0369) Thanks [@​ematipico](https://github.com/ematipico)! - Fixed CSS parsing of registered custom properties: Biome now correctly validates the `syntax` descriptor of `@property` rules. </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate CLI](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4zMC4zIiwidXBkYXRlZEluVmVyIjoiNDQuMzAuMyIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==--> Reviewed-on: https://git.oirnoir.dev/OIRNOIR/YouTube-Helper-Server/pulls/36
Summary
Fixes #11280
Preserves comments inside functional pseudo-selectors.
Regression introduced by commit.
Also relocates handwritten SCSS helpers so formatter codegen preserves them.
Test Plan
cargo test -p biome_css_formatter