mirror of
https://github.com/biomejs/biome.git
synced 2025-12-23 08:21:13 +00:00
Merge 7df03effb5 into b573d14a5c
This commit is contained in:
commit
eb16eb8360
17 changed files with 1243 additions and 640 deletions
|
|
@ -3585,6 +3585,16 @@ where
|
|||
slots,
|
||||
))
|
||||
}
|
||||
pub fn css_bogus_if_test_boolean_expr<I>(slots: I) -> CssBogusIfTestBooleanExpr
|
||||
where
|
||||
I: IntoIterator<Item = Option<SyntaxElement>>,
|
||||
I::IntoIter: ExactSizeIterator,
|
||||
{
|
||||
CssBogusIfTestBooleanExpr::unwrap_cast(SyntaxNode::new_detached(
|
||||
CssSyntaxKind::CSS_BOGUS_IF_TEST_BOOLEAN_EXPR,
|
||||
slots,
|
||||
))
|
||||
}
|
||||
pub fn css_bogus_keyframes_item<I>(slots: I) -> CssBogusKeyframesItem
|
||||
where
|
||||
I: IntoIterator<Item = Option<SyntaxElement>>,
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ impl SyntaxFactory for CssSyntaxFactory {
|
|||
| CSS_BOGUS_FONT_FEATURE_VALUES_ITEM
|
||||
| CSS_BOGUS_IF_BRANCH
|
||||
| CSS_BOGUS_IF_TEST
|
||||
| CSS_BOGUS_IF_TEST_BOOLEAN_EXPR
|
||||
| CSS_BOGUS_KEYFRAMES_ITEM
|
||||
| CSS_BOGUS_KEYFRAMES_NAME
|
||||
| CSS_BOGUS_LAYER
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ impl FormatRule<AnyCssIfTestBooleanExpr> for FormatAnyCssIfTestBooleanExpr {
|
|||
AnyCssIfTestBooleanExpr::AnyCssIfTestBooleanOrCombinableExpr(node) => {
|
||||
node.format().fmt(f)
|
||||
}
|
||||
AnyCssIfTestBooleanExpr::CssBogusIfTestBooleanExpr(node) => node.format().fmt(f),
|
||||
AnyCssIfTestBooleanExpr::CssIfTestBooleanNotExpr(node) => node.format().fmt(f),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
use crate::FormatBogusNodeRule;
|
||||
use biome_css_syntax::CssBogusIfTestBooleanExpr;
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub(crate) struct FormatCssBogusIfTestBooleanExpr;
|
||||
impl FormatBogusNodeRule<CssBogusIfTestBooleanExpr> for FormatCssBogusIfTestBooleanExpr {}
|
||||
|
|
@ -11,6 +11,7 @@ pub(crate) mod bogus_font_family_name;
|
|||
pub(crate) mod bogus_font_feature_values_item;
|
||||
pub(crate) mod bogus_if_branch;
|
||||
pub(crate) mod bogus_if_test;
|
||||
pub(crate) mod bogus_if_test_boolean_expr;
|
||||
pub(crate) mod bogus_keyframes_item;
|
||||
pub(crate) mod bogus_keyframes_name;
|
||||
pub(crate) mod bogus_layer;
|
||||
|
|
|
|||
|
|
@ -7873,6 +7873,46 @@ impl IntoFormat<CssFormatContext> for biome_css_syntax::CssBogusIfTest {
|
|||
)
|
||||
}
|
||||
}
|
||||
impl FormatRule<biome_css_syntax::CssBogusIfTestBooleanExpr>
|
||||
for crate::css::bogus::bogus_if_test_boolean_expr::FormatCssBogusIfTestBooleanExpr
|
||||
{
|
||||
type Context = CssFormatContext;
|
||||
#[inline(always)]
|
||||
fn fmt(
|
||||
&self,
|
||||
node: &biome_css_syntax::CssBogusIfTestBooleanExpr,
|
||||
f: &mut CssFormatter,
|
||||
) -> FormatResult<()> {
|
||||
FormatBogusNodeRule::<biome_css_syntax::CssBogusIfTestBooleanExpr>::fmt(self, node, f)
|
||||
}
|
||||
}
|
||||
impl AsFormat<CssFormatContext> for biome_css_syntax::CssBogusIfTestBooleanExpr {
|
||||
type Format<'a> = FormatRefWithRule<
|
||||
'a,
|
||||
biome_css_syntax::CssBogusIfTestBooleanExpr,
|
||||
crate::css::bogus::bogus_if_test_boolean_expr::FormatCssBogusIfTestBooleanExpr,
|
||||
>;
|
||||
fn format(&self) -> Self::Format<'_> {
|
||||
FormatRefWithRule::new(
|
||||
self,
|
||||
crate::css::bogus::bogus_if_test_boolean_expr::FormatCssBogusIfTestBooleanExpr::default(
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
impl IntoFormat<CssFormatContext> for biome_css_syntax::CssBogusIfTestBooleanExpr {
|
||||
type Format = FormatOwnedWithRule<
|
||||
biome_css_syntax::CssBogusIfTestBooleanExpr,
|
||||
crate::css::bogus::bogus_if_test_boolean_expr::FormatCssBogusIfTestBooleanExpr,
|
||||
>;
|
||||
fn into_format(self) -> Self::Format {
|
||||
FormatOwnedWithRule::new(
|
||||
self,
|
||||
crate::css::bogus::bogus_if_test_boolean_expr::FormatCssBogusIfTestBooleanExpr::default(
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
impl FormatRule<biome_css_syntax::CssBogusKeyframesItem>
|
||||
for crate::css::bogus::bogus_keyframes_item::FormatCssBogusKeyframesItem
|
||||
{
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@ impl ParseNodeList for GenericComponentValueList {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn is_at_generic_component_value(p: &mut CssParser) -> bool {
|
||||
pub(crate) fn is_at_generic_component_value(p: &mut CssParser) -> bool {
|
||||
is_at_any_value(p) || is_at_generic_delimiter(p)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,12 +2,15 @@ use biome_css_syntax::CssSyntaxKind;
|
|||
use biome_css_syntax::CssSyntaxKind::*;
|
||||
use biome_css_syntax::T;
|
||||
use biome_parser::Parser;
|
||||
use biome_parser::TokenSet;
|
||||
use biome_parser::parse_lists::ParseNodeList;
|
||||
use biome_parser::parse_lists::ParseSeparatedList;
|
||||
use biome_parser::parse_recovery::ParseRecovery;
|
||||
use biome_parser::parse_recovery::ParseRecoveryTokenSet;
|
||||
use biome_parser::parse_recovery::RecoveryResult;
|
||||
use biome_parser::parsed_syntax::ParsedSyntax::{Absent, Present};
|
||||
use biome_parser::prelude::{CompletedMarker, ParsedSyntax};
|
||||
use biome_parser::token_set;
|
||||
|
||||
use crate::parser::CssParser;
|
||||
use crate::syntax::at_rule::container::error::expected_any_container_style_query;
|
||||
|
|
@ -25,6 +28,10 @@ use crate::syntax::parse_declaration;
|
|||
use crate::syntax::property::GenericComponentValueList;
|
||||
use crate::syntax::value::parse_error::expected_if_branch;
|
||||
use crate::syntax::value::parse_error::expected_if_test_boolean_expr_group;
|
||||
use crate::syntax::value::parse_error::expected_if_test_boolean_not_expr;
|
||||
|
||||
const IF_BRANCH_RECOVERY_TOKEN_SET: TokenSet<CssSyntaxKind> =
|
||||
token_set![T![;], T![')'], T!['}'], EOF];
|
||||
|
||||
pub(crate) fn is_at_if_function(p: &mut CssParser) -> bool {
|
||||
p.at(T![if])
|
||||
|
|
@ -217,6 +224,11 @@ fn parse_if_media_test(p: &mut CssParser) -> ParsedSyntax {
|
|||
Present(m.complete(p, CSS_IF_MEDIA_TEST))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_at_if_test(p: &mut CssParser) -> bool {
|
||||
is_at_if_supports_test(p) || is_at_if_style_test(p) || is_at_if_media_test(p)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn parse_if_test(p: &mut CssParser) -> ParsedSyntax {
|
||||
if is_at_if_supports_test(p) {
|
||||
|
|
@ -234,13 +246,26 @@ fn parse_if_test(p: &mut CssParser) -> ParsedSyntax {
|
|||
Absent
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_at_if_test_boolean_expr_group(p: &mut CssParser) -> bool {
|
||||
p.at(T!['(']) || is_at_if_test(p)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn parse_any_if_test_boolean_expr_group(p: &mut CssParser) -> ParsedSyntax {
|
||||
// ( <boolean-expr> )
|
||||
if p.at(T!['(']) {
|
||||
let m = p.start();
|
||||
p.bump(T!['(']);
|
||||
parse_any_if_test_boolean_expr(p).ok();
|
||||
|
||||
parse_any_if_test_boolean_expr(p)
|
||||
.or_recover_with_token_set(
|
||||
p,
|
||||
&ParseRecoveryTokenSet::new(CSS_BOGUS_IF_TEST_BOOLEAN_EXPR, token_set![T![')']]),
|
||||
expected_if_test_boolean_not_expr,
|
||||
)
|
||||
.ok();
|
||||
|
||||
p.expect(T![')']);
|
||||
return Present(m.complete(p, CSS_IF_TEST_BOOLEAN_EXPR_IN_PARENS));
|
||||
}
|
||||
|
|
@ -269,7 +294,14 @@ fn parse_if_test_boolean_not_expr(p: &mut CssParser) -> ParsedSyntax {
|
|||
let m = p.start();
|
||||
|
||||
p.bump(T![not]);
|
||||
parse_any_if_test_boolean_expr_group(p).ok();
|
||||
|
||||
parse_any_if_test_boolean_expr_group(p)
|
||||
.or_recover_with_token_set(
|
||||
p,
|
||||
&ParseRecoveryTokenSet::new(CSS_BOGUS_IF_TEST_BOOLEAN_EXPR, token_set![T![')'], T![:]]),
|
||||
expected_if_test_boolean_expr_group,
|
||||
)
|
||||
.ok();
|
||||
|
||||
Present(m.complete(p, CSS_IF_TEST_BOOLEAN_NOT_EXPR))
|
||||
}
|
||||
|
|
@ -371,6 +403,11 @@ fn parse_any_if_test_boolean_expr(p: &mut CssParser) -> ParsedSyntax {
|
|||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_at_any_if_condition(p: &mut CssParser) -> bool {
|
||||
p.at(T![else]) || is_at_if_test_boolean_expr_group(p) || is_at_if_test_boolean_not_expr(p)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn parse_any_if_condition(p: &mut CssParser) -> ParsedSyntax {
|
||||
if p.at(T![else]) {
|
||||
|
|
@ -384,10 +421,37 @@ fn parse_any_if_condition(p: &mut CssParser) -> ParsedSyntax {
|
|||
|
||||
#[inline]
|
||||
fn parse_if_branch(p: &mut CssParser) -> ParsedSyntax {
|
||||
// The DeclarationOrRuleList parser that this function call will be parsed in higher up
|
||||
// the node tree uses speculative parsing and the semicolon character to determine when
|
||||
// parsing is complete or when to recover from a parsing error. This comes in conflict with
|
||||
// error recovery parsing for if branches since this parser also uses the semicolon as a recovery
|
||||
// point. To get around this, we handle our own manual recovery here by consuming all unexpected
|
||||
// tokens into the CssBogusIfBranch node until we are able to recover.
|
||||
if !is_at_any_if_condition(p) {
|
||||
if !p.at_ts(IF_BRANCH_RECOVERY_TOKEN_SET) {
|
||||
let m = p.start();
|
||||
|
||||
while !p.at_ts(IF_BRANCH_RECOVERY_TOKEN_SET) {
|
||||
p.bump_any();
|
||||
}
|
||||
|
||||
let bogus = m.complete(p, CSS_BOGUS_IF_BRANCH);
|
||||
p.error(expected_if_branch(p, bogus.range(p)));
|
||||
|
||||
return Present(bogus);
|
||||
}
|
||||
|
||||
return Absent;
|
||||
}
|
||||
|
||||
let m = p.start();
|
||||
|
||||
parse_any_if_condition(p)
|
||||
.or_recover(p, &AnyIfTestParseRecovery, expected_if_branch)
|
||||
.or_recover_with_token_set(
|
||||
p,
|
||||
&ParseRecoveryTokenSet::new(CSS_BOGUS_IF_BRANCH, token_set![T![')'], T![:]]),
|
||||
expected_if_branch,
|
||||
)
|
||||
.ok();
|
||||
|
||||
p.expect(T![:]);
|
||||
|
|
@ -402,28 +466,17 @@ struct AnyIfTestBooleanExprChainParseRecovery;
|
|||
impl ParseRecovery for AnyIfTestBooleanExprChainParseRecovery {
|
||||
type Kind = CssSyntaxKind;
|
||||
type Parser<'source> = CssParser<'source>;
|
||||
const RECOVERED_KIND: Self::Kind = CSS_BOGUS;
|
||||
const RECOVERED_KIND: Self::Kind = CSS_BOGUS_IF_TEST_BOOLEAN_EXPR;
|
||||
|
||||
fn is_at_recovered(&self, p: &mut Self::Parser<'_>) -> bool {
|
||||
is_at_if_test_boolean_not_expr(p)
|
||||
p.at(T![')'])
|
||||
|| is_at_if_test_boolean_not_expr(p)
|
||||
|| is_at_if_test_boolean_and_expr(p)
|
||||
|| is_at_if_test_boolean_or_expr(p)
|
||||
|| p.has_preceding_line_break()
|
||||
}
|
||||
}
|
||||
|
||||
struct AnyIfTestParseRecovery;
|
||||
|
||||
impl ParseRecovery for AnyIfTestParseRecovery {
|
||||
type Kind = CssSyntaxKind;
|
||||
type Parser<'source> = CssParser<'source>;
|
||||
const RECOVERED_KIND: Self::Kind = CSS_BOGUS_IF_TEST;
|
||||
|
||||
fn is_at_recovered(&self, p: &mut Self::Parser<'_>) -> bool {
|
||||
p.at(T![')']) || p.has_preceding_line_break()
|
||||
}
|
||||
}
|
||||
|
||||
struct IfBranchListParseRecovery;
|
||||
|
||||
impl ParseRecovery for IfBranchListParseRecovery {
|
||||
|
|
@ -433,7 +486,7 @@ impl ParseRecovery for IfBranchListParseRecovery {
|
|||
const RECOVERED_KIND: Self::Kind = CSS_BOGUS_IF_BRANCH;
|
||||
|
||||
fn is_at_recovered(&self, p: &mut Self::Parser<'_>) -> bool {
|
||||
p.at(T![;]) || p.at(T![')']) || p.has_preceding_line_break()
|
||||
p.at_ts(IF_BRANCH_RECOVERY_TOKEN_SET)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,3 +30,10 @@ pub(crate) fn expected_if_test_boolean_expr_group(
|
|||
) -> ParseDiagnostic {
|
||||
expected_any(&["parenthesized boolean expression", "if test"], range, p)
|
||||
}
|
||||
|
||||
pub(crate) fn expected_if_test_boolean_not_expr(
|
||||
p: &CssParser,
|
||||
range: TextRange,
|
||||
) -> ParseDiagnostic {
|
||||
expected_any(&["not boolean expression", "if test"], range, p)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,3 +81,15 @@
|
|||
.empty-if {
|
||||
color: if();
|
||||
}
|
||||
|
||||
.if-branch-list-recovery {
|
||||
a: if(style(--foo: bar): black; !bogus; else: white);
|
||||
a: if(style(--foo: bar): black; ???; else: white);
|
||||
}
|
||||
|
||||
.todo {
|
||||
background: if(style(--foo: bar) and (!bogus): red;);
|
||||
background: if(not foo: red;);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
1
crates/biome_css_syntax/src/generated/kind.rs
generated
1
crates/biome_css_syntax/src/generated/kind.rs
generated
|
|
@ -544,6 +544,7 @@ pub enum CssSyntaxKind {
|
|||
CSS_BOGUS_SUPPORTS_CONDITION,
|
||||
CSS_BOGUS_IF_BRANCH,
|
||||
CSS_BOGUS_IF_TEST,
|
||||
CSS_BOGUS_IF_TEST_BOOLEAN_EXPR,
|
||||
CSS_METAVARIABLE,
|
||||
#[doc(hidden)]
|
||||
__LAST,
|
||||
|
|
|
|||
5
crates/biome_css_syntax/src/generated/macros.rs
generated
5
crates/biome_css_syntax/src/generated/macros.rs
generated
|
|
@ -919,6 +919,11 @@ macro_rules! map_syntax_node {
|
|||
let $pattern = unsafe { $crate::CssBogusIfTest::new_unchecked(node) };
|
||||
$body
|
||||
}
|
||||
$crate::CssSyntaxKind::CSS_BOGUS_IF_TEST_BOOLEAN_EXPR => {
|
||||
let $pattern =
|
||||
unsafe { $crate::CssBogusIfTestBooleanExpr::new_unchecked(node) };
|
||||
$body
|
||||
}
|
||||
$crate::CssSyntaxKind::CSS_BOGUS_KEYFRAMES_ITEM => {
|
||||
let $pattern = unsafe { $crate::CssBogusKeyframesItem::new_unchecked(node) };
|
||||
$body
|
||||
|
|
|
|||
80
crates/biome_css_syntax/src/generated/nodes.rs
generated
80
crates/biome_css_syntax/src/generated/nodes.rs
generated
|
|
@ -9620,6 +9620,7 @@ impl AnyCssIfTestBooleanAndCombinableExpr {
|
|||
pub enum AnyCssIfTestBooleanExpr {
|
||||
AnyCssIfTestBooleanAndCombinableExpr(AnyCssIfTestBooleanAndCombinableExpr),
|
||||
AnyCssIfTestBooleanOrCombinableExpr(AnyCssIfTestBooleanOrCombinableExpr),
|
||||
CssBogusIfTestBooleanExpr(CssBogusIfTestBooleanExpr),
|
||||
CssIfTestBooleanNotExpr(CssIfTestBooleanNotExpr),
|
||||
}
|
||||
impl AnyCssIfTestBooleanExpr {
|
||||
|
|
@ -9639,6 +9640,12 @@ impl AnyCssIfTestBooleanExpr {
|
|||
_ => None,
|
||||
}
|
||||
}
|
||||
pub fn as_css_bogus_if_test_boolean_expr(&self) -> Option<&CssBogusIfTestBooleanExpr> {
|
||||
match &self {
|
||||
Self::CssBogusIfTestBooleanExpr(item) => Some(item),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
pub fn as_css_if_test_boolean_not_expr(&self) -> Option<&CssIfTestBooleanNotExpr> {
|
||||
match &self {
|
||||
Self::CssIfTestBooleanNotExpr(item) => Some(item),
|
||||
|
|
@ -24506,6 +24513,11 @@ impl From<AnyCssIfTestBooleanAndCombinableExpr> for SyntaxElement {
|
|||
node.into()
|
||||
}
|
||||
}
|
||||
impl From<CssBogusIfTestBooleanExpr> for AnyCssIfTestBooleanExpr {
|
||||
fn from(node: CssBogusIfTestBooleanExpr) -> Self {
|
||||
Self::CssBogusIfTestBooleanExpr(node)
|
||||
}
|
||||
}
|
||||
impl From<CssIfTestBooleanNotExpr> for AnyCssIfTestBooleanExpr {
|
||||
fn from(node: CssIfTestBooleanNotExpr) -> Self {
|
||||
Self::CssIfTestBooleanNotExpr(node)
|
||||
|
|
@ -24515,10 +24527,11 @@ impl AstNode for AnyCssIfTestBooleanExpr {
|
|||
type Language = Language;
|
||||
const KIND_SET: SyntaxKindSet<Language> = AnyCssIfTestBooleanAndCombinableExpr::KIND_SET
|
||||
.union(AnyCssIfTestBooleanOrCombinableExpr::KIND_SET)
|
||||
.union(CssBogusIfTestBooleanExpr::KIND_SET)
|
||||
.union(CssIfTestBooleanNotExpr::KIND_SET);
|
||||
fn can_cast(kind: SyntaxKind) -> bool {
|
||||
match kind {
|
||||
CSS_IF_TEST_BOOLEAN_NOT_EXPR => true,
|
||||
CSS_BOGUS_IF_TEST_BOOLEAN_EXPR | CSS_IF_TEST_BOOLEAN_NOT_EXPR => true,
|
||||
k if AnyCssIfTestBooleanAndCombinableExpr::can_cast(k) => true,
|
||||
k if AnyCssIfTestBooleanOrCombinableExpr::can_cast(k) => true,
|
||||
_ => false,
|
||||
|
|
@ -24526,6 +24539,9 @@ impl AstNode for AnyCssIfTestBooleanExpr {
|
|||
}
|
||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||
let res = match syntax.kind() {
|
||||
CSS_BOGUS_IF_TEST_BOOLEAN_EXPR => {
|
||||
Self::CssBogusIfTestBooleanExpr(CssBogusIfTestBooleanExpr { syntax })
|
||||
}
|
||||
CSS_IF_TEST_BOOLEAN_NOT_EXPR => {
|
||||
Self::CssIfTestBooleanNotExpr(CssIfTestBooleanNotExpr { syntax })
|
||||
}
|
||||
|
|
@ -24552,6 +24568,7 @@ impl AstNode for AnyCssIfTestBooleanExpr {
|
|||
}
|
||||
fn syntax(&self) -> &SyntaxNode {
|
||||
match self {
|
||||
Self::CssBogusIfTestBooleanExpr(it) => it.syntax(),
|
||||
Self::CssIfTestBooleanNotExpr(it) => it.syntax(),
|
||||
Self::AnyCssIfTestBooleanAndCombinableExpr(it) => it.syntax(),
|
||||
Self::AnyCssIfTestBooleanOrCombinableExpr(it) => it.syntax(),
|
||||
|
|
@ -24559,6 +24576,7 @@ impl AstNode for AnyCssIfTestBooleanExpr {
|
|||
}
|
||||
fn into_syntax(self) -> SyntaxNode {
|
||||
match self {
|
||||
Self::CssBogusIfTestBooleanExpr(it) => it.into_syntax(),
|
||||
Self::CssIfTestBooleanNotExpr(it) => it.into_syntax(),
|
||||
Self::AnyCssIfTestBooleanAndCombinableExpr(it) => it.into_syntax(),
|
||||
Self::AnyCssIfTestBooleanOrCombinableExpr(it) => it.into_syntax(),
|
||||
|
|
@ -24570,6 +24588,7 @@ impl std::fmt::Debug for AnyCssIfTestBooleanExpr {
|
|||
match self {
|
||||
Self::AnyCssIfTestBooleanAndCombinableExpr(it) => std::fmt::Debug::fmt(it, f),
|
||||
Self::AnyCssIfTestBooleanOrCombinableExpr(it) => std::fmt::Debug::fmt(it, f),
|
||||
Self::CssBogusIfTestBooleanExpr(it) => std::fmt::Debug::fmt(it, f),
|
||||
Self::CssIfTestBooleanNotExpr(it) => std::fmt::Debug::fmt(it, f),
|
||||
}
|
||||
}
|
||||
|
|
@ -24579,6 +24598,7 @@ impl From<AnyCssIfTestBooleanExpr> for SyntaxNode {
|
|||
match n {
|
||||
AnyCssIfTestBooleanExpr::AnyCssIfTestBooleanAndCombinableExpr(it) => it.into_syntax(),
|
||||
AnyCssIfTestBooleanExpr::AnyCssIfTestBooleanOrCombinableExpr(it) => it.into_syntax(),
|
||||
AnyCssIfTestBooleanExpr::CssBogusIfTestBooleanExpr(it) => it.into_syntax(),
|
||||
AnyCssIfTestBooleanExpr::CssIfTestBooleanNotExpr(it) => it.into_syntax(),
|
||||
}
|
||||
}
|
||||
|
|
@ -30936,6 +30956,62 @@ impl From<CssBogusIfTest> for SyntaxElement {
|
|||
}
|
||||
}
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Serialize)]
|
||||
pub struct CssBogusIfTestBooleanExpr {
|
||||
syntax: SyntaxNode,
|
||||
}
|
||||
impl CssBogusIfTestBooleanExpr {
|
||||
#[doc = r" Create an AstNode from a SyntaxNode without checking its kind"]
|
||||
#[doc = r""]
|
||||
#[doc = r" # Safety"]
|
||||
#[doc = r" This function must be guarded with a call to [AstNode::can_cast]"]
|
||||
#[doc = r" or a match on [SyntaxNode::kind]"]
|
||||
#[inline]
|
||||
pub const unsafe fn new_unchecked(syntax: SyntaxNode) -> Self {
|
||||
Self { syntax }
|
||||
}
|
||||
pub fn items(&self) -> SyntaxElementChildren {
|
||||
support::elements(&self.syntax)
|
||||
}
|
||||
}
|
||||
impl AstNode for CssBogusIfTestBooleanExpr {
|
||||
type Language = Language;
|
||||
const KIND_SET: SyntaxKindSet<Language> =
|
||||
SyntaxKindSet::from_raw(RawSyntaxKind(CSS_BOGUS_IF_TEST_BOOLEAN_EXPR as u16));
|
||||
fn can_cast(kind: SyntaxKind) -> bool {
|
||||
kind == CSS_BOGUS_IF_TEST_BOOLEAN_EXPR
|
||||
}
|
||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||
if Self::can_cast(syntax.kind()) {
|
||||
Some(Self { syntax })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn syntax(&self) -> &SyntaxNode {
|
||||
&self.syntax
|
||||
}
|
||||
fn into_syntax(self) -> SyntaxNode {
|
||||
self.syntax
|
||||
}
|
||||
}
|
||||
impl std::fmt::Debug for CssBogusIfTestBooleanExpr {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("CssBogusIfTestBooleanExpr")
|
||||
.field("items", &DebugSyntaxElementChildren(self.items()))
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
impl From<CssBogusIfTestBooleanExpr> for SyntaxNode {
|
||||
fn from(n: CssBogusIfTestBooleanExpr) -> Self {
|
||||
n.syntax
|
||||
}
|
||||
}
|
||||
impl From<CssBogusIfTestBooleanExpr> for SyntaxElement {
|
||||
fn from(n: CssBogusIfTestBooleanExpr) -> Self {
|
||||
n.syntax.into()
|
||||
}
|
||||
}
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Serialize)]
|
||||
pub struct CssBogusKeyframesItem {
|
||||
syntax: SyntaxNode,
|
||||
}
|
||||
|
|
@ -31999,7 +32075,7 @@ impl From<CssValueAtRuleGenericValue> for SyntaxElement {
|
|||
n.syntax.into()
|
||||
}
|
||||
}
|
||||
biome_rowan::declare_node_union! { pub AnyCssBogusNode = CssBogus | CssBogusAtRule | CssBogusBlock | CssBogusCustomIdentifier | CssBogusDeclarationItem | CssBogusDocumentMatcher | CssBogusFontFamilyName | CssBogusFontFeatureValuesItem | CssBogusIfBranch | CssBogusIfTest | CssBogusKeyframesItem | CssBogusKeyframesName | CssBogusLayer | CssBogusMediaQuery | CssBogusPageSelectorPseudo | CssBogusParameter | CssBogusProperty | CssBogusPropertyValue | CssBogusPseudoClass | CssBogusPseudoElement | CssBogusRule | CssBogusScopeRange | CssBogusSelector | CssBogusSubSelector | CssBogusSupportsCondition | CssBogusUnicodeRangeValue | CssBogusUrlModifier | CssUnknownAtRuleComponentList | CssValueAtRuleGenericValue }
|
||||
biome_rowan::declare_node_union! { pub AnyCssBogusNode = CssBogus | CssBogusAtRule | CssBogusBlock | CssBogusCustomIdentifier | CssBogusDeclarationItem | CssBogusDocumentMatcher | CssBogusFontFamilyName | CssBogusFontFeatureValuesItem | CssBogusIfBranch | CssBogusIfTest | CssBogusIfTestBooleanExpr | CssBogusKeyframesItem | CssBogusKeyframesName | CssBogusLayer | CssBogusMediaQuery | CssBogusPageSelectorPseudo | CssBogusParameter | CssBogusProperty | CssBogusPropertyValue | CssBogusPseudoClass | CssBogusPseudoElement | CssBogusRule | CssBogusScopeRange | CssBogusSelector | CssBogusSubSelector | CssBogusSupportsCondition | CssBogusUnicodeRangeValue | CssBogusUrlModifier | CssUnknownAtRuleComponentList | CssValueAtRuleGenericValue }
|
||||
#[derive(Clone, Eq, PartialEq, Hash)]
|
||||
pub struct CssBracketedValueList {
|
||||
syntax_list: SyntaxList,
|
||||
|
|
|
|||
|
|
@ -131,6 +131,9 @@ impl biome_rowan::SyntaxKind for CssSyntaxKind {
|
|||
kind if AnyCssFontFeatureValuesBlock::can_cast(*kind) => CSS_BOGUS_BLOCK,
|
||||
kind if AnyCssUnicodeValue::can_cast(*kind) => CSS_BOGUS_UNICODE_RANGE_VALUE,
|
||||
kind if AnyCssSupportsCondition::can_cast(*kind) => CSS_BOGUS_SUPPORTS_CONDITION,
|
||||
kind if AnyCssIfBranch::can_cast(*kind) => CSS_BOGUS_IF_BRANCH,
|
||||
kind if AnyCssIfTest::can_cast(*kind) => CSS_BOGUS_IF_TEST,
|
||||
kind if AnyCssIfTestBooleanExpr::can_cast(*kind) => CSS_BOGUS_IF_TEST_BOOLEAN_EXPR,
|
||||
|
||||
_ => CSS_BOGUS,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ CssBogusUnicodeRangeValue = SyntaxElement*
|
|||
CssBogusSupportsCondition = SyntaxElement*
|
||||
CssBogusIfBranch = SyntaxElement*
|
||||
CssBogusIfTest = SyntaxElement*
|
||||
CssBogusIfTestBooleanExpr = SyntaxElement*
|
||||
|
||||
CssRoot =
|
||||
bom: 'UNICODE_BOM'?
|
||||
|
|
@ -1859,12 +1860,16 @@ CssParameter = AnyCssExpression
|
|||
// supports( [ <ident> : <declaration-value> ] | <supports-condition> ) |
|
||||
// media( <media-feature> | <media-condition> ) |
|
||||
// style( <style-query> )
|
||||
//
|
||||
// if(style(--color: green)): red);
|
||||
CssIfFunction =
|
||||
'if'
|
||||
'('
|
||||
CssIfBranchList
|
||||
')'
|
||||
|
||||
// if(style(--theme: dark): red; else: blue)
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
CssIfBranchList = AnyCssIfBranch (';' AnyCssIfBranch)* ';'?
|
||||
|
||||
// https://drafts.csswg.org/css-values-5/#typedef-boolean-expr
|
||||
|
|
@ -1876,8 +1881,12 @@ AnyCssIfTestBooleanExpr =
|
|||
CssIfTestBooleanNotExpr
|
||||
| AnyCssIfTestBooleanAndCombinableExpr
|
||||
| AnyCssIfTestBooleanOrCombinableExpr
|
||||
| CssBogusIfTestBooleanExpr
|
||||
|
||||
// not <boolean-expr-group>
|
||||
//
|
||||
// if(not style(--color: green): red)
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
CssIfTestBooleanNotExpr =
|
||||
'not'
|
||||
expression: AnyCssIfTestBooleanExprGroup
|
||||
|
|
@ -1886,6 +1895,8 @@ AnyCssIfTestBooleanAndCombinableExpr =
|
|||
AnyCssIfTestBooleanExprGroup
|
||||
| CssIfTestBooleanAndExpr
|
||||
|
||||
// if(style(--color: green) and style(--color: blue)): red)
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
CssIfTestBooleanAndExpr =
|
||||
left: AnyCssIfTestBooleanExprGroup
|
||||
'and'
|
||||
|
|
@ -1895,6 +1906,8 @@ AnyCssIfTestBooleanOrCombinableExpr =
|
|||
AnyCssIfTestBooleanExprGroup
|
||||
| CssIfTestBooleanOrExpr
|
||||
|
||||
// if(style(--color: green) or style(--color: blue)): red)
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
CssIfTestBooleanOrExpr =
|
||||
left: AnyCssIfTestBooleanExprGroup
|
||||
'or'
|
||||
|
|
@ -1906,15 +1919,22 @@ AnyCssIfTestBooleanExprGroup =
|
|||
| CssIfTestBooleanExprInParens
|
||||
|
||||
// ( <boolean-expr> )
|
||||
//
|
||||
// if(style(--foo: bar) and (style(--fiz: buzz) or style(--baz: qux)): red)
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
CssIfTestBooleanExprInParens =
|
||||
'('
|
||||
expression: AnyCssIfTestBooleanExpr
|
||||
')'
|
||||
|
||||
// if(media(width < 700px): 0 auto; else: 20px auto;);
|
||||
// ^^^^
|
||||
CssElseKeyword = 'else'
|
||||
|
||||
AnyCssIfCondition = AnyCssIfTestBooleanExpr | CssElseKeyword
|
||||
|
||||
// if(style(--color: green): red; else: blue)
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^
|
||||
CssIfBranch =
|
||||
condition: AnyCssIfCondition
|
||||
':'
|
||||
|
|
@ -1924,6 +1944,8 @@ AnyCssIfBranch =
|
|||
CssIfBranch
|
||||
| CssBogusIfBranch
|
||||
|
||||
// supports(color: lch(75% 0 0)): lch(75% 0 0)
|
||||
// ^^^^^^^^^^^^^^^^^^^
|
||||
CssIfSupportsIdentifierTest =
|
||||
ident: CssIdentifier
|
||||
':'
|
||||
|
|
@ -1933,6 +1955,8 @@ AnyCssIfSupportsTestCondition =
|
|||
CssIfSupportsIdentifierTest
|
||||
| AnyCssImportSupportsCondition
|
||||
|
||||
// if(supports(selector(:buffering)): 1em;)
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
CssIfSupportsTest =
|
||||
'supports'
|
||||
'('
|
||||
|
|
@ -1943,6 +1967,8 @@ AnyCssIfMediaTestQuery =
|
|||
AnyCssMediaCondition
|
||||
| AnyCssQueryFeature
|
||||
|
||||
// if(media(width > 700px): calc(3rem + 2vw))
|
||||
// ^^^^^^^^^^^^^^^^^^^^
|
||||
CssIfMediaTest =
|
||||
'media'
|
||||
'('
|
||||
|
|
|
|||
|
|
@ -577,6 +577,7 @@ pub const CSS_KINDS_SRC: KindsSrc = KindsSrc {
|
|||
"CSS_BOGUS_SUPPORTS_CONDITION",
|
||||
"CSS_BOGUS_IF_BRANCH",
|
||||
"CSS_BOGUS_IF_TEST",
|
||||
"CSS_BOGUS_IF_TEST_BOOLEAN_EXPR",
|
||||
// Grit metavariable
|
||||
"CSS_METAVARIABLE",
|
||||
],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue