feat(parse/tailwind): parse negative candidates, other misc cleanup/refactors#7937
feat(parse/tailwind): parse negative candidates, other misc cleanup/refactors#7937
Conversation
|
Parser conformance results onjs/262
jsx/babel
symbols/microsoft
ts/babel
ts/microsoft
|
CodSpeed Performance ReportMerging #7937 will not alter performanceComparing Summary
Footnotes
|
WalkthroughAdds support for negative Tailwind modifiers (e.g. Possibly related PRs
Suggested labels
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro ⛔ Files ignored due to path filters (43)
📒 Files selected for processing (11)
🚧 Files skipped from review as they are similar to previous changes (6)
🧰 Additional context used📓 Path-based instructions (2)**/*.{rs,toml}📄 CodeRabbit inference engine (CONTRIBUTING.md)
Files:
**/*.rs📄 CodeRabbit inference engine (CONTRIBUTING.md)
Files:
🧠 Learnings (15)📚 Learning: 2025-10-15T09:22:15.851ZApplied to files:
📚 Learning: 2025-10-15T09:22:15.851ZApplied to files:
📚 Learning: 2025-10-15T09:22:46.002ZApplied to files:
📚 Learning: 2025-10-24T21:24:58.650ZApplied to files:
📚 Learning: 2025-10-24T21:24:58.650ZApplied to files:
📚 Learning: 2025-10-15T09:22:15.851ZApplied to files:
📚 Learning: 2025-10-24T21:24:58.650ZApplied to files:
📚 Learning: 2025-10-24T21:24:58.650ZApplied to files:
📚 Learning: 2025-10-15T09:24:31.042ZApplied to files:
📚 Learning: 2025-10-15T09:24:31.042ZApplied to files:
📚 Learning: 2025-10-15T09:22:46.002ZApplied to files:
📚 Learning: 2025-10-15T09:22:46.002ZApplied to files:
📚 Learning: 2025-10-24T21:24:58.650ZApplied to files:
📚 Learning: 2025-10-15T09:24:31.042ZApplied to files:
📚 Learning: 2025-10-15T09:24:31.042ZApplied to files:
🧬 Code graph analysis (1)crates/biome_tailwind_parser/src/syntax/mod.rs (2)
⏰ 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). (20)
🔇 Additional comments (7)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
crates/biome_tailwind_parser/src/lexer/mod.rs (1)
74-87: Consider reducing duplication.The
consume_token_saw_negativemethod duplicates much of the logic fromconsume_token(lines 49-72). Whilst the duplication may be intentional for performance or clarity, you could potentially extract shared logic into helper methods to improve maintainability.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (43)
crates/biome_tailwind_factory/src/generated/node_factory.rsis excluded by!**/generated/**,!**/generated/**and included by**crates/biome_tailwind_factory/src/generated/syntax_factory.rsis excluded by!**/generated/**,!**/generated/**and included by**crates/biome_tailwind_parser/tests/tailwind_specs/error/arbitrary-candidate/missing-property.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/error/arbitrary-candidate/missing-value-in-arbitrary.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/error/incomplete-arbitrary-value-0.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/error/incomplete-arbitrary-value-1.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/error/incomplete-arbitrary-value-2.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/error/incomplete-arbitrary-variant.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/error/missing-modifier-value-1.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/error/missing-modifier-value.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/error/missing-value.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/brackets/gradient.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/brackets/image-url.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/brackets/shadow.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/candidates/arbitrary-candidate-0.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/candidates/arbitrary-candidate-1.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/candidates/arbitrary-candidate-2.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/candidates/arbitrary-candidate-3.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/gradients/precise-control.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/gradients/simple.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/simple/arbitrary-value-0.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/simple/arbitrary-value-1.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/simple/base-has-dash-0.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/simple/base-has-dash-1.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/simple/base-has-dash-2.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/simple/basic-0.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/simple/basic-1.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/simple/css-value.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/simple/important.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/simple/modifier.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/simple/multiple-spaces.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/simple/multiple.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/simple/negative.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/simple/static.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/stress/stress-1.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/stress/stress-2.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/variants/arbitrary-variant.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/variants/functional-arbirary-param.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/variants/functional-named-param.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/variants/hover.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_parser/tests/tailwind_specs/ok/variants/hover_focus.txt.snapis excluded by!**/*.snapand included by**crates/biome_tailwind_syntax/src/generated/nodes.rsis excluded by!**/generated/**,!**/generated/**and included by**crates/biome_tailwind_syntax/src/generated/nodes_mut.rsis excluded by!**/generated/**,!**/generated/**and included by**
📒 Files selected for processing (11)
.github/labeler.yml(1 hunks)crates/biome_parser/src/lexer.rs(2 hunks)crates/biome_tailwind_parser/src/lexer/mod.rs(2 hunks)crates/biome_tailwind_parser/src/lexer/tests.rs(1 hunks)crates/biome_tailwind_parser/src/syntax/mod.rs(4 hunks)crates/biome_tailwind_parser/src/syntax/variant.rs(1 hunks)crates/biome_tailwind_parser/src/token_source.rs(1 hunks)crates/biome_tailwind_parser/tests/tailwind_specs/ok/gradients/precise-control.txt(1 hunks)crates/biome_tailwind_parser/tests/tailwind_specs/ok/gradients/simple.txt(1 hunks)crates/biome_tailwind_parser/tests/tailwind_specs/ok/simple/negative.txt(1 hunks)xtask/codegen/tailwind.ungram(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{rs,toml}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Format Rust and TOML files before committing (e.g., via
just f)
Files:
crates/biome_tailwind_parser/src/syntax/variant.rscrates/biome_tailwind_parser/src/token_source.rscrates/biome_parser/src/lexer.rscrates/biome_tailwind_parser/src/syntax/mod.rscrates/biome_tailwind_parser/src/lexer/tests.rscrates/biome_tailwind_parser/src/lexer/mod.rs
**/*.rs
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Document rules, assists, and their options with inline rustdoc in the Rust source
Files:
crates/biome_tailwind_parser/src/syntax/variant.rscrates/biome_tailwind_parser/src/token_source.rscrates/biome_parser/src/lexer.rscrates/biome_tailwind_parser/src/syntax/mod.rscrates/biome_tailwind_parser/src/lexer/tests.rscrates/biome_tailwind_parser/src/lexer/mod.rs
🧠 Learnings (34)
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Do not attempt to fix code; if a mandatory token/node is missing, return `None` instead
Applied to files:
crates/biome_tailwind_parser/src/syntax/variant.rscrates/biome_tailwind_parser/src/syntax/mod.rscrates/biome_tailwind_parser/src/lexer/mod.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : Use options/full_options/use_options code block modifiers as specified to demonstrate configuration in docs; keep modifier order consistent
Applied to files:
crates/biome_tailwind_parser/src/syntax/variant.rs.github/labeler.ymlcrates/biome_tailwind_parser/src/syntax/mod.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : Avoid deep indentation by using combinators (map, filter, and_then) rather than nested if-let/unwrap chains
Applied to files:
crates/biome_tailwind_parser/src/syntax/variant.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/**/*.rs : After generation, remove usages of `format_verbatim_node` and implement real formatting with biome_formatter utilities
Applied to files:
crates/biome_tailwind_parser/src/syntax/variant.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Parse rules should return ParsedSyntax; return Absent without consuming tokens when the node cannot be predicted
Applied to files:
crates/biome_tailwind_parser/src/syntax/variant.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/lint/nursery/**/*.rs : Place all new rules in the nursery group
Applied to files:
.github/labeler.yml
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : In declare_lint_rule! macros, set version: "next"
Applied to files:
.github/labeler.yml
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : Rule documentation: first paragraph must be a single line summary
Applied to files:
.github/labeler.yml
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/style/**/*.rs : Rules in style group must have severity: info or warn (prefer info if unsure)
Applied to files:
.github/labeler.yml
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : Set the language field in declare_lint_rule! to the most appropriate dialect (js/jsx/ts/tsx)
Applied to files:
.github/labeler.yml
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/performance/**/*.rs : Rules in performance group must have severity: warn
Applied to files:
.github/labeler.yml
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : If a rule is inspired by an external source, populate sources in declare_lint_rule! with RuleSource::{Eslint,...} and same()/inspired()
Applied to files:
.github/labeler.yml
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Place per-rule options types in biome_rule_options crate under lib/, one file per rule
Applied to files:
.github/labeler.yml
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/suspicious/**/*.rs : Rules in suspicious group must have severity: warn or error (prefer warn if unsure)
Applied to files:
.github/labeler.yml
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : If a rule provides a code action, add fix_kind to declare_lint_rule! (FixKind::Safe or ::Unsafe)
Applied to files:
.github/labeler.yml
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Applies to crates/biome_parser/crates/biome_*_{syntax,factory}/** : Create per-language crates biome_<lang>_syntax and biome_<lang>_factory under crates/
Applied to files:
.github/labeler.yml
📚 Learning: 2025-10-15T09:25:05.698Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:25:05.698Z
Learning: Applies to crates/biome_service/../biome_lsp/src/server.tests.rs : Keep end-to-end LSP tests in ../biome_lsp/src/server.tests.rs
Applied to files:
.github/labeler.yml
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : For cross-file analyses, use custom visitors/Queryable to emit matches during main traversal to avoid redundant passes
Applied to files:
.github/labeler.yml
📚 Learning: 2025-10-15T09:20:45.587Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_aria_metadata/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:20:45.587Z
Learning: Applies to crates/biome_aria_metadata/**/{build.rs,aria-data.json} : Keep aria-data.json at the expected location/name because build.rs uses it to generate ARIA metadata
Applied to files:
.github/labeler.yml
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/tests/quick_test.rs : Quick test lives in biome_js_analyze/tests/quick_test.rs; unignore #[ignore] and set rule filter and SOURCE for ad-hoc runs
Applied to files:
.github/labeler.yml
📚 Learning: 2025-10-26T15:28:00.951Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-26T15:28:00.951Z
Learning: Applies to **/*.{rs,toml} : Format Rust and TOML files before committing (e.g., via `just f`)
Applied to files:
.github/labeler.yml
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/**/Cargo.toml : Add the specified dev-dependencies under [dev-dependencies] for the test infrastructure
Applied to files:
.github/labeler.yml
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Lexer must implement the biome_parser::Lexer trait
Applied to files:
crates/biome_parser/src/lexer.rscrates/biome_tailwind_parser/src/syntax/mod.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Applies to crates/biome_parser/crates/**/src/lexer/mod.rs : Create a lexer module at crates/<parser_crate>/src/lexer/mod.rs
Applied to files:
crates/biome_parser/src/lexer.rscrates/biome_tailwind_parser/src/lexer/mod.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/tests/spec_tests.rs : In tests/spec_tests.rs, generate tests with `tests_macros::gen_tests! {"tests/specs/html/**/*.html", crate::spec_test::run, ""}`
Applied to files:
crates/biome_tailwind_parser/tests/tailwind_specs/ok/gradients/simple.txtcrates/biome_tailwind_parser/tests/tailwind_specs/ok/simple/negative.txt
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/tests/** : Create a tests directory containing a specs subfolder and the files spec_test.rs, spec_tests.rs, and language.rs
Applied to files:
crates/biome_tailwind_parser/tests/tailwind_specs/ok/gradients/simple.txtcrates/biome_tailwind_parser/tests/tailwind_specs/ok/simple/negative.txt
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : For non-mandatory tokens, use the provided helper constructors (e.g., `token`, `space_token`, `dynamic_token`)
Applied to files:
crates/biome_tailwind_parser/src/syntax/mod.rscrates/biome_tailwind_parser/src/lexer/mod.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : When a token is mandatory and present in the AST, use the AST-provided token (e.g., `node.l_paren_token().format()`) instead of emitting a static token
Applied to files:
crates/biome_tailwind_parser/src/syntax/mod.rscrates/biome_tailwind_parser/src/lexer/mod.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : Avoid avoidable string allocations; compare against &str or TokenText rather than allocating Strings
Applied to files:
crates/biome_tailwind_parser/src/syntax/mod.rscrates/biome_tailwind_parser/src/lexer/mod.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Use p.eat for optional tokens, p.expect for required tokens; use .ok() for optional nodes and .or_add_diagnostic(...) for required nodes
Applied to files:
crates/biome_tailwind_parser/src/syntax/mod.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/tests/language.rs : Create tests/language.rs defining `HtmlTestFormatLanguage` and implement the TestFormatLanguage trait
Applied to files:
crates/biome_tailwind_parser/src/lexer/tests.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_tailwind_parser/src/lexer/mod.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/tests/specs/**/{invalid*,valid*}.* : Name snapshot test files with invalid* and valid* prefixes to indicate reported vs non-reported cases
Applied to files:
crates/biome_tailwind_parser/tests/tailwind_specs/ok/simple/negative.txt
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/tests/specs/html/**/*.html : Place HTML test cases under tests/specs/html as .html files discovered by the test macro
Applied to files:
crates/biome_tailwind_parser/tests/tailwind_specs/ok/simple/negative.txt
🧬 Code graph analysis (2)
crates/biome_tailwind_parser/src/syntax/mod.rs (1)
crates/biome_tailwind_parser/src/syntax/value.rs (1)
parse_value(9-17)
crates/biome_tailwind_parser/src/lexer/mod.rs (2)
crates/biome_parser/src/lexer.rs (2)
current(30-30)current(536-542)crates/biome_tailwind_parser/src/token_source.rs (1)
current(111-113)
⏰ 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). (19)
- GitHub Check: Documentation
- GitHub Check: Bench (biome_css_analyze)
- GitHub Check: Bench (biome_css_parser)
- GitHub Check: Test (depot-ubuntu-24.04-arm-16)
- GitHub Check: Bench (biome_css_formatter)
- GitHub Check: Test (depot-windows-2022-16)
- GitHub Check: Lint project (depot-windows-2022)
- GitHub Check: Parser conformance
- GitHub Check: Test Node.js API
- GitHub Check: autofix
- GitHub Check: Check Dependencies
- GitHub Check: Bench (biome_graphql_parser)
- GitHub Check: Bench (biome_js_analyze)
- GitHub Check: Bench (biome_js_parser)
- GitHub Check: Bench (biome_js_formatter)
- GitHub Check: Bench (biome_graphql_formatter)
- GitHub Check: Bench (biome_json_parser)
- GitHub Check: Bench (biome_json_formatter)
- GitHub Check: Bench (biome_json_analyze)
🔇 Additional comments (16)
crates/biome_tailwind_parser/tests/tailwind_specs/ok/gradients/precise-control.txt (1)
1-1: LGTM!Valid Tailwind gradient syntax for testing precise percentage control.
.github/labeler.yml (1)
114-117: LGTM!Labeler rule follows the established pattern and correctly targets Tailwind-related crates.
crates/biome_tailwind_parser/tests/tailwind_specs/ok/gradients/simple.txt (1)
1-1: LGTM!Valid Tailwind gradient syntax for testing basic gradient parsing.
xtask/codegen/tailwind.ungram (1)
62-62: LGTM!The optional negative field correctly models Tailwind's negative utility syntax (e.g.,
-mt-4). Placement before the candidate is logical.crates/biome_parser/src/lexer.rs (1)
223-233: LGTM!The
prev_byte_atmethod is correctly implemented with proper boundary checks. It mirrorsbyte_atfor backwards lookups, which is useful for the negative token context handling.crates/biome_tailwind_parser/tests/tailwind_specs/ok/simple/negative.txt (1)
1-1: LGTM!Test data correctly demonstrates negative Tailwind utilities, including variants with negatives (e.g.,
hover:-mt-2).crates/biome_tailwind_parser/src/lexer/tests.rs (1)
195-203: LGTM!Test correctly validates the
SawNegativecontext, expecting a DASH token followed by the base identifier. Well-structured.crates/biome_tailwind_parser/src/syntax/variant.rs (1)
82-85: LGTM!Correct guard: variants cannot start with a negative sign. The negative prefix belongs to the candidate level (e.g., in
hover:-mt-2, the-is part of the candidate, not the variant).crates/biome_tailwind_parser/src/token_source.rs (1)
25-26: LGTM!Clear documentation and a sensible addition to handle negative Tailwind candidates.
crates/biome_tailwind_parser/src/lexer/mod.rs (1)
270-270: LGTM!Correctly routes the
SawNegativecontext to the new consumption path.crates/biome_tailwind_parser/src/syntax/mod.rs (6)
72-74: LGTM!Correctly handles the negative prefix by switching to the
SawNegativecontext.
59-60: LGTM!Cleaner recovery pattern using
enable_recovery_on_line_break()instead of explicitly including NEWLINE/EOF in the token set.
80-81: LGTM!Consistent recovery pattern with the candidate list recovery above.
121-121: LGTM!Using
expectinstead ofbumpis more defensive and follows parser conventions for required tokens.
124-125: LGTM!Recovery set properly updated with line break recovery enabled.
202-202: Verify the recovery pattern inconsistency.Unlike the other recovery token set changes (lines 59-60, 80-81, 124-125), this one retains
NEWLINEin the token set and doesn't callenable_recovery_on_line_break(). Is this intentional for modifier recovery, or should it follow the same pattern as the others?
e0ee9c0 to
5b79888
Compare
Summary
Putting a
-in front of a candidate makes it a negative value.Test Plan
Added tests.
Also tested against tailwind's playground: https://play.tailwindcss.com/gMIIXZnNPl
Docs
no changeset because this parser isn't used anywhere yet