pub mod ast_utils;
pub mod diagnostics;
pub mod parsing;
pub mod pretty;
pub mod types;
pub use ast_utils::compute_expression_end_pub;
pub use diagnostics::analyze;
pub use types::*;
use bbnf::types::AST;
use crate::analysis::LineIndex;
use diagnostics::analyze_from_cache;
use parsing::{OwnedAst, parse_once};
pub struct DocumentState {
pub text: String,
pub info: DocumentInfo,
pub line_index: LineIndex,
ast_cell: OwnedAst,
}
impl DocumentState {
pub fn new(text: String) -> Self {
let line_index = LineIndex::new(&text);
let parse_diag = std::cell::Cell::new(None::<ParseDiagnostics>);
let ast_cell = OwnedAst::new(text.clone(), |src| {
let (cached, diag) = parse_once(src);
parse_diag.set(Some(diag));
cached
});
let diag = parse_diag.into_inner().unwrap();
let info = analyze_from_cache(
&text,
&line_index,
ast_cell.borrow_dependent().as_ref(),
&diag,
);
Self {
text,
info,
line_index,
ast_cell,
}
}
pub fn update(&mut self, text: String) {
if *self.ast_cell.borrow_owner() == text {
return;
}
let line_index = LineIndex::new(&text);
let parse_diag = std::cell::Cell::new(None::<ParseDiagnostics>);
let ast_cell = OwnedAst::new(text.clone(), |src| {
let (cached, diag) = parse_once(src);
parse_diag.set(Some(diag));
cached
});
let diag = parse_diag.into_inner().unwrap();
self.info = analyze_from_cache(
&text,
&line_index,
ast_cell.borrow_dependent().as_ref(),
&diag,
);
self.line_index = line_index;
self.ast_cell = ast_cell;
self.text = text;
}
pub fn ast(&self) -> Option<&AST<'_>> {
self.ast_cell.borrow_dependent().as_ref().map(|c| &c.ast)
}
}