Skip to content

feat(css): add support for SCSS @use and @forward at-rules#9440

Merged
denbezrukov merged 13 commits intomainfrom
db/scss-at-rule
Mar 11, 2026
Merged

feat(css): add support for SCSS @use and @forward at-rules#9440
denbezrukov merged 13 commits intomainfrom
db/scss-at-rule

Conversation

@denbezrukov
Copy link
Contributor

Summary

Adds SCSS support for @use and @forward.

Test Plan

- `cargo test -p biome_css_parser`
- `cargo test -p biome_css_formatter`

@changeset-bot
Copy link

changeset-bot bot commented Mar 10, 2026

⚠️ No Changeset found

Latest commit: c36a4a4

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-Parser Area: parser A-Formatter Area: formatter A-Tooling Area: internal tools L-CSS Language: CSS and super languages L-Grit Language: GritQL labels Mar 10, 2026
@github-actions
Copy link
Contributor

Parser conformance results on

js/262

Test result main count This PR count Difference
Total 53079 53079 0
Passed 51859 51859 0
Failed 1178 1178 0
Panics 42 42 0
Coverage 97.70% 97.70% 0.00%

jsx/babel

Test result main count This PR count Difference
Total 38 38 0
Passed 37 37 0
Failed 1 1 0
Panics 0 0 0
Coverage 97.37% 97.37% 0.00%

markdown/commonmark

Test result main count This PR count Difference
Total 652 652 0
Passed 652 652 0
Failed 0 0 0
Panics 0 0 0
Coverage 100.00% 100.00% 0.00%

symbols/microsoft

Test result main count This PR count Difference
Total 5466 5466 0
Passed 1915 1915 0
Failed 3551 3551 0
Panics 0 0 0
Coverage 35.03% 35.03% 0.00%

ts/babel

Test result main count This PR count Difference
Total 636 636 0
Passed 568 568 0
Failed 68 68 0
Panics 0 0 0
Coverage 89.31% 89.31% 0.00%

ts/microsoft

Test result main count This PR count Difference
Total 18875 18875 0
Passed 13014 13014 0
Failed 5860 5860 0
Panics 1 1 0
Coverage 68.95% 68.95% 0.00%

@codspeed-hq
Copy link

codspeed-hq bot commented Mar 10, 2026

Merging this PR will not alter performance

✅ 58 untouched benchmarks
⏩ 156 skipped benchmarks1


Comparing db/scss-at-rule (c36a4a4) with main (8475d90)2

Open in CodSpeed

Footnotes

  1. 156 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 (f2debed) during the generation of this report, so 8475d90 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 10, 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

Adds comprehensive SCSS @forward and @use support: new syntax kinds and keywords; lexer keyword entries; extensive SCSS parsers (forward, use, module clauses, parameter lists) with recovery and diagnostics; parser re-exports; many new formatter modules and generated Format/AsFormat/IntoFormat bindings for SCSS nodes; removal of obsolete CSS bogus nodes and their formatter hooks; and test fixtures exercising ok/error cases for forward/use.

Possibly related PRs

Suggested reviewers

  • dyc3
  • ematipico
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(css): add support for SCSS @use and @forward at-rules' accurately describes the main changes—adding parser and formatter support for two SCSS at-rules with their associated clauses and syntax nodes.
Description check ✅ Passed The description directly relates to the changeset by stating it adds SCSS support for @use and @forward, and provides a clear test plan, though it's quite concise.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch db/scss-at-rule

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
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

🧹 Nitpick comments (2)
crates/biome_css_parser/src/syntax/scss/at_rule/parameter.rs (1)

21-30: Please turn these rustdoc samples into doctests.

The new scss fences help readers, but they won't be exercised by rustdoc and can drift quietly.

As per coding guidelines, "Use doc tests (doctest) format with code blocks in rustdoc comments; ensure assertions pass in tests".

Also applies to: 69-78

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_css_parser/src/syntax/scss/at_rule/parameter.rs` around lines 21
- 30, The SCSS code fences in the doc comment for the SCSS parameter parser are
using ```scss which prevents rustdoc from running them; update those examples in
parameter.rs to be actual doctests by replacing the ```scss fences with Rust
doctest fences (use ```rust or an unlabelled ``` so rustdoc treats them as
tests) and convert the sample into a small Rust doctest that invokes the parser
API (replace the SCSS snippet with a Rust example that calls the relevant
parsing function in this module and asserts expected output), and do the same
for the other sample at lines 69-78 so both examples are exercised by rustdoc
and their assertions pass.
crates/biome_css_parser/src/syntax/scss/at_rule/module_clauses.rs (1)

182-232: Consider adding diagnose_missing_element for configuration item lists.

Unlike ScssModuleMemberList, this implementation doesn't override diagnose_missing_element. If a trailing comma appears before ), the default diagnostic may be less helpful than a custom message like "Expected a configuration item after ,".

♻️ Optional: Add custom diagnostic for missing elements
     fn allow_empty(&self) -> bool {
         false
     }
+
+    fn diagnose_missing_element(&mut self, p: &mut Self::Parser<'_>) {
+        p.error(expected_scss_module_configuration(p, p.cur_range()));
+    }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_css_parser/src/syntax/scss/at_rule/module_clauses.rs` around
lines 182 - 232, ScssModuleConfigurationItemList lacks a custom
diagnose_missing_element override, so when a trailing comma appears before ')'
users get the generic diagnostic; implement diagnose_missing_element on
ScssModuleConfigurationItemList (similar to ScssModuleMemberList) to call
p.err_with_diagnostic or emit a specific message like "Expected a configuration
item after `,`" and reference the separating element T![,] and LIST_KIND
SCSS_MODULE_CONFIGURATION_ITEM_LIST so the parser reports the precise
missing-element diagnostic for configuration item lists.
🤖 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_css_parser/src/syntax/scss/at_rule/forward_at_rule.rs`:
- Around line 68-71: The code currently makes the hyphen optional in the "as
<prefix>-*" sequence by calling p.eat(T![-]) which accepts absence of '-' —
change this to p.expect(T![-]) so the parser requires the literal hyphen; update
the sequence around p.bump(T![as]) /
parse_regular_identifier(p).or_add_diagnostic(p, expected_identifier) to call
p.expect(T![-]) before p.expect(T![*]) to enforce the Sass spec requirement for
"as <prefix>-*".

---

Nitpick comments:
In `@crates/biome_css_parser/src/syntax/scss/at_rule/module_clauses.rs`:
- Around line 182-232: ScssModuleConfigurationItemList lacks a custom
diagnose_missing_element override, so when a trailing comma appears before ')'
users get the generic diagnostic; implement diagnose_missing_element on
ScssModuleConfigurationItemList (similar to ScssModuleMemberList) to call
p.err_with_diagnostic or emit a specific message like "Expected a configuration
item after `,`" and reference the separating element T![,] and LIST_KIND
SCSS_MODULE_CONFIGURATION_ITEM_LIST so the parser reports the precise
missing-element diagnostic for configuration item lists.

In `@crates/biome_css_parser/src/syntax/scss/at_rule/parameter.rs`:
- Around line 21-30: The SCSS code fences in the doc comment for the SCSS
parameter parser are using ```scss which prevents rustdoc from running them;
update those examples in parameter.rs to be actual doctests by replacing the
```scss fences with Rust doctest fences (use ```rust or an unlabelled ``` so
rustdoc treats them as tests) and convert the sample into a small Rust doctest
that invokes the parser API (replace the SCSS snippet with a Rust example that
calls the relevant parsing function in this module and asserts expected output),
and do the same for the other sample at lines 69-78 so both examples are
exercised by rustdoc and their assertions pass.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b5685968-edc4-4589-868c-86ccaad9e1fd

📥 Commits

Reviewing files that changed from the base of the PR and between 73205b9 and d05104c.

⛔ Files ignored due to path filters (12)
  • crates/biome_css_factory/src/generated/node_factory.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_css_factory/src/generated/syntax_factory.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_css_formatter/tests/specs/css/scss/at-rule/forward.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_formatter/tests/specs/css/scss/at-rule/use.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_parser/tests/css_test_suite/error/scss/at-rule/forward.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_parser/tests/css_test_suite/error/scss/at-rule/use.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_parser/tests/css_test_suite/ok/scss/at-rule/forward.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_parser/tests/css_test_suite/ok/scss/at-rule/use.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_syntax/src/generated/kind.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_css_syntax/src/generated/macros.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_css_syntax/src/generated/nodes.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_css_syntax/src/generated/nodes_mut.rs is excluded by !**/generated/**, !**/generated/** and included by **
📒 Files selected for processing (46)
  • crates/biome_css_formatter/src/css/any/at_rule.rs
  • crates/biome_css_formatter/src/css/any/ts_type.rs
  • crates/biome_css_formatter/src/css/bogus/bogus_declaration_item.rs
  • crates/biome_css_formatter/src/css/bogus/bogus_type.rs
  • crates/biome_css_formatter/src/css/bogus/mod.rs
  • crates/biome_css_formatter/src/generated.rs
  • crates/biome_css_formatter/src/scss/any/forward_visibility_clause.rs
  • crates/biome_css_formatter/src/scss/any/mod.rs
  • crates/biome_css_formatter/src/scss/any/module_configuration.rs
  • crates/biome_css_formatter/src/scss/any/use_namespace.rs
  • crates/biome_css_formatter/src/scss/auxiliary/forward_as_clause.rs
  • crates/biome_css_formatter/src/scss/auxiliary/hide_clause.rs
  • crates/biome_css_formatter/src/scss/auxiliary/mod.rs
  • crates/biome_css_formatter/src/scss/auxiliary/module_configuration.rs
  • crates/biome_css_formatter/src/scss/auxiliary/module_configuration_list.rs
  • crates/biome_css_formatter/src/scss/auxiliary/show_clause.rs
  • crates/biome_css_formatter/src/scss/auxiliary/use_all_namespace.rs
  • crates/biome_css_formatter/src/scss/auxiliary/use_as_clause.rs
  • crates/biome_css_formatter/src/scss/auxiliary/with_clause.rs
  • crates/biome_css_formatter/src/scss/lists/mod.rs
  • crates/biome_css_formatter/src/scss/lists/module_configuration_item_list.rs
  • crates/biome_css_formatter/src/scss/lists/module_member_list.rs
  • crates/biome_css_formatter/src/scss/statements/forward_at_rule.rs
  • crates/biome_css_formatter/src/scss/statements/mod.rs
  • crates/biome_css_formatter/src/scss/statements/use_at_rule.rs
  • crates/biome_css_formatter/tests/specs/css/scss/at-rule/forward.scss
  • crates/biome_css_formatter/tests/specs/css/scss/at-rule/use.scss
  • crates/biome_css_parser/src/lexer/mod.rs
  • crates/biome_css_parser/src/syntax/at_rule/mod.rs
  • crates/biome_css_parser/src/syntax/scss/at_rule/content_at_rule.rs
  • crates/biome_css_parser/src/syntax/scss/at_rule/forward_at_rule.rs
  • crates/biome_css_parser/src/syntax/scss/at_rule/include_at_rule.rs
  • crates/biome_css_parser/src/syntax/scss/at_rule/mod.rs
  • crates/biome_css_parser/src/syntax/scss/at_rule/module_clauses.rs
  • crates/biome_css_parser/src/syntax/scss/at_rule/parameter.rs
  • crates/biome_css_parser/src/syntax/scss/at_rule/use_at_rule.rs
  • crates/biome_css_parser/src/syntax/scss/mod.rs
  • crates/biome_css_parser/tests/css_test_suite/error/scss/at-rule/forward.scss
  • crates/biome_css_parser/tests/css_test_suite/error/scss/at-rule/use.scss
  • crates/biome_css_parser/tests/css_test_suite/ok/scss/at-rule/forward.scss
  • crates/biome_css_parser/tests/css_test_suite/ok/scss/at-rule/use.scss
  • crates/biome_css_syntax/src/lib.rs
  • crates/biome_grit_patterns/src/grit_target_language/css_target_language/generated_mappings.rs
  • crates/biome_parser/src/parse_lists.rs
  • xtask/codegen/css.ungram
  • xtask/codegen/src/css_kinds_src.rs
💤 Files with no reviewable changes (5)
  • crates/biome_css_formatter/src/css/bogus/mod.rs
  • crates/biome_css_formatter/src/css/any/ts_type.rs
  • crates/biome_css_formatter/src/css/bogus/bogus_type.rs
  • crates/biome_css_syntax/src/lib.rs
  • crates/biome_css_formatter/src/css/bogus/bogus_declaration_item.rs

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

♻️ Duplicate comments (1)
crates/biome_css_parser/src/syntax/scss/at_rule/forward_at_rule.rs (1)

66-69: ⚠️ Potential issue | 🟠 Major

The hyphen in as <prefix>-* should be required, not optional.

The Sass specification mandates as <prefix>-* with a literal hyphen. Using p.eat(T![-]) allows the parser to accept invalid syntax like @forward "theme" as foo*;.

🐛 Proposed fix
     p.bump(T![as]);
     parse_regular_identifier(p).or_add_diagnostic(p, expected_identifier);
-    p.eat(T![-]);
+    p.expect(T![-]);
     p.expect(T![*]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_css_parser/src/syntax/scss/at_rule/forward_at_rule.rs` around
lines 66 - 69, The hyphen in the `as <prefix>-*` production is currently
optional because the code uses `p.eat(T![-])`; change this to require the hyphen
by replacing `p.eat(T![-])` with `p.expect(T![-])` (keeping the surrounding
calls: `parse_regular_identifier(p).or_add_diagnostic(p, expected_identifier)`
and `p.expect(T![*])`) so the parser rejects inputs like `@forward "theme" as
foo*;` and reports a proper diagnostic when the hyphen is missing.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@crates/biome_css_parser/src/syntax/scss/at_rule/forward_at_rule.rs`:
- Around line 66-69: The hyphen in the `as <prefix>-*` production is currently
optional because the code uses `p.eat(T![-])`; change this to require the hyphen
by replacing `p.eat(T![-])` with `p.expect(T![-])` (keeping the surrounding
calls: `parse_regular_identifier(p).or_add_diagnostic(p, expected_identifier)`
and `p.expect(T![*])`) so the parser rejects inputs like `@forward "theme" as
foo*;` and reports a proper diagnostic when the hyphen is missing.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 94533b6a-c0c9-454b-b888-d9bc00877b26

📥 Commits

Reviewing files that changed from the base of the PR and between d05104c and 0c71183.

📒 Files selected for processing (7)
  • crates/biome_css_formatter/src/scss/auxiliary/hide_clause.rs
  • crates/biome_css_formatter/src/scss/auxiliary/module_configuration.rs
  • crates/biome_css_formatter/src/scss/auxiliary/show_clause.rs
  • crates/biome_css_formatter/src/scss/auxiliary/use_as_clause.rs
  • crates/biome_css_parser/src/syntax/scss/at_rule/forward_at_rule.rs
  • crates/biome_css_parser/src/syntax/scss/at_rule/module_clauses.rs
  • crates/biome_css_parser/src/syntax/scss/at_rule/use_at_rule.rs
🚧 Files skipped from review as they are similar to previous changes (3)
  • crates/biome_css_formatter/src/scss/auxiliary/module_configuration.rs
  • crates/biome_css_formatter/src/scss/auxiliary/show_clause.rs
  • crates/biome_css_formatter/src/scss/auxiliary/hide_clause.rs

Copy link
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 `@xtask/codegen/css.ungram`:
- Around line 2665-2688: The grammar node ScssModuleConfiguration currently ends
at value: ScssExpression and cannot represent the `!default` modifier; update
ScssModuleConfiguration to include an optional modifier (e.g., default: '!'? or
default: '!default' boolean) and adjust parsing to allow an optional `!default`
token following value: ScssExpression, ensuring AnyScssModuleConfiguration and
ScssModuleConfigurationItemList still accept the new form; update any relevant
comments/examples to show "$primary: blue !default" and ensure downstream
consumers of ScssModuleConfiguration (AST builders/visitors) handle the new
optional field.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2921e2a3-d5bd-40d6-833d-eab8bc9400e4

📥 Commits

Reviewing files that changed from the base of the PR and between 0c71183 and 77467bb.

⛔ Files ignored due to path filters (6)
  • crates/biome_css_factory/src/generated/node_factory.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_css_factory/src/generated/syntax_factory.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_css_parser/tests/css_test_suite/error/scss/at-rule/forward.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_parser/tests/css_test_suite/ok/scss/at-rule/forward.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_syntax/src/generated/nodes.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_css_syntax/src/generated/nodes_mut.rs is excluded by !**/generated/**, !**/generated/** and included by **
📒 Files selected for processing (4)
  • crates/biome_css_formatter/src/scss/auxiliary/forward_as_clause.rs
  • crates/biome_css_parser/src/syntax/scss/at_rule/forward_at_rule.rs
  • crates/biome_css_parser/tests/css_test_suite/error/scss/at-rule/forward.scss
  • xtask/codegen/css.ungram
🚧 Files skipped from review as they are similar to previous changes (3)
  • crates/biome_css_parser/tests/css_test_suite/error/scss/at-rule/forward.scss
  • crates/biome_css_formatter/src/scss/auxiliary/forward_as_clause.rs
  • crates/biome_css_parser/src/syntax/scss/at_rule/forward_at_rule.rs

@Netail Netail changed the title feat(css): add support for SCSS @use, @forward, @show, and @hide at-rules feat(css): add support for SCSS @use and @forward at-rules Mar 10, 2026
@Netail Netail added the L-SCSS label Mar 10, 2026
@github-actions github-actions bot added the A-Linter Area: linter label Mar 11, 2026
Copy link
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

🧹 Nitpick comments (2)
crates/biome_css_parser/src/syntax/scss/at_rule/module_clauses.rs (2)

143-146: Note: parse_scss_module_member_list always returns Present.

Since this function wraps parse_list() in Present unconditionally, callers using .or_add_diagnostic() will never trigger that diagnostic—the error path is handled internally via diagnose_missing_element. This works correctly but the caller-side .or_add_diagnostic() is effectively dead code.

Not blocking; the error handling is sound via the list implementation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_css_parser/src/syntax/scss/at_rule/module_clauses.rs` around
lines 143 - 146, The wrapper parse_scss_module_member_list always returns
Present by wrapping ScssModuleMemberList.parse_list(p), which prevents callers'
.or_add_diagnostic() from ever firing; change parse_scss_module_member_list to
return the ParsedSyntax produced by ScssModuleMemberList.parse_list(p) directly
(i.e., remove the unconditional Present(...) wrapper) so the Missing path
propagates to callers and .or_add_diagnostic() can work, leaving any internal
diagnose_missing_element logic inside the list implementation intact.

242-280: ScssModuleConfigurationItemList is missing diagnose_missing_element.

Unlike ScssModuleMemberList, this list relies solely on the recover() method for diagnostics. This works, but for consistency you may want to add the override here as well—especially if you want uniform error messages for trailing commas like with ($a: 1,).

Not blocking; current behaviour is acceptable.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_css_parser/src/syntax/scss/at_rule/module_clauses.rs` around
lines 242 - 280, Add a diagnose_missing_element override to the
ParseSeparatedList impl for ScssModuleConfigurationItemList so the parser emits
the same missing-element/trailing-comma diagnostics as ScssModuleMemberList;
implement diagnose_missing_element to produce a diagnostic when a separating
element (T![,]) is present but the next configuration is missing, reusing the
same recovery/expectation helpers (parse_scss_module_configuration,
ScssModuleConfigurationItemListRecovery, expected_scss_module_configuration) and
the list kind SCSS_MODULE_CONFIGURATION_ITEM_LIST so behavior matches the other
list implementation.
🤖 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_css_formatter/src/scss/auxiliary/with_clause.rs`:
- Around line 15-23: The code special-cases trailing `@forward` clauses to emit
`with(` (no separator) while other paths emit `with (`, causing inconsistent
normalization; update the formatter so all branches output the same separator
after with_token (i.e., always include space() between with_token.format() and
configurations.format()), removing the branch that writes with_token.format()
without a separator and changing the hard_space() case to space() as well; apply
the same change to the corresponding code block referenced at lines 28-45 (use
the same consistent write! pattern with with_token.format(), space(),
configurations.format()), letting the parent at-rule formatter handle line
placement.

---

Nitpick comments:
In `@crates/biome_css_parser/src/syntax/scss/at_rule/module_clauses.rs`:
- Around line 143-146: The wrapper parse_scss_module_member_list always returns
Present by wrapping ScssModuleMemberList.parse_list(p), which prevents callers'
.or_add_diagnostic() from ever firing; change parse_scss_module_member_list to
return the ParsedSyntax produced by ScssModuleMemberList.parse_list(p) directly
(i.e., remove the unconditional Present(...) wrapper) so the Missing path
propagates to callers and .or_add_diagnostic() can work, leaving any internal
diagnose_missing_element logic inside the list implementation intact.
- Around line 242-280: Add a diagnose_missing_element override to the
ParseSeparatedList impl for ScssModuleConfigurationItemList so the parser emits
the same missing-element/trailing-comma diagnostics as ScssModuleMemberList;
implement diagnose_missing_element to produce a diagnostic when a separating
element (T![,]) is present but the next configuration is missing, reusing the
same recovery/expectation helpers (parse_scss_module_configuration,
ScssModuleConfigurationItemListRecovery, expected_scss_module_configuration) and
the list kind SCSS_MODULE_CONFIGURATION_ITEM_LIST so behavior matches the other
list implementation.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 86f2d31b-1b64-4a77-95bf-688a1bec75a0

📥 Commits

Reviewing files that changed from the base of the PR and between 383ea3f and a9667ac.

⛔ Files ignored due to path filters (10)
  • crates/biome_css_factory/src/generated/node_factory.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_css_factory/src/generated/syntax_factory.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_css_formatter/tests/specs/css/scss/at-rule/forward.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_formatter/tests/specs/css/scss/at-rule/use.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_parser/tests/css_test_suite/error/scss/at-rule/forward.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_parser/tests/css_test_suite/error/scss/at-rule/use.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_parser/tests/css_test_suite/ok/scss/at-rule/forward.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_parser/tests/css_test_suite/ok/scss/at-rule/use.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_syntax/src/generated/nodes.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_css_syntax/src/generated/nodes_mut.rs is excluded by !**/generated/**, !**/generated/** and included by **
📒 Files selected for processing (14)
  • crates/biome_css_formatter/src/scss/auxiliary/forward_as_clause.rs
  • crates/biome_css_formatter/src/scss/auxiliary/hide_clause.rs
  • crates/biome_css_formatter/src/scss/auxiliary/module_configuration.rs
  • crates/biome_css_formatter/src/scss/auxiliary/module_configuration_list.rs
  • crates/biome_css_formatter/src/scss/auxiliary/show_clause.rs
  • crates/biome_css_formatter/src/scss/auxiliary/with_clause.rs
  • crates/biome_css_formatter/tests/specs/css/scss/at-rule/forward.scss
  • crates/biome_css_formatter/tests/specs/css/scss/at-rule/use.scss
  • crates/biome_css_parser/src/syntax/scss/at_rule/forward_at_rule.rs
  • crates/biome_css_parser/src/syntax/scss/at_rule/module_clauses.rs
  • crates/biome_css_parser/tests/css_test_suite/error/scss/at-rule/use.scss
  • crates/biome_css_parser/tests/css_test_suite/ok/scss/at-rule/forward.scss
  • crates/biome_css_parser/tests/css_test_suite/ok/scss/at-rule/use.scss
  • xtask/codegen/css.ungram
🚧 Files skipped from review as they are similar to previous changes (4)
  • crates/biome_css_formatter/tests/specs/css/scss/at-rule/use.scss
  • crates/biome_css_parser/tests/css_test_suite/ok/scss/at-rule/use.scss
  • crates/biome_css_formatter/src/scss/auxiliary/forward_as_clause.rs
  • crates/biome_css_parser/tests/css_test_suite/ok/scss/at-rule/forward.scss

@denbezrukov denbezrukov merged commit f4d2073 into main Mar 11, 2026
31 checks passed
@denbezrukov denbezrukov deleted the db/scss-at-rule branch March 11, 2026 13:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Formatter Area: formatter A-Linter Area: linter A-Parser Area: parser A-Tooling Area: internal tools L-CSS Language: CSS and super languages L-Grit Language: GritQL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants