Skip to main content

oxc_css_parser/parser/
builder.rs

1use super::Parser;
2use crate::{
3    ParserOptions, Syntax,
4    tokenizer::{Tokenizer, token::Comment},
5};
6
7/// Parser builder is for building a parser while allowing us
8/// to control advanced behaviors.
9///
10/// Unlike [`Parser`], syntax isn't required when creating a parser builder,
11/// and the default syntax will be CSS. If you need to parse with another syntax,
12/// use the [`syntax`](ParserBuilder::syntax) to modify it.
13pub struct ParserBuilder<'cmt, 's: 'cmt> {
14    source: &'s str,
15    syntax: Syntax,
16    options: Option<ParserOptions>,
17    comments: Option<&'cmt mut Vec<Comment<'s>>>,
18}
19
20impl<'cmt, 's: 'cmt> ParserBuilder<'cmt, 's> {
21    /// Create a parser builder from given source code.
22    pub fn new(source: &'s str) -> Self {
23        let source = source.strip_prefix('\u{feff}').unwrap_or(source);
24        ParserBuilder {
25            source,
26            options: None,
27            syntax: Syntax::default(),
28            comments: None,
29        }
30    }
31
32    /// Specify the syntax for parsing.
33    pub fn syntax(mut self, syntax: Syntax) -> Self {
34        self.syntax = syntax;
35        self
36    }
37
38    /// Customize parser options.
39    pub fn options(mut self, options: ParserOptions) -> Self {
40        self.options = Some(options);
41        self
42    }
43
44    /// Collect comments and put them into the given collection.
45    pub fn comments(mut self, comments: &'cmt mut Vec<Comment<'s>>) -> Self {
46        self.comments = Some(comments);
47        self
48    }
49
50    /// Disable collecting comments.
51    ///
52    /// Collecting comments is disabled by default,
53    /// so you don't need to use this if you never call the [`comments`](ParserBuilder::comments) method.
54    pub fn ignore_comments(mut self) -> Self {
55        self.comments = None;
56        self
57    }
58
59    /// Build a parser.
60    pub fn build(self) -> Parser<'cmt, 's> {
61        let options = self.options.unwrap_or_default();
62        // Backtick is not valid CSS/SCSS/Sass; the placeholder lexer path only
63        // makes sense for SCSS (in Less, backtick is the inline-JS delimiter).
64        debug_assert!(
65            options.template_placeholder.is_none() || self.syntax == Syntax::Scss,
66            "template_placeholder requires Syntax::Scss (backtick is Less's inline-JS delimiter)",
67        );
68        Parser {
69            source: self.source,
70            syntax: self.syntax,
71            options,
72            tokenizer: Tokenizer::new(
73                self.source,
74                self.syntax,
75                options.template_placeholder,
76                self.comments,
77            ),
78            state: Default::default(),
79            recoverable_errors: vec![],
80            cached_token: None,
81        }
82    }
83}