-
-
Notifications
You must be signed in to change notification settings - Fork 808
feat(scss): add basic SCSS declaration support and comments #8721
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
base: next
Are you sure you want to change the base?
Conversation
|
Merging this PR will not alter performance
Comparing Footnotes
|
b0432c2 to
f85d89d
Compare
WalkthroughAdds SCSS support across the codebase: new grammar nodes and tokens (ScssDeclaration, ScssIdentifier, ScssNamespacedIdentifier, ScssVariableModifier and lists, and DOLLAR), parser and lexer changes to recognise SCSS identifiers, nested comments and SCSS declarations, a CssFileSource language flag propagated into token source and parser, SCSS-specific parse modules and diagnostics, formatter rules and generated formatter wiring for SCSS nodes, new SCSS formatter modules, and expanded test fixtures/globs to include .scss files. Possibly related PRs
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
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @crates/biome_css_formatter/src/scss/lists/variable_modifier_list.rs:
- Around line 1-10: The formatter for ScssVariableModifierList currently uses
f.join() which preserves source trivia and can leave modifiers stuck together;
update the fmt implementation in FormatScssVariableModifierList to use
f.join_with(space()) when composing entries(node.iter().formatted()) so
modifiers are separated with a single space (i.e., replace the join() call with
join_with(space()) to normalize sequences like !global !default).
🧹 Nitpick comments (5)
crates/biome_css_parser/tests/css_test_suite/ok/scss/comment/nested.scss (1)
24-25: Consider removing trailing blank lines.Trailing blank lines at EOF are typically unnecessary unless specifically testing whitespace handling.
crates/biome_css_parser/tests/css_test_suite/ok/scss/comment/line.scss (1)
7-9: Consider removing trailing blank lines.Multiple trailing blank lines at EOF are typically unnecessary unless specifically testing whitespace handling.
crates/biome_css_analyze/src/assist/source/use_sorted_properties.rs (1)
245-245: Consider ordering SCSS declarations like custom properties.SCSS variable declarations (e.g.,
$primary-color: #ff0000;) are conceptually similar to CSS custom properties (--primary-color: #ff0000;). Mapping them toNodeKindOrder::UnknownKindplaces them after nested rules, whilst custom properties are sorted first viaNodeKindOrder::CustomProperty. For consistency, SCSS declarations might benefit fromCustomPropertyordering or a dedicated ordering category.</comment_end>
Also applies to: 251-251
crates/biome_css_parser/tests/spec_test.rs (1)
41-100: SCSS test routing looks correct; consider fixing snapshot fences for readability. Right now.scsscases will still render under acsscode fence (Line 108).Proposed tweak (keeps snapshots clearer)
@@ - writeln!(snapshot, "\n## Input\n\n```css\n{content}\n```\n\n").unwrap(); + let fence_lang = if extension == "scss" { "scss" } else { "css" }; + writeln!(snapshot, "\n## Input\n\n```{fence_lang}\n{content}\n```\n\n").unwrap();Also applies to: 108-109
crates/biome_css_syntax/src/file_source.rs (1)
172-211: Worth considering:.module.scsswell-known handling.Right now only
.module.cssgets special-cased; SCSS modules are fairly common in the wild.Possible extension
pub fn try_from_well_known(path: &Utf8Path) -> Result<Self, FileSourceError> { let file_name = path.file_name().ok_or(FileSourceError::MissingFileName)?; if file_name.ends_with(".module.css") { return Self::try_from_extension("module.css"); } + if file_name.ends_with(".module.scss") { + return Ok(Self::scss().with_css_modules()); + }
ematipico
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.
That's a good start! I left some feedback that needs some attention
.changeset/short-emus-know.md
Outdated
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 changesest isn't needed at the moment, because end-users can't use it yet. Biome doesn't load .scss files yet.
We will be ready to create a changeset only when Biome is able to load these files.
I believe it's better to create an umbrella issue and close the discussion #3441 , it will send a good message
crates/biome_css_formatter/tests/specs/css/scss/declaration/global-flag.scss.snap
Outdated
Show resolved
Hide resolved
crates/biome_css_formatter/tests/specs/css/scss/declaration/mixed.scss.snap
Outdated
Show resolved
Hide resolved
crates/biome_css_formatter/tests/specs/css/scss/declaration/simple-variable.scss.snap
Outdated
Show resolved
Hide resolved
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 (2)
crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-modifier.scss (1)
7-8: Verify: Does this test case intentionally test multiple errors?This test case appears to test two error conditions simultaneously: the missing modifier after
!and the missing semicolon. For clarity, consider either:
- Splitting this into separate test cases (one with
$height: 50vh !;for missing modifier only)- Updating the comment to explicitly note both error conditions being tested
crates/biome_css_formatter/tests/spec_test.rs (1)
58-62: Minor formatting inconsistency.Line 60 has an extra space before
else. Otherwise, the conditional logic correctly selects SCSS language when appropriate.✨ Suggested fix
let language = if source_type.is_scss() { language::CssTestFormatLanguage::scss() - } else { + } else { language::CssTestFormatLanguage::default() };
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (6)
crates/biome_css_formatter/tests/specs/css/scss/declaration/global-flag.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_formatter/tests/specs/css/scss/declaration/mixed.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_formatter/tests/specs/css/scss/declaration/namespaced.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_formatter/tests/specs/css/scss/declaration/simple-variable.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/invalid-modifier.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-modifier.scss.snapis excluded by!**/*.snapand included by**
📒 Files selected for processing (14)
crates/biome_css_formatter/src/scss/auxiliary/declaration.rscrates/biome_css_formatter/src/scss/lists/variable_modifier_list.rscrates/biome_css_formatter/tests/language.rscrates/biome_css_formatter/tests/quick_test.rscrates/biome_css_formatter/tests/spec_test.rscrates/biome_css_formatter/tests/specs/css/scss/declaration/global-flag.scsscrates/biome_css_formatter/tests/specs/css/scss/declaration/mixed.scsscrates/biome_css_formatter/tests/specs/css/scss/declaration/namespaced.scsscrates/biome_css_formatter/tests/specs/css/scss/declaration/simple-variable.scsscrates/biome_css_parser/src/syntax/scss.rscrates/biome_css_parser/tests/css_test_suite/error/scss/declaration/invalid-modifier.scsscrates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-modifier.scsscrates/biome_css_syntax/src/lib.rscrates/biome_css_syntax/src/scss_ext.rs
🚧 Files skipped from review as they are similar to previous changes (4)
- crates/biome_css_formatter/src/scss/lists/variable_modifier_list.rs
- crates/biome_css_formatter/tests/specs/css/scss/declaration/simple-variable.scss
- crates/biome_css_parser/src/syntax/scss.rs
- crates/biome_css_formatter/tests/specs/css/scss/declaration/mixed.scss
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs
📄 CodeRabbit inference engine (CONTRIBUTING.md)
**/*.rs: Use inline rustdoc documentation for rules, assists, and their options
Use thedbg!()macro for debugging output in Rust tests and code
Use doc tests (doctest) format with code blocks in rustdoc comments; ensure assertions pass in tests
Files:
crates/biome_css_formatter/tests/language.rscrates/biome_css_syntax/src/lib.rscrates/biome_css_formatter/tests/quick_test.rscrates/biome_css_syntax/src/scss_ext.rscrates/biome_css_formatter/src/scss/auxiliary/declaration.rscrates/biome_css_formatter/tests/spec_test.rs
🧠 Learnings (34)
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/tests/language.rs : Implement `TestFormatLanguage` trait in `tests/language.rs` for the formatter's test language
Applied to files:
crates/biome_css_formatter/tests/language.rscrates/biome_css_syntax/src/lib.rscrates/biome_css_formatter/tests/quick_test.rscrates/biome_css_formatter/tests/spec_test.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/src/context.rs : Define `<Language>FormatContext` struct in a `context.rs` file containing `comments` and `source_map` fields, implementing `FormatContext` and `CstFormatContext` traits
Applied to files:
crates/biome_css_formatter/tests/language.rscrates/biome_css_syntax/src/lib.rscrates/biome_css_formatter/tests/quick_test.rscrates/biome_css_formatter/src/scss/auxiliary/declaration.rscrates/biome_css_formatter/tests/spec_test.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/language_kind.rs : Add a new variant to `LanguageKind` enum in `language_kind.rs` file and implement all methods for the new language variant
Applied to files:
crates/biome_css_formatter/tests/language.rscrates/biome_css_syntax/src/lib.rscrates/biome_css_syntax/src/scss_ext.rscrates/biome_css_formatter/tests/spec_test.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/src/lib.rs : Define a type alias `<Language>Formatter<'buf>` as `Formatter<'buf, <Language>FormatContext>` in the main formatter crate
Applied to files:
crates/biome_css_formatter/tests/language.rscrates/biome_css_syntax/src/lib.rscrates/biome_css_formatter/tests/spec_test.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/tests/spec_tests.rs : Use the `tests_macros::gen_tests!` macro in `spec_tests.rs` to generate test functions for each specification file matching the pattern `tests/specs/<language>/**/*.<ext>`
Applied to files:
crates/biome_css_formatter/tests/language.rscrates/biome_css_formatter/tests/quick_test.rscrates/biome_css_formatter/tests/spec_test.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/language_kind.rs : Add a new language prefix to the `LANGUAGE_PREFIXES` constant in `language_kind.rs` file
Applied to files:
crates/biome_css_formatter/tests/language.rscrates/biome_css_syntax/src/lib.rscrates/biome_css_formatter/tests/spec_test.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/src/comments.rs : Define `<Language>CommentStyle` as a public type alias for `Comments<<Language>Language>` in a `comments.rs` file
Applied to files:
crates/biome_css_formatter/tests/language.rscrates/biome_css_syntax/src/lib.rscrates/biome_css_formatter/tests/spec_test.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/*_kinds_src.rs : Create a file called `src/{language}_kinds_src.rs` that returns a static `KindSrc` for new language parsers
Applied to files:
crates/biome_css_formatter/tests/language.rscrates/biome_css_syntax/src/lib.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Implement the `FormatLanguage` trait with `SyntaxLanguage`, `Context`, and `FormatRule` associated types for the language's formatter
Applied to files:
crates/biome_css_formatter/tests/language.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Create two new crates `biome_{language}_syntax` and `biome_{language}_factory` using `cargo new --lib` for new language parsers
Applied to files:
crates/biome_css_syntax/src/lib.rscrates/biome_css_formatter/tests/spec_test.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Implement a token source struct that wraps the lexer and implements `TokenSourceWithBufferedLexer` and `LexerWithCheckpoint` for lookahead and re-lexing capabilities
Applied to files:
crates/biome_css_syntax/src/lib.rscrates/biome_css_formatter/tests/spec_test.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Use `ConditionalParsedSyntax` for syntax that is only valid in specific contexts (e.g., strict mode, file types, language versions) and call `or_invalid_to_bogus()` to convert to a bogus node if not supported
Applied to files:
crates/biome_css_syntax/src/lib.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Define `FormatHtmlSyntaxNode` struct in a `cst.rs` file implementing `FormatRule<HtmlSyntaxNode>`, `AsFormat<HtmlFormatContext>`, and `IntoFormat<HtmlFormatContext>` traits using the provided boilerplate code
Applied to files:
crates/biome_css_syntax/src/lib.rscrates/biome_css_formatter/src/scss/auxiliary/declaration.rs
📚 Learning: 2025-11-24T18:05:27.810Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:27.810Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Import the `FormatNode` trait and implement it for your Node when creating formatters in biome_js_formatter
Applied to files:
crates/biome_css_syntax/src/lib.rscrates/biome_css_formatter/src/scss/auxiliary/declaration.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/*.ungram : Nodes for enclosing syntax errors must have the `Bogus` word, e.g., `HtmlBogusAttribute`, and must be part of a variant
Applied to files:
crates/biome_css_syntax/src/lib.rs
📚 Learning: 2025-11-24T18:05:27.810Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:27.810Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : When formatting AST nodes, use mandatory tokens from the AST instead of hardcoding token strings (e.g., use `node.l_paren_token().format()` instead of `token("(")`)
Applied to files:
crates/biome_css_syntax/src/lib.rscrates/biome_css_formatter/tests/quick_test.rscrates/biome_css_formatter/src/scss/auxiliary/declaration.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/lexer/mod.rs : Implement a `Lexer` trait from `biome_parser` crate for the lexer struct that consumes characters from source code and emits tokens
Applied to files:
crates/biome_css_syntax/src/lib.rs
📚 Learning: 2025-12-04T13:29:49.287Z
Learnt from: dyc3
Repo: biomejs/biome PR: 8291
File: crates/biome_html_formatter/tests/specs/prettier/vue/html-vue/elastic-header.html:10-10
Timestamp: 2025-12-04T13:29:49.287Z
Learning: Files under `crates/biome_html_formatter/tests/specs/prettier` are test fixtures synced from Prettier and should not receive detailed code quality reviews (e.g., HTTP vs HTTPS, formatting suggestions, etc.). These files are test data meant to validate formatter behavior and should be preserved as-is.
Applied to files:
crates/biome_css_formatter/tests/quick_test.rscrates/biome_css_formatter/tests/spec_test.rscrates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-modifier.scss
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/Cargo.toml : Include development dependencies in `Cargo.toml` for formatter tests: `biome_formatter_test`, `biome_<language>_factory`, `biome_<language>_parser`, `biome_parser`, `biome_service`, `countme`, `iai`, `quickcheck`, `quickcheck_macros`, and `tests_macros`
Applied to files:
crates/biome_css_formatter/tests/quick_test.rscrates/biome_css_formatter/tests/spec_test.rs
📚 Learning: 2025-12-21T21:15:03.796Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T21:15:03.796Z
Learning: Applies to **/*.rs : Use doc tests (doctest) format with code blocks in rustdoc comments; ensure assertions pass in tests
Applied to files:
crates/biome_css_formatter/tests/quick_test.rs
📚 Learning: 2025-11-24T18:06:12.048Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:12.048Z
Learning: Applies to crates/biome_service/src/workspace/watcher.tests.rs : Implement watcher tests for workspace methods in watcher.tests.rs and end-to-end tests in LSP tests
Applied to files:
crates/biome_css_formatter/tests/quick_test.rscrates/biome_css_formatter/tests/spec_test.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Create test infrastructure with `tests/specs` folder structure and `spec_test.rs`, `spec_tests.rs`, and `language.rs` files in test directories
Applied to files:
crates/biome_css_formatter/tests/quick_test.rscrates/biome_css_formatter/tests/spec_test.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Use `Markup!` macro for diagnostic messages and code action descriptions to ensure proper formatting
Applied to files:
crates/biome_css_formatter/tests/quick_test.rs
📚 Learning: 2025-11-24T18:05:42.356Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:42.356Z
Learning: Applies to crates/biome_js_type_info/**/*.rs : Distinguish between `TypeData::Unknown` and `TypeData::UnknownKeyword` to measure inference effectiveness versus explicit user-provided unknown types
Applied to files:
crates/biome_css_syntax/src/scss_ext.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Check if a variable is global using the semantic model before reporting diagnostics for rules that ban global functions or variables
Applied to files:
crates/biome_css_syntax/src/scss_ext.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Implement the `FormatNodeRule<N>` trait with `fmt_fields` as the only required method; default implementations of `fmt`, `is_suppressed`, `fmt_leading_comments`, `fmt_dangling_comments`, and `fmt_trailing_comments` are provided
Applied to files:
crates/biome_css_formatter/src/scss/auxiliary/declaration.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Deprecated rules must include a `deprecated` field in the `declare_lint_rule!` macro with an explanation of what rule to use instead
Applied to files:
crates/biome_css_formatter/src/scss/auxiliary/declaration.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/src/lib.rs : Expose a public `format_node` function that accepts formatting options and a root syntax node, returning a `FormatResult<Formatted<Context>>` with appropriate documentation
Applied to files:
crates/biome_css_formatter/src/scss/auxiliary/declaration.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Use `declare_lint_rule!` macro with a `version` field set to `next` for new rules
Applied to files:
crates/biome_css_formatter/src/scss/auxiliary/declaration.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Mark rules with `issue_number` in the `declare_lint_rule!` macro if they are work-in-progress to indicate missing features
Applied to files:
crates/biome_css_formatter/src/scss/auxiliary/declaration.rs
📚 Learning: 2025-11-24T18:05:27.810Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:27.810Z
Learning: The formatter foundation relies on using the generic `Format` trait and `FormatNode` for nodes, with creation of an intermediate IR via a series of helpers
Applied to files:
crates/biome_css_formatter/src/scss/auxiliary/declaration.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/tests/specs/**/* : Create test files with `invalid` and `valid` prefixes to represent code that should and should not trigger the rule
Applied to files:
crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/invalid-modifier.scsscrates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-modifier.scss
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Create specification test files in `tests/specs/<language>/` directories with one or more test files; use `cargo insta accept` or `cargo insta review` to accept/reject snapshots
Applied to files:
crates/biome_css_formatter/tests/spec_test.rs
📚 Learning: 2025-11-24T18:06:12.048Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:12.048Z
Learning: Applies to crates/biome_service/src/workspace*.rs : Implement the Workspace trait in the Biome Service to manage internal state of projects, including open documents, project layout instances, and module graph instances
Applied to files:
crates/biome_css_formatter/tests/spec_test.rs
🧬 Code graph analysis (3)
crates/biome_css_formatter/tests/language.rs (1)
crates/biome_css_syntax/src/file_source.rs (1)
scss(102-108)
crates/biome_css_formatter/src/scss/auxiliary/declaration.rs (5)
crates/biome_css_formatter/src/scss/auxiliary/variable_modifier.rs (1)
fmt_fields(9-13)crates/biome_css_formatter/src/scss/value/identifier.rs (1)
fmt_fields(9-13)crates/biome_css_formatter/src/lib.rs (6)
fmt_fields(204-204)format(46-46)format(59-61)format(76-81)format(96-98)format(348-350)crates/biome_css_formatter/src/scss/value/namespaced_identifier.rs (1)
fmt_fields(9-21)crates/biome_formatter/src/builders.rs (1)
space(606-608)
crates/biome_css_formatter/tests/spec_test.rs (2)
crates/biome_formatter_test/src/spec.rs (1)
test_file(323-325)crates/biome_css_formatter/tests/language.rs (1)
scss(19-23)
⏰ 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). (8)
- GitHub Check: Test (depot-ubuntu-24.04-arm-16)
- GitHub Check: Documentation
- GitHub Check: Check Dependencies
- GitHub Check: Test (depot-windows-2022-16)
- GitHub Check: Bench (biome_css_analyze)
- GitHub Check: Bench (biome_css_parser)
- GitHub Check: Bench (biome_css_formatter)
- GitHub Check: autofix
🔇 Additional comments (15)
crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-modifier.scss (1)
1-6: LGTM! Clear test cases for missing modifiers.The first two test cases appropriately test the missing modifier error with spacing variations. The comments accurately describe each scenario.
crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/invalid-modifier.scss (1)
1-14: LGTM! Comprehensive error test coverage.The test cases effectively cover various invalid modifier scenarios, including CSS modifiers in SCSS context, unknown identifiers, typos, and multiple invalid modifiers. Well-commented and clear.
crates/biome_css_formatter/tests/specs/css/scss/declaration/global-flag.scss (1)
1-13: LGTM! Thorough formatter test input.The test cases effectively exercise the formatter with diverse spacing scenarios, line breaks, and modifier combinations (including edge cases like duplicate modifiers). This will ensure robust formatting behaviour.
crates/biome_css_syntax/src/scss_ext.rs (2)
1-10: LGTM! Clean implementation.The
is_default()method correctly usesmatches!with safe token access and appropriate kind checking. Documentation is clear.
12-25: LGTM! Consistent and correct.Both
is_global()andis_unknown()follow the same safe pattern asis_default(). Theis_unknown()negation logic correctly identifies modifiers that are neither default nor global, including invalid ones.crates/biome_css_formatter/src/scss/auxiliary/declaration.rs (2)
1-7: LGTM! Correct structure.The imports are minimal and appropriate, and the struct definition follows standard formatter patterns with the correct derives and visibility.
8-29: LGTM! Solid formatter implementation.The
fmt_fieldsimplementation correctly follows formatter patterns: proper use ofwrite!macro, formatting mandatory tokens from the AST (not hardcoding strings), and conditional formatting for optional modifiers. The formatting order matches SCSS syntax conventions.crates/biome_css_formatter/tests/specs/css/scss/declaration/namespaced.scss (1)
1-6: LGTM! Good coverage of namespaced syntax.The test cases cover various namespace lengths and spacing patterns, ensuring the formatter handles namespaced SCSS variables correctly across different formatting scenarios.
crates/biome_css_formatter/tests/language.rs (1)
18-24: LGTM!Clean constructor implementation that provides SCSS test language configuration. Follows the expected pattern for test language variants.
crates/biome_css_formatter/tests/spec_test.rs (2)
7-7: LGTM!Import required for source type detection logic.
55-55: LGTM!Parsing source type from test file path. The
unwrap()is acceptable here since test files should always have valid paths, and a panic provides a clear failure signal in tests.crates/biome_css_formatter/tests/quick_test.rs (2)
17-26: LGTM!Test input updated to SCSS with variable declarations and modifiers, correctly parsed using
CssFileSource::scss(). Good coverage of the SCSS features mentioned in the PR objectives.
29-37: LGTM!Formatter options properly configured and language correctly set to SCSS. The expanded options provide good test coverage for different formatting scenarios.
crates/biome_css_syntax/src/lib.rs (2)
17-17: LGTM!Exporting
CssFileLanguagealigns with the PR objective to add SCSS support, allowing external crates to distinguish between CSS and SCSS files.
7-7: Remove the unusedscss_extmodule declaration or add usage.The module is declared but never referenced anywhere in the codebase, making the code inside unreachable. Either integrate it properly into the module hierarchy (e.g., by exporting types from it) or remove the declaration.
⛔ Skipped due to learnings
Learnt from: CR Repo: biomejs/biome PR: 0 File: crates/biome_formatter/CONTRIBUTING.md:0-0 Timestamp: 2025-11-24T18:05:20.371Z Learning: Applies to crates/biome_formatter/**/biome_*_formatter/src/context.rs : Define `<Language>FormatContext` struct in a `context.rs` file containing `comments` and `source_map` fields, implementing `FormatContext` and `CstFormatContext` traitsLearnt from: CR Repo: biomejs/biome PR: 0 File: crates/biome_analyze/CONTRIBUTING.md:0-0 Timestamp: 2026-01-02T14:58:16.536Z Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Rule names should use the `use` prefix when the rule's sole intention is to mandate a single conceptLearnt from: CR Repo: biomejs/biome PR: 0 File: crates/biome_formatter/CONTRIBUTING.md:0-0 Timestamp: 2025-11-24T18:05:20.371Z Learning: Applies to crates/biome_formatter/**/biome_*_formatter/src/comments.rs : Define `<Language>CommentStyle` as a public type alias for `Comments<<Language>Language>` in a `comments.rs` fileLearnt from: CR Repo: biomejs/biome PR: 0 File: crates/biome_analyze/CONTRIBUTING.md:0-0 Timestamp: 2026-01-02T14:58:16.536Z Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Deprecated rules must include a `deprecated` field in the `declare_lint_rule!` macro with an explanation of what rule to use insteadLearnt from: CR Repo: biomejs/biome PR: 0 File: crates/biome_analyze/CONTRIBUTING.md:0-0 Timestamp: 2026-01-02T14:58:16.536Z Learning: Applies to crates/biome_analyze/biome_rule_options/lib/**/*.rs : Rule options must be defined in the `biome_rule_options` crate with a file named after the ruleLearnt from: dyc3 Repo: biomejs/biome PR: 8291 File: crates/biome_html_formatter/tests/specs/prettier/vue/html-vue/elastic-header.html:10-10 Timestamp: 2025-12-04T13:29:49.287Z Learning: Files under `crates/biome_html_formatter/tests/specs/prettier` are test fixtures synced from Prettier and should not receive detailed code quality reviews (e.g., HTTP vs HTTPS, formatting suggestions, etc.). These files are test data meant to validate formatter behavior and should be preserved as-is.Learnt from: CR Repo: biomejs/biome PR: 0 File: crates/biome_analyze/CONTRIBUTING.md:0-0 Timestamp: 2026-01-02T14:58:16.536Z Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Mark rules with `issue_number` in the `declare_lint_rule!` macro if they are work-in-progress to indicate missing featuresLearnt from: CR Repo: biomejs/biome PR: 0 File: crates/biome_analyze/CONTRIBUTING.md:0-0 Timestamp: 2026-01-02T14:58:16.536Z Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Invalid code snippets in rule documentation must emit exactly one diagnostic
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 (1)
crates/biome_css_parser/src/syntax/scss.rs (1)
59-65: Consider adding a comment to clarify semicolon behaviour.The logic correctly makes semicolons optional before closing braces (allowing both
$var: value }and$var: value; }) whilst requiring them in other contexts. A brief comment would aid future maintainers.📝 Suggested comment
+ // Semicolons are optional before closing braces in SCSS if !p.at(T!['}']) { if p.nth_at(1, T!['}']) { p.eat(T![;]);
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
crates/biome_css_formatter/tests/language.rscrates/biome_css_formatter/tests/prettier_tests.rscrates/biome_css_formatter/tests/quick_test.rscrates/biome_css_formatter/tests/spec_test.rscrates/biome_css_parser/src/syntax/scss.rs
🚧 Files skipped from review as they are similar to previous changes (1)
- crates/biome_css_formatter/tests/language.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs
📄 CodeRabbit inference engine (CONTRIBUTING.md)
**/*.rs: Use inline rustdoc documentation for rules, assists, and their options
Use thedbg!()macro for debugging output in Rust tests and code
Use doc tests (doctest) format with code blocks in rustdoc comments; ensure assertions pass in tests
Files:
crates/biome_css_formatter/tests/prettier_tests.rscrates/biome_css_formatter/tests/spec_test.rscrates/biome_css_formatter/tests/quick_test.rscrates/biome_css_parser/src/syntax/scss.rs
🧠 Learnings (27)
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/tests/language.rs : Implement `TestFormatLanguage` trait in `tests/language.rs` for the formatter's test language
Applied to files:
crates/biome_css_formatter/tests/prettier_tests.rscrates/biome_css_formatter/tests/spec_test.rscrates/biome_css_formatter/tests/quick_test.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/tests/spec_tests.rs : Use the `tests_macros::gen_tests!` macro in `spec_tests.rs` to generate test functions for each specification file matching the pattern `tests/specs/<language>/**/*.<ext>`
Applied to files:
crates/biome_css_formatter/tests/prettier_tests.rscrates/biome_css_formatter/tests/spec_test.rscrates/biome_css_formatter/tests/quick_test.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/src/context.rs : Define `<Language>FormatContext` struct in a `context.rs` file containing `comments` and `source_map` fields, implementing `FormatContext` and `CstFormatContext` traits
Applied to files:
crates/biome_css_formatter/tests/prettier_tests.rscrates/biome_css_formatter/tests/spec_test.rscrates/biome_css_formatter/tests/quick_test.rs
📚 Learning: 2025-12-04T13:29:49.287Z
Learnt from: dyc3
Repo: biomejs/biome PR: 8291
File: crates/biome_html_formatter/tests/specs/prettier/vue/html-vue/elastic-header.html:10-10
Timestamp: 2025-12-04T13:29:49.287Z
Learning: Files under `crates/biome_html_formatter/tests/specs/prettier` are test fixtures synced from Prettier and should not receive detailed code quality reviews (e.g., HTTP vs HTTPS, formatting suggestions, etc.). These files are test data meant to validate formatter behavior and should be preserved as-is.
Applied to files:
crates/biome_css_formatter/tests/prettier_tests.rscrates/biome_css_formatter/tests/spec_test.rscrates/biome_css_formatter/tests/quick_test.rs
📚 Learning: 2025-11-24T18:06:12.048Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:12.048Z
Learning: Applies to crates/biome_service/src/workspace/watcher.tests.rs : Implement watcher tests for workspace methods in watcher.tests.rs and end-to-end tests in LSP tests
Applied to files:
crates/biome_css_formatter/tests/prettier_tests.rscrates/biome_css_formatter/tests/quick_test.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/Cargo.toml : Include development dependencies in `Cargo.toml` for formatter tests: `biome_formatter_test`, `biome_<language>_factory`, `biome_<language>_parser`, `biome_parser`, `biome_service`, `countme`, `iai`, `quickcheck`, `quickcheck_macros`, and `tests_macros`
Applied to files:
crates/biome_css_formatter/tests/prettier_tests.rscrates/biome_css_formatter/tests/spec_test.rscrates/biome_css_formatter/tests/quick_test.rs
📚 Learning: 2025-11-24T18:05:27.810Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:27.810Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Import the `FormatNode` trait and implement it for your Node when creating formatters in biome_js_formatter
Applied to files:
crates/biome_css_formatter/tests/prettier_tests.rscrates/biome_css_formatter/tests/spec_test.rscrates/biome_css_formatter/tests/quick_test.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Create test infrastructure with `tests/specs` folder structure and `spec_test.rs`, `spec_tests.rs`, and `language.rs` files in test directories
Applied to files:
crates/biome_css_formatter/tests/prettier_tests.rscrates/biome_css_formatter/tests/spec_test.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : When porting rules from other linters, use `sources` metadata with `RuleSource::Eslint().same()` for identical behavior or `.inspired()` for different behavior
Applied to files:
crates/biome_css_formatter/tests/prettier_tests.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/src/lib.rs : Define a type alias `<Language>Formatter<'buf>` as `Formatter<'buf, <Language>FormatContext>` in the main formatter crate
Applied to files:
crates/biome_css_formatter/tests/prettier_tests.rscrates/biome_css_formatter/tests/spec_test.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/src/lib.rs : Expose a public `format_node` function that accepts formatting options and a root syntax node, returning a `FormatResult<Formatted<Context>>` with appropriate documentation
Applied to files:
crates/biome_css_formatter/tests/prettier_tests.rscrates/biome_css_formatter/tests/spec_test.rscrates/biome_css_formatter/tests/quick_test.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Implement the `IntoFormat<Context>` trait in `lib.rs` with implementations for `SyntaxResult` and `Option` types as part of the formatter infrastructure
Applied to files:
crates/biome_css_formatter/tests/prettier_tests.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Create a new formatter crate using the command `just new-crate biome_<language>_formatter` where `<language>` is the target language (e.g., `biome_html_formatter` for HTML)
Applied to files:
crates/biome_css_formatter/tests/prettier_tests.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Implement the `AsFormat<Context>` trait in `lib.rs` with generic implementations for references, `SyntaxResult`, and `Option` types as provided in the formatter boilerplate code
Applied to files:
crates/biome_css_formatter/tests/prettier_tests.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Define `FormatHtmlSyntaxNode` struct in a `cst.rs` file implementing `FormatRule<HtmlSyntaxNode>`, `AsFormat<HtmlFormatContext>`, and `IntoFormat<HtmlFormatContext>` traits using the provided boilerplate code
Applied to files:
crates/biome_css_formatter/tests/prettier_tests.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/src/comments.rs : Define `<Language>CommentStyle` as a public type alias for `Comments<<Language>Language>` in a `comments.rs` file
Applied to files:
crates/biome_css_formatter/tests/spec_test.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/language_kind.rs : Add a new variant to `LanguageKind` enum in `language_kind.rs` file and implement all methods for the new language variant
Applied to files:
crates/biome_css_formatter/tests/spec_test.rscrates/biome_css_formatter/tests/quick_test.rscrates/biome_css_parser/src/syntax/scss.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/language_kind.rs : Add a new language prefix to the `LANGUAGE_PREFIXES` constant in `language_kind.rs` file
Applied to files:
crates/biome_css_formatter/tests/spec_test.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Create specification test files in `tests/specs/<language>/` directories with one or more test files; use `cargo insta accept` or `cargo insta review` to accept/reject snapshots
Applied to files:
crates/biome_css_formatter/tests/spec_test.rs
📚 Learning: 2025-12-21T21:15:03.796Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T21:15:03.796Z
Learning: Applies to **/*.rs : Use doc tests (doctest) format with code blocks in rustdoc comments; ensure assertions pass in tests
Applied to files:
crates/biome_css_formatter/tests/quick_test.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Parse rule functions must be prefixed with `parse_` and use the name defined in the grammar file, e.g., `parse_for_statement` or `parse_expression`
Applied to files:
crates/biome_css_parser/src/syntax/scss.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Parse rules must take a mutable reference to the parser as their only parameter and return a `ParsedSyntax`
Applied to files:
crates/biome_css_parser/src/syntax/scss.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Use `ConditionalParsedSyntax` for syntax that is only valid in specific contexts (e.g., strict mode, file types, language versions) and call `or_invalid_to_bogus()` to convert to a bogus node if not supported
Applied to files:
crates/biome_css_parser/src/syntax/scss.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Use `ParseSeparatedList` and `ParseNodeList` for parsing lists with error recovery to avoid infinite loops
Applied to files:
crates/biome_css_parser/src/syntax/scss.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Implement a token source struct that wraps the lexer and implements `TokenSourceWithBufferedLexer` and `LexerWithCheckpoint` for lookahead and re-lexing capabilities
Applied to files:
crates/biome_css_parser/src/syntax/scss.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/lexer/mod.rs : Implement a `Lexer` trait from `biome_parser` crate for the lexer struct that consumes characters from source code and emits tokens
Applied to files:
crates/biome_css_parser/src/syntax/scss.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : A parser struct must implement the `Parser` trait and save the token source, parser context, and optional parser options
Applied to files:
crates/biome_css_parser/src/syntax/scss.rs
🧬 Code graph analysis (3)
crates/biome_css_formatter/tests/prettier_tests.rs (2)
crates/biome_css_syntax/src/file_source.rs (2)
scss(102-108)css(94-100)crates/biome_css_formatter/tests/language.rs (1)
new(18-20)
crates/biome_css_formatter/tests/spec_test.rs (1)
crates/biome_css_formatter/tests/language.rs (1)
new(18-20)
crates/biome_css_formatter/tests/quick_test.rs (5)
crates/biome_css_formatter/tests/language.rs (2)
parse(28-35)new(18-20)crates/biome_css_parser/src/lib.rs (1)
parse_css(27-30)crates/biome_css_syntax/src/file_source.rs (1)
scss(102-108)crates/biome_css_parser/src/parser.rs (1)
new(106-118)crates/biome_css_formatter/src/lib.rs (1)
new(262-264)
⏰ 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). (11)
- GitHub Check: Test (depot-ubuntu-24.04-arm-16)
- GitHub Check: Lint project (depot-windows-2022)
- GitHub Check: Documentation
- GitHub Check: Check Dependencies
- GitHub Check: Test (depot-windows-2022-16)
- GitHub Check: End-to-end tests
- GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
- GitHub Check: Bench (biome_css_formatter)
- GitHub Check: Bench (biome_css_parser)
- GitHub Check: Bench (biome_css_analyze)
- GitHub Check: autofix
🔇 Additional comments (8)
crates/biome_css_parser/src/syntax/scss.rs (5)
17-31: LGTM! Clean identifier parsing.The SCSS identifier parsing correctly checks for
$followed by an identifier and parses both tokens. The use of.ok()on Line 29 appropriately discards theResultsince the parser tracks errors internally.
34-42: Lookahead logic is correct.The position checks are accurate:
- Simple identifier:
$(0),id(1),:(2)- Namespaced:
ns(0),.(1),$(2),id(3),:(4)
71-89: Namespaced identifier parsing looks good.Correctly parses the
namespace.$variablepattern with appropriate checks and token sequencing.
108-126: Good error recovery for invalid modifiers.Lines 119-122 correctly handle the case where an identifier follows
!but isn'tdefaultorglobal, emitting an error whilst continuing to parse. This prevents the parser from getting stuck on malformed input.
128-153: ParseNodeList implementation is appropriate.The recovery logic correctly handles optional modifier lists:
AbsentreturnsAlreadyRecovered(no recovery needed), whilstPresentreturnsOk. This is suitable since SCSS variable modifiers are optional elements.Based on learnings, this follows the correct pattern for list parsing with error recovery.
crates/biome_css_formatter/tests/spec_test.rs (1)
55-57: Source type wiring looks correct.Lines 55-57 properly derive the source type from the test file path and construct the test language accordingly. The
unwrap()on Line 55 is appropriate for test code where file paths should always convert successfully.crates/biome_css_formatter/tests/prettier_tests.rs (1)
24-31: Clean extension-based source type selection.The runtime selection of CSS vs SCSS based on file extension is straightforward and correctly wired through to the language construction. Well done!
crates/biome_css_formatter/tests/quick_test.rs (1)
17-37: SCSS quick test properly configured.The test input demonstrates SCSS variable declarations with modifiers, and the parsing/formatting pipeline correctly uses
CssFileSource::scss(). Theoptions.clone()on Line 33 is necessary sinceformat_nodetakes ownership.
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: 3
🤖 Fix all issues with AI agents
In @crates/biome_css_parser/src/syntax/declaration.rs:
- Around line 94-116: The conditional in parse_declaration_with_semicolon
incorrectly includes EOF (using `if !p.at(T!['}']) || p.at(EOF)`), causing
semicolon handling to run at EOF and emit bogus diagnostics; change the guard to
skip the semicolon logic when either a closing brace or EOF is present (e.g. use
logical AND/negation so it only runs when not at '}' AND not at EOF, or
equivalently wrap the two checks in a negation of (p.at(T!['}']) || p.at(EOF)));
keep the inner logic that peeks with nth_at(1, ...) and uses p.eat or p.expect
as-is.
- Around line 16-39: The recovery sync set in DeclarationList::recover is too
narrow and only syncs on T!['}'], which lets a malformed declaration eat the
rest of the block; update the ParseRecoveryTokenSet passed to
or_recover_with_token_set to include the semicolon token as a recovery boundary
(e.g., token_set!(T!['}'], T![';'])) so recovery will also stop at ';' and
resume parsing subsequent declarations; modify the call in recover that
currently builds ParseRecoveryTokenSet::new(CSS_BOGUS, token_set!(T!['}'])) to
include T![';'] alongside T!['}'].
In @crates/biome_css_parser/src/syntax/scss/declaration.rs:
- Around line 29-53: Add a unit test that documents SCSS semicolon handling at
EOF by exercising parse_scss_declaration: construct SCSS snippets where a
declaration at file end is missing the trailing ';' (and variants followed by
'}' or EOF) and assert whether parse_scss_declaration (via calling
is_at_scss_declaration and invoking parse_scss_declaration on a CssParser)
returns Present or Absent; if the current behavior (requires ';' at EOF unless
followed by '}') is intended, assert it; if SCSS should allow omitting the final
semicolon, update parse_scss_declaration to accept EOF (adjust the conditional
that checks p.at(T!['}']) / p.nth_at(1, T!['}']) and the p.expect(T![;]) logic)
and add the corresponding passing test.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
crates/biome_css_parser/src/syntax/declaration.rscrates/biome_css_parser/src/syntax/mod.rscrates/biome_css_parser/src/syntax/scss/declaration.rscrates/biome_css_parser/src/syntax/scss/mod.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs
📄 CodeRabbit inference engine (CONTRIBUTING.md)
**/*.rs: Use inline rustdoc documentation for rules, assists, and their options
Use thedbg!()macro for debugging output in Rust tests and code
Use doc tests (doctest) format with code blocks in rustdoc comments; ensure assertions pass in tests
Files:
crates/biome_css_parser/src/syntax/scss/mod.rscrates/biome_css_parser/src/syntax/scss/declaration.rscrates/biome_css_parser/src/syntax/declaration.rscrates/biome_css_parser/src/syntax/mod.rs
🧠 Learnings (14)
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Parse rule functions must be prefixed with `parse_` and use the name defined in the grammar file, e.g., `parse_for_statement` or `parse_expression`
Applied to files:
crates/biome_css_parser/src/syntax/scss/mod.rscrates/biome_css_parser/src/syntax/scss/declaration.rscrates/biome_css_parser/src/syntax/mod.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Use `ConditionalParsedSyntax` for syntax that is only valid in specific contexts (e.g., strict mode, file types, language versions) and call `or_invalid_to_bogus()` to convert to a bogus node if not supported
Applied to files:
crates/biome_css_parser/src/syntax/scss/mod.rscrates/biome_css_parser/src/syntax/scss/declaration.rscrates/biome_css_parser/src/syntax/mod.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Parse rules must take a mutable reference to the parser as their only parameter and return a `ParsedSyntax`
Applied to files:
crates/biome_css_parser/src/syntax/scss/mod.rscrates/biome_css_parser/src/syntax/scss/declaration.rscrates/biome_css_parser/src/syntax/mod.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Implement a token source struct that wraps the lexer and implements `TokenSourceWithBufferedLexer` and `LexerWithCheckpoint` for lookahead and re-lexing capabilities
Applied to files:
crates/biome_css_parser/src/syntax/scss/mod.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Use `p.eat(token)` for optional tokens, `p.expect(token)` for required tokens, `parse_rule(p).ok(p)` for optional nodes, and `parse_rule(p).or_add_diagnostic(p, error)` for required nodes
Applied to files:
crates/biome_css_parser/src/syntax/scss/mod.rscrates/biome_css_parser/src/syntax/mod.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Use `ParseSeparatedList` and `ParseNodeList` for parsing lists with error recovery to avoid infinite loops
Applied to files:
crates/biome_css_parser/src/syntax/declaration.rscrates/biome_css_parser/src/syntax/mod.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Rules should explain to users what the error is, why it is triggered, and what they should do to fix it
Applied to files:
crates/biome_css_parser/src/syntax/mod.rs
📚 Learning: 2025-11-24T18:04:57.309Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:04:57.309Z
Learning: Diagnostic should provide a way for the user to fix the issue through log advice, diff advice, or command advice. Add the FIXABLE tag to highlight actionable hints
Applied to files:
crates/biome_css_parser/src/syntax/mod.rs
📚 Learning: 2025-11-24T18:04:57.309Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:04:57.309Z
Learning: Diagnostic should explain why something went wrong, not just state that it went wrong. Add explanations in log advices and show hyperlinks to relevant documentation pages
Applied to files:
crates/biome_css_parser/src/syntax/mod.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Implement the `diagnostic` function to provide error messages explaining what the error is, why it is triggered, and what the user should do
Applied to files:
crates/biome_css_parser/src/syntax/mod.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Use `Markup!` macro for diagnostic messages and code action descriptions to ensure proper formatting
Applied to files:
crates/biome_css_parser/src/syntax/mod.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Code blocks in rule documentation must specify a language identifier and be tagged with `expect_diagnostic` for invalid examples or remain untagged for valid examples
Applied to files:
crates/biome_css_parser/src/syntax/mod.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Parse rules must return `ParsedSyntax::Absent` if the rule can't predict by the next token(s) if they form the expected node, and must not progress the parser in this case
Applied to files:
crates/biome_css_parser/src/syntax/mod.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Implement error recovery in list parsing using `or_recover()` to wrap unparseable tokens in a `BOGUS_*` node and consume tokens until a recovery token is found
Applied to files:
crates/biome_css_parser/src/syntax/mod.rs
🧬 Code graph analysis (4)
crates/biome_css_parser/src/syntax/scss/mod.rs (2)
crates/biome_css_parser/src/syntax/mod.rs (2)
is_nth_at_identifier(344-346)parse_regular_identifier(350-352)crates/biome_css_parser/src/syntax/scss/declaration.rs (2)
is_at_scss_declaration(19-27)parse_scss_declaration(30-53)
crates/biome_css_parser/src/syntax/scss/declaration.rs (3)
crates/biome_css_parser/src/syntax/scss/mod.rs (2)
is_at_scss_identifier(14-16)parse_scss_identifier(19-28)crates/biome_css_parser/src/syntax/mod.rs (3)
is_at_identifier(339-341)is_nth_at_identifier(344-346)parse_regular_identifier(350-352)crates/biome_parser/src/diagnostic.rs (1)
expected_token_any(400-423)
crates/biome_css_parser/src/syntax/declaration.rs (4)
crates/biome_css_parser/src/syntax/parse_error.rs (2)
expected_declaration_item(212-214)scss_only_syntax_error(247-259)crates/biome_css_parser/src/syntax/property/mod.rs (2)
is_at_any_property(26-28)parse_any_property(31-40)crates/biome_css_parser/src/syntax/scss/declaration.rs (3)
is_at_scss_declaration(19-27)parse_scss_declaration(30-53)parse_element(120-122)crates/biome_css_parser/src/syntax/mod.rs (3)
parse_element(130-146)parse_element(295-297)parse_element(506-520)
crates/biome_css_parser/src/syntax/mod.rs (4)
crates/biome_css_parser/src/syntax/parse_error.rs (5)
expected_any_rule(62-64)expected_component_value(216-230)expected_non_css_wide_keyword_identifier(20-44)scss_only_syntax_error(247-259)tailwind_disabled(236-241)crates/biome_css_parser/src/syntax/scss/declaration.rs (2)
is_at_scss_declaration(19-27)parse_scss_declaration(30-53)crates/biome_css_parser/src/syntax/scss/mod.rs (2)
is_at_scss_identifier(14-16)parse_scss_identifier(19-28)crates/biome_css_parser/src/syntax/declaration.rs (5)
is_at_any_declaration(81-83)is_at_any_declaration_with_semicolon(61-63)is_at_declaration(42-44)parse_any_declaration_with_semicolon(66-78)parse_declaration(47-58)
⏰ 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). (11)
- GitHub Check: Test (depot-windows-2022-16)
- GitHub Check: Lint project (depot-windows-2022)
- GitHub Check: End-to-end tests
- GitHub Check: Test (depot-ubuntu-24.04-arm-16)
- GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
- GitHub Check: Documentation
- GitHub Check: Check Dependencies
- GitHub Check: autofix
- GitHub Check: Bench (biome_css_analyze)
- GitHub Check: Bench (biome_css_formatter)
- GitHub Check: Bench (biome_css_parser)
🔇 Additional comments (4)
crates/biome_css_parser/src/syntax/scss/mod.rs (1)
13-28: SCSS identifier parsing is clean and predictable.Nice, minimal rule: fast lookahead and no parser movement on
Absent.crates/biome_css_parser/src/syntax/mod.rs (3)
41-69: Feature gating for SCSS is nicely contained.
CssSyntaxFeatures::Scss => p.source_type.is_scss()is exactly the sort of boring plumbing we like.
101-103: Routing SCSS declarations/values through the main CSS paths looks solid.The ordering (SCSS checks before generic identifier/value parsing) should avoid misclassification while still producing useful SCSS-only diagnostics in CSS mode.
Also applies to: 130-146, 233-287
100-146:parse_exclusive_syntaxalready handles unsupported syntax correctly.The implementation properly converts unsupported syntax to a bogus node via
change_to_bogus(), consumes tokens via the unconditionalparse(p)call, and returns aPresentnode orAbsentas appropriate. No changes needed.
| impl ParseNodeList for DeclarationList { | ||
| type Kind = CssSyntaxKind; | ||
| type Parser<'source> = CssParser<'source>; | ||
| const LIST_KIND: Self::Kind = CSS_DECLARATION_LIST; | ||
|
|
||
| fn parse_element(&mut self, p: &mut Self::Parser<'_>) -> ParsedSyntax { | ||
| parse_any_declaration_with_semicolon(p) | ||
| } | ||
|
|
||
| fn is_at_list_end(&self, p: &mut Self::Parser<'_>) -> bool { | ||
| p.at(T!['}']) | ||
| } | ||
|
|
||
| fn recover( | ||
| &mut self, | ||
| p: &mut Self::Parser<'_>, | ||
| parsed_element: ParsedSyntax, | ||
| ) -> RecoveryResult { | ||
| parsed_element.or_recover_with_token_set( | ||
| p, | ||
| &ParseRecoveryTokenSet::new(CSS_BOGUS, token_set!(T!['}'])), | ||
| expected_declaration_item, | ||
| ) | ||
| } |
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.
Declaration list recovery sync set is too narrow (may eat the whole block).
On Line 36 you only recover on }. A single malformed declaration could cause recovery to skip everything until the closing brace, dropping valid declarations that follow. Consider also syncing on ; (common “next item” boundary).
Proposed tweak
- &ParseRecoveryTokenSet::new(CSS_BOGUS, token_set!(T!['}'])),
+ &ParseRecoveryTokenSet::new(CSS_BOGUS, token_set!(T![;], T!['}'])),📝 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.
| impl ParseNodeList for DeclarationList { | |
| type Kind = CssSyntaxKind; | |
| type Parser<'source> = CssParser<'source>; | |
| const LIST_KIND: Self::Kind = CSS_DECLARATION_LIST; | |
| fn parse_element(&mut self, p: &mut Self::Parser<'_>) -> ParsedSyntax { | |
| parse_any_declaration_with_semicolon(p) | |
| } | |
| fn is_at_list_end(&self, p: &mut Self::Parser<'_>) -> bool { | |
| p.at(T!['}']) | |
| } | |
| fn recover( | |
| &mut self, | |
| p: &mut Self::Parser<'_>, | |
| parsed_element: ParsedSyntax, | |
| ) -> RecoveryResult { | |
| parsed_element.or_recover_with_token_set( | |
| p, | |
| &ParseRecoveryTokenSet::new(CSS_BOGUS, token_set!(T!['}'])), | |
| expected_declaration_item, | |
| ) | |
| } | |
| impl ParseNodeList for DeclarationList { | |
| type Kind = CssSyntaxKind; | |
| type Parser<'source> = CssParser<'source>; | |
| const LIST_KIND: Self::Kind = CSS_DECLARATION_LIST; | |
| fn parse_element(&mut self, p: &mut Self::Parser<'_>) -> ParsedSyntax { | |
| parse_any_declaration_with_semicolon(p) | |
| } | |
| fn is_at_list_end(&self, p: &mut Self::Parser<'_>) -> bool { | |
| p.at(T!['}']) | |
| } | |
| fn recover( | |
| &mut self, | |
| p: &mut Self::Parser<'_>, | |
| parsed_element: ParsedSyntax, | |
| ) -> RecoveryResult { | |
| parsed_element.or_recover_with_token_set( | |
| p, | |
| &ParseRecoveryTokenSet::new(CSS_BOGUS, token_set!(T![;], T!['}'])), | |
| expected_declaration_item, | |
| ) | |
| } |
🤖 Prompt for AI Agents
In @crates/biome_css_parser/src/syntax/declaration.rs around lines 16 - 39, The
recovery sync set in DeclarationList::recover is too narrow and only syncs on
T!['}'], which lets a malformed declaration eat the rest of the block; update
the ParseRecoveryTokenSet passed to or_recover_with_token_set to include the
semicolon token as a recovery boundary (e.g., token_set!(T!['}'], T![';'])) so
recovery will also stop at ';' and resume parsing subsequent declarations;
modify the call in recover that currently builds
ParseRecoveryTokenSet::new(CSS_BOGUS, token_set!(T!['}'])) to include T![';']
alongside T!['}'].
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 (1)
crates/biome_css_parser/src/syntax/scss/declaration.rs (1)
43-49: Consider adding a brief comment to clarify the semicolon handling logic.The conditional logic here handles three cases: trailing
}, optional semicolon before}, and required semicolon otherwise. While functional, a short inline comment would help future readers understand the intent more quickly.📝 Suggested clarification
+ // Semicolon is optional before `}` or at EOF; required otherwise. if !p.at(T!['}']) && !p.at(EOF) { if p.nth_at(1, T!['}']) { p.eat(T![;]); } else { p.expect(T![;]); } }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
crates/biome_css_parser/src/syntax/scss/declaration.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs
📄 CodeRabbit inference engine (CONTRIBUTING.md)
**/*.rs: Use inline rustdoc documentation for rules, assists, and their options
Use thedbg!()macro for debugging output in Rust tests and code
Use doc tests (doctest) format with code blocks in rustdoc comments; ensure assertions pass in tests
Files:
crates/biome_css_parser/src/syntax/scss/declaration.rs
🧠 Learnings (6)
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Parse rule functions must be prefixed with `parse_` and use the name defined in the grammar file, e.g., `parse_for_statement` or `parse_expression`
Applied to files:
crates/biome_css_parser/src/syntax/scss/declaration.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Parse rules must take a mutable reference to the parser as their only parameter and return a `ParsedSyntax`
Applied to files:
crates/biome_css_parser/src/syntax/scss/declaration.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Use `ConditionalParsedSyntax` for syntax that is only valid in specific contexts (e.g., strict mode, file types, language versions) and call `or_invalid_to_bogus()` to convert to a bogus node if not supported
Applied to files:
crates/biome_css_parser/src/syntax/scss/declaration.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Invalid code snippets in rule documentation must emit exactly one diagnostic
Applied to files:
crates/biome_css_parser/src/syntax/scss/declaration.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Code blocks in rule documentation must specify a language identifier and be tagged with `expect_diagnostic` for invalid examples or remain untagged for valid examples
Applied to files:
crates/biome_css_parser/src/syntax/scss/declaration.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Mark rules with `issue_number` in the `declare_lint_rule!` macro if they are work-in-progress to indicate missing features
Applied to files:
crates/biome_css_parser/src/syntax/scss/declaration.rs
🧬 Code graph analysis (1)
crates/biome_css_parser/src/syntax/scss/declaration.rs (4)
crates/biome_css_parser/src/syntax/scss/mod.rs (2)
is_at_scss_identifier(14-16)parse_scss_identifier(19-28)crates/biome_css_parser/src/syntax/mod.rs (12)
is_at_identifier(339-341)is_nth_at_identifier(344-346)parse_regular_identifier(350-352)parse_element(130-146)parse_element(295-297)parse_element(506-520)is_at_list_end(148-150)is_at_list_end(299-301)is_at_list_end(522-524)recover(152-162)recover(303-313)recover(526-536)crates/biome_parser/src/diagnostic.rs (1)
expected_token_any(400-423)crates/biome_css_parser/src/syntax/declaration.rs (3)
parse_element(21-23)is_at_list_end(25-27)recover(29-39)
⏰ 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). (11)
- GitHub Check: Check Dependencies
- GitHub Check: Test (depot-ubuntu-24.04-arm-16)
- GitHub Check: Lint project (depot-windows-2022)
- GitHub Check: Test (depot-windows-2022-16)
- GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
- GitHub Check: Documentation
- GitHub Check: End-to-end tests
- GitHub Check: autofix
- GitHub Check: Bench (biome_css_parser)
- GitHub Check: Bench (biome_css_analyze)
- GitHub Check: Bench (biome_css_formatter)
🔇 Additional comments (5)
crates/biome_css_parser/src/syntax/scss/declaration.rs (5)
1-16: LGTM!Imports are well-organised and all appear to be used.
18-27: LGTM!Detection logic correctly accounts for token positions: position 2 for simple SCSS identifiers (
$ident:) and position 4 for namespaced identifiers (ns.$ident:).
54-73: LGTM!Namespaced identifier detection and parsing correctly handles the
namespace.$variablepattern.
89-110: LGTM!Good error recovery pattern—consumes the invalid identifier after emitting a diagnostic so parsing can continue gracefully.
112-137: LGTM!The
ScssVariableModifierListimplementation follows the establishedParseNodeListpattern, with appropriate recovery signalling.
a341e26 to
df6bcc9
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: 0
🧹 Nitpick comments (1)
crates/biome_css_parser/src/syntax/declaration.rs (1)
66-78: Simplify the logic for clarity.Line 73 checks
is_at_any_declaration_with_semicolon(p), but since empty declarations (line 67) and SCSS declarations (line 69) are already handled above, this check is redundant. At this point, onlyis_at_declaration(p)can match.♻️ Proposed refactor to improve clarity
pub(crate) fn parse_any_declaration_with_semicolon(p: &mut CssParser) -> ParsedSyntax { if is_at_empty_declaration(p) { parse_empty_declaration(p) } else if is_at_scss_declaration(p) { CssSyntaxFeatures::Scss.parse_exclusive_syntax(p, parse_scss_declaration, |p, marker| { scss_only_syntax_error(p, "SCSS variable declarations", marker.range(p)) }) - } else if is_at_any_declaration_with_semicolon(p) { + } else if is_at_declaration(p) { parse_declaration_with_semicolon(p) } else { Absent } }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
crates/biome_css_parser/tests/css_test_suite/ok/snippet/eof_optional_semicolon.styled.css.snapis excluded by!**/*.snapand included by**
📒 Files selected for processing (2)
crates/biome_css_parser/src/syntax/declaration.rscrates/biome_css_parser/tests/css_test_suite/ok/snippet/eof_optional_semicolon.styled.css
💤 Files with no reviewable changes (1)
- crates/biome_css_parser/tests/css_test_suite/ok/snippet/eof_optional_semicolon.styled.css
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs
📄 CodeRabbit inference engine (CONTRIBUTING.md)
**/*.rs: Use inline rustdoc documentation for rules, assists, and their options
Use thedbg!()macro for debugging output in Rust tests and code
Use doc tests (doctest) format with code blocks in rustdoc comments; ensure assertions pass in tests
Files:
crates/biome_css_parser/src/syntax/declaration.rs
🧠 Learnings (12)
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Use `ParseSeparatedList` and `ParseNodeList` for parsing lists with error recovery to avoid infinite loops
Applied to files:
crates/biome_css_parser/src/syntax/declaration.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Parse rule functions must be prefixed with `parse_` and use the name defined in the grammar file, e.g., `parse_for_statement` or `parse_expression`
Applied to files:
crates/biome_css_parser/src/syntax/declaration.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Use `ConditionalParsedSyntax` for syntax that is only valid in specific contexts (e.g., strict mode, file types, language versions) and call `or_invalid_to_bogus()` to convert to a bogus node if not supported
Applied to files:
crates/biome_css_parser/src/syntax/declaration.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Implement error recovery in list parsing using `or_recover()` to wrap unparseable tokens in a `BOGUS_*` node and consume tokens until a recovery token is found
Applied to files:
crates/biome_css_parser/src/syntax/declaration.rs
📚 Learning: 2025-10-25T07:22:18.540Z
Learnt from: ematipico
Repo: biomejs/biome PR: 7852
File: crates/biome_css_parser/src/syntax/property/mod.rs:161-168
Timestamp: 2025-10-25T07:22:18.540Z
Learning: In the Biome CSS parser, lexer token emission should not be gated behind parser options like `is_tailwind_directives_enabled()`. The lexer must emit correct tokens regardless of parser options to enable accurate diagnostics and error messages when the syntax is used incorrectly.
Applied to files:
crates/biome_css_parser/src/syntax/declaration.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Use `p.eat(token)` for optional tokens, `p.expect(token)` for required tokens, `parse_rule(p).ok(p)` for optional nodes, and `parse_rule(p).or_add_diagnostic(p, error)` for required nodes
Applied to files:
crates/biome_css_parser/src/syntax/declaration.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Code blocks in rule documentation must specify a language identifier and be tagged with `expect_diagnostic` for invalid examples or remain untagged for valid examples
Applied to files:
crates/biome_css_parser/src/syntax/declaration.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Invalid code snippets in rule documentation must emit exactly one diagnostic
Applied to files:
crates/biome_css_parser/src/syntax/declaration.rs
📚 Learning: 2025-12-22T09:27:13.161Z
Learnt from: ematipico
Repo: biomejs/biome PR: 8537
File: crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs:167-210
Timestamp: 2025-12-22T09:27:13.161Z
Learning: In crates/biome_analyze/**/*analyze/src/**/*.rs, the `fix_kind` field in `declare_lint_rule!` should only be specified when the rule implements the `action` function. Rules that only emit diagnostics without providing code fixes should not include `fix_kind` in their metadata.
Applied to files:
crates/biome_css_parser/src/syntax/declaration.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Mark rules with `issue_number` in the `declare_lint_rule!` macro if they are work-in-progress to indicate missing features
Applied to files:
crates/biome_css_parser/src/syntax/declaration.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Parse rules must return `ParsedSyntax::Absent` if the rule can't predict by the next token(s) if they form the expected node, and must not progress the parser in this case
Applied to files:
crates/biome_css_parser/src/syntax/declaration.rs
📚 Learning: 2025-12-31T15:35:41.261Z
Learnt from: dyc3
Repo: biomejs/biome PR: 8639
File: crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs:101-108
Timestamp: 2025-12-31T15:35:41.261Z
Learning: In crates/biome_analyze/**/*analyze/src/lint/nursery/**/*.rs, the `issue_number` field in `declare_lint_rule!` macro is optional and the vast majority of nursery rules do not need it. Do not recommend adding `issue_number` unless there's a specific reason.
Applied to files:
crates/biome_css_parser/src/syntax/declaration.rs
🧬 Code graph analysis (1)
crates/biome_css_parser/src/syntax/declaration.rs (4)
crates/biome_css_parser/src/syntax/parse_error.rs (2)
expected_declaration_item(212-214)scss_only_syntax_error(247-259)crates/biome_css_parser/src/syntax/property/mod.rs (2)
is_at_any_property(26-28)parse_any_property(31-40)crates/biome_css_parser/src/syntax/scss/declaration.rs (3)
is_at_scss_declaration(19-27)parse_scss_declaration(30-52)parse_element(119-121)crates/biome_css_parser/src/syntax/mod.rs (3)
parse_element(130-146)parse_element(295-297)parse_element(506-520)
⏰ 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). (4)
- GitHub Check: Bench (biome_css_analyze)
- GitHub Check: Bench (biome_css_parser)
- GitHub Check: Bench (biome_css_formatter)
- GitHub Check: autofix
🔇 Additional comments (7)
crates/biome_css_parser/src/syntax/declaration.rs (7)
1-13: LGTM! Imports are well-organised.All necessary dependencies are correctly imported with appropriate visibility.
14-40: LGTM! Proper list parsing with recovery.The
DeclarationListimplementation correctly usesParseNodeListwith appropriate error recovery, following the established patterns.
42-58: LGTM! Declaration parsing follows conventions.The predicate and parse functions correctly implement the standard parser pattern with appropriate node completion.
80-83: LGTM! Clean predicate function.
85-116: LGTM! Semicolon handling is correct.The documentation clearly explains the logic, and the implementation correctly handles optional semicolons for the last declaration in a block whilst enforcing them elsewhere.
118-131: LGTM! Empty declaration parsing is straightforward.
133-147: LGTM! Important flag parsing is correct.The two-token lookahead properly identifies
!importantsequences, and the implementation follows parser conventions.
Summary
This PR implements foundational support for parsing and formatting SCSS variable declarations and comments in SCSS files.
Features Added
SCSS Variable Declarations:
SCSS Comments:
Test Plan
new tests
Docs