use crate::parser::CssParser;
use crate::syntax::parse_root;
use biome_css_factory::CssSyntaxFactory;
use biome_css_syntax::{CssLanguage, CssRoot, CssSyntaxNode};
pub use biome_parser::prelude::*;
use biome_parser::{tree_sink::LosslessTreeSink, AnyParse};
use biome_rowan::{AstNode, NodeCache};
pub use parser::CssParserOptions;
mod lexer;
mod parser;
mod prelude;
mod state;
mod syntax;
mod token_source;
pub(crate) type CssLosslessTreeSink<'source> =
LosslessTreeSink<'source, CssLanguage, CssSyntaxFactory>;
pub fn parse_css(source: &str, options: CssParserOptions) -> CssParse {
let mut cache = NodeCache::default();
parse_css_with_cache(source, &mut cache, options)
}
pub fn parse_css_with_cache(
source: &str,
cache: &mut NodeCache,
options: CssParserOptions,
) -> CssParse {
tracing::debug_span!("Parsing phase").in_scope(move || {
let mut parser = CssParser::new(source, options);
parse_root(&mut parser);
let (events, diagnostics, trivia) = parser.finish();
let mut tree_sink = CssLosslessTreeSink::with_cache(source, &trivia, cache);
biome_parser::event::process(&mut tree_sink, events, diagnostics);
let (green, diagnostics) = tree_sink.finish();
CssParse::new(green, diagnostics)
})
}
#[derive(Debug)]
pub struct CssParse {
root: CssSyntaxNode,
diagnostics: Vec<ParseDiagnostic>,
}
impl CssParse {
pub fn new(root: CssSyntaxNode, diagnostics: Vec<ParseDiagnostic>) -> CssParse {
CssParse { root, diagnostics }
}
pub fn syntax(&self) -> CssSyntaxNode {
self.root.clone()
}
pub fn diagnostics(&self) -> &[ParseDiagnostic] {
&self.diagnostics
}
pub fn into_diagnostics(self) -> Vec<ParseDiagnostic> {
self.diagnostics
}
pub fn has_errors(&self) -> bool {
self.diagnostics
.iter()
.any(|diagnostic| diagnostic.is_error())
}
pub fn tree(&self) -> CssRoot {
CssRoot::unwrap_cast(self.syntax())
}
}
impl From<CssParse> for AnyParse {
fn from(parse: CssParse) -> Self {
let root = parse.syntax();
let diagnostics = parse.into_diagnostics();
Self::new(
root.as_send().unwrap(),
diagnostics,
)
}
}
#[cfg(test)]
mod tests {
use crate::{parse_css, CssParserOptions};
#[test]
fn parser_smoke_test() {
let src = r#"
"#;
let _css = parse_css(src, CssParserOptions::default());
}
}