oxc_css_parser/parser/at_rule/
layer.rs1use super::Parser;
2use crate::{
3 Parse,
4 ast::*,
5 error::{Error, PResult},
6 pos::Span,
7 tokenizer::{Token, TokenWithSpan},
8 util,
9};
10
11impl<'a> Parse<'a> for LayerNames<'a> {
16 fn parse(input: &mut Parser<'a>) -> PResult<Self> {
17 let first = input.parse::<LayerName>()?;
18 let mut span = first.span.clone();
19
20 let mut names = input.vec1(first);
21 let mut comma_spans = input.vec();
22 while let Some((_, comma_span)) = input.cursor.eat_comma()? {
23 comma_spans.push(comma_span);
24 names.push(input.parse()?);
25 }
26
27 if let Some(last) = names.last() {
28 span.end = last.span.end;
29 }
30 Ok(LayerNames { names, comma_spans, span })
31 }
32}
33
34impl<'a> Parse<'a> for LayerName<'a> {
38 fn parse(input: &mut Parser<'a>) -> PResult<Self> {
39 let first = input.parse::<InterpolableIdent>()?;
40 let start = first.span().start;
41 let mut end = first.span().end;
42
43 let mut idents = input.vec1(first);
44 while let TokenWithSpan { token: Token::Dot(..), span } = input.cursor.peek()? {
45 if span.start == end {
46 let span = input.cursor.bump()?.span;
47 let ident = input.parse::<InterpolableIdent>()?;
48 util::assert_no_ws_or_comment(&span, ident.span())?;
49 end = ident.span().end;
50 idents.push(ident);
51 } else {
52 break;
53 }
54 }
55
56 let invalid_ident = idents.iter().find(|ident| match &ident {
57 InterpolableIdent::Literal(ident) => util::is_css_wide_keyword(ident.name),
58 _ => false,
59 });
60 if let Some(invalid_ident) = invalid_ident {
61 input.recoverable_errors.push(Error {
62 kind: crate::error::ErrorKind::CSSWideKeywordDisallowed,
63 span: invalid_ident.span().clone(),
64 });
65 }
66
67 let span = Span { start, end };
68 Ok(LayerName { idents, span })
69 }
70}