feat(css): use ScssExpression in ScssNestingDeclaration and CssGenericProperty#9328
feat(css): use ScssExpression in ScssNestingDeclaration and CssGenericProperty#9328denbezrukov merged 7 commits intomainfrom
Conversation
|
Parser conformance results onjs/262
jsx/babel
markdown/commonmark
symbols/microsoft
ts/babel
ts/microsoft
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughReplaces generic component-value handling for property and nesting declarations with SCSS expression-aware parsing and formatting. Adds Possibly related PRs
Suggested labels
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
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Merging this PR will not alter performance
Comparing Footnotes
|
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (7)
crates/biome_css_parser/tests/css_test_suite/error/scss/expression/paren-map-missing-value.scss (1)
1-1: Tiny wording nit: make the fixture comment singular.“missing pair values” reads plural, but this case has one missing value. A tighter comment will make the intent crystal clear for future readers.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/biome_css_parser/tests/css_test_suite/error/scss/expression/paren-map-missing-value.scss` at line 1, Update the fixture comment text "// Map inferred from parens should recover missing pair values" to use singular wording since the test covers a single missing value; replace "missing pair values" with "missing pair value" so the comment reads "// Map inferred from parens should recover missing pair value" to make the intent clearer for readers and maintainers.crates/biome_css_parser/tests/css_test_suite/error/scss/expression/missing-expressions.scss (1)
13-14: Optional: add one EOF-boundary malformed-expression case.Consider a final case with a missing expression at end-of-file (no trailing token/semicolon) to guard recovery at stream end.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/biome_css_parser/tests/css_test_suite/error/scss/expression/missing-expressions.scss` around lines 13 - 14, Add an EOF-boundary malformed-expression test variation: create a similar map with a trailing colon but no trailing semicolon or newline at EOF to ensure recovery at stream end (e.g. add a variable like $map-trailing-eof with value "(b: 1, c:)" and leave the file ending immediately after it). Place it alongside the existing $map-trailing case so the parser sees the missing expression at EOF.crates/biome_css_parser/tests/css_test_suite/ok/scss/value/minus-operator.scss (1)
1-1: Exclude this CSS parser test fixture from any stylelint CI rules if they're added.This fixture intentionally uses non-standard selectors and property names to test the parser's handling of the minus operator—code that would rightfully trigger
selector-type-no-unknown,property-no-unknown, and related stylelint rules. Since it's a parser test case rather than production code, either add it to.stylelintignoreor configure stylelint to skip the entirecrates/biome_css_parser/tests/css_test_suite/directory.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/biome_css_parser/tests/css_test_suite/ok/scss/value/minus-operator.scss` at line 1, Exclude the test fixture minus-operator.scss (the parser test using non-standard selectors/properties) from stylelint rules by either adding its path or the entire css_test_suite directory to .stylelintignore or updating the stylelint config to ignore crates/biome_css_parser/tests/css_test_suite/ so stylelint rules like selector-type-no-unknown and property-no-unknown are skipped for these parser test files.crates/biome_css_parser/src/syntax/value/attr.rs (1)
171-186: Please add one regression fixture for nestedif()in attr fallback.Because fallback list recovery now stops on
;, a case likeattr(x, if(media(print): a; else: b;))is worth pinning down.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/biome_css_parser/src/syntax/value/attr.rs` around lines 171 - 186, Add a regression fixture that parses a nested if() inside an attr fallback like "attr(x, if(media(print): a; else: b;))" to ensure recovery behavior (in functions is_at_list_end and recover using ParseRecoveryTokenSet with token_set!(T![')'], T![;]) and CSS_BOGUS_PROPERTY_VALUE / expected_component_value) doesn't prematurely stop on the inner ';'. Create a test case that feeds that exact string into the attr fallback parsing path and asserts the full nested if() is accepted (or produces the expected recovery), so this scenario is pinned down for future changes.crates/biome_css_parser/tests/css_test_suite/ok/scss/value/binary-operators.scss (1)
19-29: The at-rule block is clearly marked TODO; nice placeholder.If you want, I can draft the follow-up fixture set once
@function/@debugsupport is wired in this suite.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/biome_css_parser/tests/css_test_suite/ok/scss/value/binary-operators.scss` around lines 19 - 29, The test fixture contains a TODO block noting missing support for at-rules like `@function` and `@debug`; implement support or add follow-up test fixtures: update the parser handling for at-rules referenced (e.g., recognize "@function f()", "@debug") and ensure the value parsing logic treats "/" as division only in expression contexts (e.g., in "@function f() { return a / b; }" and "1 * 2 / 3") but not in standalone debug values like "15px / 30px" or in cases with parentheses, function calls, variables, and namespace access (e.g., "(1 + 2) / 3", "fn() / 3", "$var / 3", "mod.$var / 3"); add or enable tests for these cases once `@function/`@debug are supported and ensure AST nodes or tokenization for at-rules and binary-operator division are handled accordingly.crates/biome_css_semantic/src/events.rs (1)
241-245: Drop the redundant.clone()onto_trimmed_string().This allocates twice for no gain.
🧹 Tiny tidy-up
- syntax = Some(value.to_trimmed_string().clone()); + syntax = Some(value.to_trimmed_string());🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/biome_css_semantic/src/events.rs` around lines 241 - 245, The assignment to syntax unnecessarily clones the string returned by value.to_trimmed_string(); remove the redundant .clone() so that syntax is set with the String returned by value.to_trimmed_string() (i.e., change the expression inside syntax = Some(...) accordingly), leaving prop.value() and to_trimmed_string() usage intact.crates/biome_css_analyze/src/lint/correctness/no_invalid_grid_areas.rs (1)
109-123: Consider removing temporaryVecallocations inflat_map.You can
filter_mapthe list first, thenflat_mapits iterator directly.Based on learnings: "Use functional methods like `map`, `filter`, and `and_then` on `Result` and `Option` types instead of nested `if let` statements to avoid excessive indentation".♻️ Small refactor sketch
- .flat_map(|grid_props| { - let value = match grid_props { - Ok(value) => value, - Err(_) => return Vec::new(), - }; - let list = match value { - AnyCssGenericPropertyValueOrExpression::CssGenericComponentValueList(list) => { - list - } - AnyCssGenericPropertyValueOrExpression::ScssExpression(_) => return Vec::new(), - }; - - list.into_iter() - .filter_map(|x| x.as_any_css_value()?.as_css_string()?.value_token().ok()) - .collect::<Vec<_>>() - }) + .filter_map(|grid_props| { + let value = grid_props.ok()?; + match value { + AnyCssGenericPropertyValueOrExpression::CssGenericComponentValueList(list) => { + Some(list) + } + AnyCssGenericPropertyValueOrExpression::ScssExpression(_) => None, + } + }) + .flat_map(|list| { + list.into_iter() + .filter_map(|x| x.as_any_css_value()?.as_css_string()?.value_token().ok()) + })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/biome_css_analyze/src/lint/correctness/no_invalid_grid_areas.rs` around lines 109 - 123, The closure passed to flat_map allocates temporary Vecs for early returns; instead, transform the outer iterator of grid_props using filter_map to skip Err(_) and ScssExpression cases and yield the inner list directly, then flat_map that list iterator and apply the existing filter_map on each component value (referencing the closure variables grid_props, value, list and the enum AnyCssGenericPropertyValueOrExpression). Concretely: convert the match on grid_props to a filter_map that returns Some(list) only for Ok(AnyCssGenericComponentValueList(list)), drop the Vec::new() returns, then replace the inner collect::<Vec<_>>() with a flat_map over list.into_iter().filter_map(|x| x.as_any_css_value()?.as_css_string()?.value_token().ok()) so no intermediate Vec is allocated.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@crates/biome_css_parser/src/syntax/at_rule/supports/mod.rs`:
- Around line 307-309: parse_supports_declaration(...) is being called with
.or_recover(...).ok() and its result discarded, which lets empty SCSS `@supports
(color:)` silently pass; change the call site to capture the result of
parse_supports_declaration(p).or_recover(p, &AnyInParensParseRecovery,
expected_declaration) and if it returns None emit the missing component-value
diagnostic (use the existing expected_declaration/expected_component_value path)
instead of swallowing it so empty values produce the proper error; update the
analogous block around lines 348-352 the same way.
In `@crates/biome_css_parser/src/syntax/property/mod.rs`:
- Around line 85-89: The enabled-path for
parse_composes_property_with_value_end_set currently ignores the incoming
value_end_set/recovery_end_set and uses the fixed ComposesClassList end set;
change the enabled-path and its recovery code to use the dynamic end set passed
into the function. Concretely, replace hard-coded ComposesClassList end-set
usage in the enabled branch and its recovery calls with the composed end set
derived from the function's value_end_set/recovery_end_set parameters (i.e.,
pass value_end_set into whatever helper or check currently uses
ComposesClassList::end() and also pass recovery_end_set into the list-recovery
routine) so both normal parse and recovery use the same boundary sets.
In
`@crates/biome_css_parser/tests/css_test_suite/ok/scss/value/logic-eq-operator.scss`:
- Line 1: Add a file-level stylelint disable comment at the top to suppress
fixture-only noise for the synthetic selectors/properties (e.g., selector "foo"
and any "test-*" properties) by disabling the specific noisy rules (for example
selector-type-no-unknown and property-no-unknown) for the whole file; place a
single stylelint-disable comment as the first line so linting is suppressed for
this fixture and no further per-line changes are needed.
---
Nitpick comments:
In `@crates/biome_css_analyze/src/lint/correctness/no_invalid_grid_areas.rs`:
- Around line 109-123: The closure passed to flat_map allocates temporary Vecs
for early returns; instead, transform the outer iterator of grid_props using
filter_map to skip Err(_) and ScssExpression cases and yield the inner list
directly, then flat_map that list iterator and apply the existing filter_map on
each component value (referencing the closure variables grid_props, value, list
and the enum AnyCssGenericPropertyValueOrExpression). Concretely: convert the
match on grid_props to a filter_map that returns Some(list) only for
Ok(AnyCssGenericComponentValueList(list)), drop the Vec::new() returns, then
replace the inner collect::<Vec<_>>() with a flat_map over
list.into_iter().filter_map(|x|
x.as_any_css_value()?.as_css_string()?.value_token().ok()) so no intermediate
Vec is allocated.
In `@crates/biome_css_parser/src/syntax/value/attr.rs`:
- Around line 171-186: Add a regression fixture that parses a nested if() inside
an attr fallback like "attr(x, if(media(print): a; else: b;))" to ensure
recovery behavior (in functions is_at_list_end and recover using
ParseRecoveryTokenSet with token_set!(T![')'], T![;]) and
CSS_BOGUS_PROPERTY_VALUE / expected_component_value) doesn't prematurely stop on
the inner ';'. Create a test case that feeds that exact string into the attr
fallback parsing path and asserts the full nested if() is accepted (or produces
the expected recovery), so this scenario is pinned down for future changes.
In
`@crates/biome_css_parser/tests/css_test_suite/error/scss/expression/missing-expressions.scss`:
- Around line 13-14: Add an EOF-boundary malformed-expression test variation:
create a similar map with a trailing colon but no trailing semicolon or newline
at EOF to ensure recovery at stream end (e.g. add a variable like
$map-trailing-eof with value "(b: 1, c:)" and leave the file ending immediately
after it). Place it alongside the existing $map-trailing case so the parser sees
the missing expression at EOF.
In
`@crates/biome_css_parser/tests/css_test_suite/error/scss/expression/paren-map-missing-value.scss`:
- Line 1: Update the fixture comment text "// Map inferred from parens should
recover missing pair values" to use singular wording since the test covers a
single missing value; replace "missing pair values" with "missing pair value" so
the comment reads "// Map inferred from parens should recover missing pair
value" to make the intent clearer for readers and maintainers.
In
`@crates/biome_css_parser/tests/css_test_suite/ok/scss/value/binary-operators.scss`:
- Around line 19-29: The test fixture contains a TODO block noting missing
support for at-rules like `@function` and `@debug`; implement support or add
follow-up test fixtures: update the parser handling for at-rules referenced
(e.g., recognize "@function f()", "@debug") and ensure the value parsing logic
treats "/" as division only in expression contexts (e.g., in "@function f() {
return a / b; }" and "1 * 2 / 3") but not in standalone debug values like "15px
/ 30px" or in cases with parentheses, function calls, variables, and namespace
access (e.g., "(1 + 2) / 3", "fn() / 3", "$var / 3", "mod.$var / 3"); add or
enable tests for these cases once `@function/`@debug are supported and ensure AST
nodes or tokenization for at-rules and binary-operator division are handled
accordingly.
In
`@crates/biome_css_parser/tests/css_test_suite/ok/scss/value/minus-operator.scss`:
- Line 1: Exclude the test fixture minus-operator.scss (the parser test using
non-standard selectors/properties) from stylelint rules by either adding its
path or the entire css_test_suite directory to .stylelintignore or updating the
stylelint config to ignore crates/biome_css_parser/tests/css_test_suite/ so
stylelint rules like selector-type-no-unknown and property-no-unknown are
skipped for these parser test files.
In `@crates/biome_css_semantic/src/events.rs`:
- Around line 241-245: The assignment to syntax unnecessarily clones the string
returned by value.to_trimmed_string(); remove the redundant .clone() so that
syntax is set with the String returned by value.to_trimmed_string() (i.e.,
change the expression inside syntax = Some(...) accordingly), leaving
prop.value() and to_trimmed_string() usage intact.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 9a87795a-394c-41e6-83c1-7586673e2c07
⛔ Files ignored due to path filters (56)
crates/biome_css_factory/src/generated/node_factory.rsis excluded by!**/generated/**,!**/generated/**and included by**crates/biome_css_factory/src/generated/syntax_factory.rsis excluded by!**/generated/**,!**/generated/**and included by**crates/biome_css_formatter/tests/specs/css/scss/expression/bracketed-values.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_formatter/tests/specs/css/scss/expression/edge-cases.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_formatter/tests/specs/css/scss/expression/formatting.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_formatter/tests/specs/css/scss/expression/function-call.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/error/at_rule/at_rule_container/at_rule_container_style_query_error.css.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/error/function/if.css.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/error/scss/at-rule/container-general-enclosed.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/error/scss/at-rule/supports-general-enclosed.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/error/scss/expression/arglist-ellipsis-recovery.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/error/scss/expression/ellipsis.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/error/scss/expression/list-map-paren.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/error/scss/expression/list-recovery.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/error/scss/expression/missing-expressions.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/error/scss/expression/paren-map-missing-value.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/error/scss/recovery/map-missing-value.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/error/scss/value/qualified-name-dollar-function.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/error/scss/value/qualified-name-missing-member.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/at-rule/page.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/at-rule/supports-expression.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/comment/line.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/comment/multiline.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/comment/nested.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/declaration/global-flag.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/declaration/important.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/declaration/nested-variables.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/declaration/spacing-after-colon.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/expression/complex-expressions.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/expression/core.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/expression/edge-cases-extra.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/expression/empty-map.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/expression/fallback-values.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/expression/keyword-argument-context.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/expression/list-map-paren.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/expression/map-key-colon.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/expression/map-vs-paren-list.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/expression/unary-parenthesized.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/recovery/list-space-trailing-comma.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/value/binary-operators.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/value/bracketed-values.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/value/css-if-function.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/value/division-operator.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/value/function-args-inline.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/value/logic-eq-operator.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/value/logic-ne-operator.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/value/minus-operator.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/value/number.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/value/operator-precedence.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/value/parent-and-colon-values.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/value/plus-operator.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/value/qualified-names.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/value/unary-operator-chain.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_parser/tests/css_test_suite/ok/scss/value/unary-operators.scss.snapis excluded by!**/*.snapand included by**crates/biome_css_syntax/src/generated/nodes.rsis excluded by!**/generated/**,!**/generated/**and included by**crates/biome_css_syntax/src/generated/nodes_mut.rsis excluded by!**/generated/**,!**/generated/**and included by**
📒 Files selected for processing (46)
crates/biome_css_analyze/src/lint/a11y/use_generic_font_names.rscrates/biome_css_analyze/src/lint/correctness/no_invalid_grid_areas.rscrates/biome_css_analyze/src/lint/suspicious/no_duplicate_font_names.rscrates/biome_css_formatter/src/css/any/generic_property_value_or_expression.rscrates/biome_css_formatter/src/css/any/mod.rscrates/biome_css_formatter/src/generated.rscrates/biome_css_formatter/tests/specs/css/scss/expression/bracketed-values.scsscrates/biome_css_formatter/tests/specs/css/scss/expression/edge-cases.scsscrates/biome_css_formatter/tests/specs/css/scss/expression/formatting.scsscrates/biome_css_formatter/tests/specs/css/scss/expression/function-call.scsscrates/biome_css_parser/src/syntax/at_rule/container/mod.rscrates/biome_css_parser/src/syntax/at_rule/import.rscrates/biome_css_parser/src/syntax/at_rule/supports/mod.rscrates/biome_css_parser/src/syntax/declaration.rscrates/biome_css_parser/src/syntax/mod.rscrates/biome_css_parser/src/syntax/property/mod.rscrates/biome_css_parser/src/syntax/value/attr.rscrates/biome_css_parser/src/syntax/value/if.rscrates/biome_css_parser/tests/css_test_suite/error/scss/expression/arglist-ellipsis-recovery.scsscrates/biome_css_parser/tests/css_test_suite/error/scss/expression/ellipsis.scsscrates/biome_css_parser/tests/css_test_suite/error/scss/expression/list-recovery.scsscrates/biome_css_parser/tests/css_test_suite/error/scss/expression/missing-expressions.scsscrates/biome_css_parser/tests/css_test_suite/error/scss/expression/paren-map-missing-value.scsscrates/biome_css_parser/tests/css_test_suite/error/scss/recovery/map-missing-value.scsscrates/biome_css_parser/tests/css_test_suite/ok/scss/at-rule/supports-expression.scsscrates/biome_css_parser/tests/css_test_suite/ok/scss/expression/complex-expressions.scsscrates/biome_css_parser/tests/css_test_suite/ok/scss/expression/edge-cases-extra.scsscrates/biome_css_parser/tests/css_test_suite/ok/scss/expression/fallback-values.scsscrates/biome_css_parser/tests/css_test_suite/ok/scss/expression/map-key-colon.scsscrates/biome_css_parser/tests/css_test_suite/ok/scss/expression/map-vs-paren-list.scsscrates/biome_css_parser/tests/css_test_suite/ok/scss/recovery/list-space-trailing-comma.scsscrates/biome_css_parser/tests/css_test_suite/ok/scss/value/binary-operators.scsscrates/biome_css_parser/tests/css_test_suite/ok/scss/value/css-if-function.scsscrates/biome_css_parser/tests/css_test_suite/ok/scss/value/division-operator.scsscrates/biome_css_parser/tests/css_test_suite/ok/scss/value/function-args-inline.scsscrates/biome_css_parser/tests/css_test_suite/ok/scss/value/logic-eq-operator.scsscrates/biome_css_parser/tests/css_test_suite/ok/scss/value/logic-ne-operator.scsscrates/biome_css_parser/tests/css_test_suite/ok/scss/value/minus-operator.scsscrates/biome_css_parser/tests/css_test_suite/ok/scss/value/number.scsscrates/biome_css_parser/tests/css_test_suite/ok/scss/value/operator-precedence.scsscrates/biome_css_parser/tests/css_test_suite/ok/scss/value/plus-operator.scsscrates/biome_css_parser/tests/css_test_suite/ok/scss/value/unary-operator-chain.scsscrates/biome_css_parser/tests/css_test_suite/ok/scss/value/unary-operators.scsscrates/biome_css_semantic/src/events.rscrates/biome_css_semantic/src/semantic_model/model.rsxtask/codegen/css.ungram
✅ Files skipped from review due to trivial changes (3)
- crates/biome_css_parser/tests/css_test_suite/ok/scss/expression/fallback-values.scss
- crates/biome_css_parser/tests/css_test_suite/ok/scss/expression/map-key-colon.scss
- crates/biome_css_parser/tests/css_test_suite/ok/scss/expression/map-vs-paren-list.scss
There was a problem hiding this comment.
♻️ Duplicate comments (1)
crates/biome_css_parser/src/syntax/property/mod.rs (1)
85-89:⚠️ Potential issue | 🟠 MajorThread the dynamic boundary sets through
composesparsing.Line 111 still parses classes with a fixed end set, and recovery at Lines 155-177 is fixed too. In boundary-aware contexts, this can over-consume before recovery kicks in. Please wire
value_end_set/recovery_end_setinto both list-end and recovery checks.Suggested patch
-fn parse_composes_property_with_value_end_set( +fn parse_composes_property_with_value_end_set( p: &mut CssParser, value_end_set: TokenSet<CssSyntaxKind>, recovery_end_set: TokenSet<CssSyntaxKind>, ) -> ParsedSyntax { @@ - let classes = ComposesClassList.parse_list(p); + let classes = + ComposesClassList::new(value_end_set, recovery_end_set).parse_list(p); @@ -struct ComposesClassList; +struct ComposesClassList { + end_set: TokenSet<CssSyntaxKind>, + recovery_set: TokenSet<CssSyntaxKind>, +} + +impl ComposesClassList { + fn new(value_end_set: TokenSet<CssSyntaxKind>, recovery_end_set: TokenSet<CssSyntaxKind>) -> Self { + Self { + end_set: value_end_set.union(token_set!(T![from])), + recovery_set: recovery_end_set.union(token_set!(T![from])), + } + } +} @@ fn is_at_list_end(&self, p: &mut Self::Parser<'_>) -> bool { - p.at_ts(END_OF_COMPOSES_CLASS_TOKEN_SET) + p.at_ts(self.end_set) } @@ - parsed_element.or_recover(p, &ComposesClassListParseRecovery, expected_identifier) + parsed_element.or_recover( + p, + &ComposesClassListParseRecovery::new(self.recovery_set), + expected_identifier, + ) } } -struct ComposesClassListParseRecovery; +struct ComposesClassListParseRecovery { + recovery_set: TokenSet<CssSyntaxKind>, +} + +impl ComposesClassListParseRecovery { + fn new(recovery_set: TokenSet<CssSyntaxKind>) -> Self { + Self { recovery_set } + } +} @@ fn is_at_recovered(&self, p: &mut Self::Parser<'_>) -> bool { - p.at_ts(END_OF_COMPOSES_CLASS_TOKEN_SET) || is_at_identifier(p) + p.at_ts(self.recovery_set) || is_at_identifier(p) } }Also applies to: 111-112, 155-177
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/biome_css_parser/src/syntax/property/mod.rs` around lines 85 - 89, The composes parsing function parse_composes_property_with_value_end_set is still using fixed end sets when parsing class lists and during recovery (the code paths that check for list termination and the recovery loop), which can over-consume in boundary-aware contexts; update the list-end checks and the recovery-condition checks inside parse_composes_property_with_value_end_set (and the helper(s) it calls for parsing class tokens) to use the passed-in value_end_set and recovery_end_set instead of the hard-coded/endset constants so both the normal list termination and the recovery loop break when any token in value_end_set or recovery_end_set is encountered; ensure you pass these sets through to any helper functions that parse individual class items so all checks consistently use the dynamic sets (refer to symbol parse_composes_property_with_value_end_set and any internal parsing/recovery loops).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@crates/biome_css_parser/src/syntax/property/mod.rs`:
- Around line 85-89: The composes parsing function
parse_composes_property_with_value_end_set is still using fixed end sets when
parsing class lists and during recovery (the code paths that check for list
termination and the recovery loop), which can over-consume in boundary-aware
contexts; update the list-end checks and the recovery-condition checks inside
parse_composes_property_with_value_end_set (and the helper(s) it calls for
parsing class tokens) to use the passed-in value_end_set and recovery_end_set
instead of the hard-coded/endset constants so both the normal list termination
and the recovery loop break when any token in value_end_set or recovery_end_set
is encountered; ensure you pass these sets through to any helper functions that
parse individual class items so all checks consistently use the dynamic sets
(refer to symbol parse_composes_property_with_value_end_set and any internal
parsing/recovery loops).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 9dab6a9a-9215-4758-b28a-8d0d6b15f67e
📒 Files selected for processing (2)
crates/biome_css_parser/src/syntax/mod.rscrates/biome_css_parser/src/syntax/property/mod.rs
There was a problem hiding this comment.
🧹 Nitpick comments (1)
crates/biome_css_parser/src/syntax/at_rule/supports/mod.rs (1)
350-367: Consider extracting this value-parsing logic into a shared helper.This block now closely mirrors the generic-property value parsing in
crates/biome_css_parser/src/syntax/property/mod.rs. A shared helper would reduce behavioural drift between normal declarations and@supportsdeclarations.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/biome_css_parser/src/syntax/at_rule/supports/mod.rs` around lines 350 - 367, The parsing logic in parse_supports_property_value duplicates the generic-property parsing in property::mod; extract the common behavior into a shared helper (e.g., parse_property_value_allow_empty) that encapsulates the CssSyntaxFeatures::Scss branch using parse_scss_expression_allow_empty_value_until and the non-SCSS branch using GenericComponentValueList::new(...).parse_list, and use that helper from parse_supports_property_value and the equivalent function in crates/biome_css_parser/src/syntax/property/mod.rs; preserve the existing error reporting via expected_component_value and p.cur_range() so callers (parse_supports_property_value and the property parser) get identical behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@crates/biome_css_parser/src/syntax/at_rule/supports/mod.rs`:
- Around line 350-367: The parsing logic in parse_supports_property_value
duplicates the generic-property parsing in property::mod; extract the common
behavior into a shared helper (e.g., parse_property_value_allow_empty) that
encapsulates the CssSyntaxFeatures::Scss branch using
parse_scss_expression_allow_empty_value_until and the non-SCSS branch using
GenericComponentValueList::new(...).parse_list, and use that helper from
parse_supports_property_value and the equivalent function in
crates/biome_css_parser/src/syntax/property/mod.rs; preserve the existing error
reporting via expected_component_value and p.cur_range() so callers
(parse_supports_property_value and the property parser) get identical behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 28162075-3e4c-4c4b-bfff-03e773ec2781
📒 Files selected for processing (1)
crates/biome_css_parser/src/syntax/at_rule/supports/mod.rs
Summary
Updates SCSS nested property parsing to use
ScssExpressionforScssNestingDeclarationandCssGenericPropertyvaluesinstead of
CssGenericComponentValueList.Test Plan
cargo test -p biome_css_parsercargo test -p biome_css_formatter