bbnf_analysis/state/
mod.rs1pub mod ast_utils;
2pub mod diagnostics;
3pub mod parsing;
4pub mod pretty;
5pub mod types;
6
7pub use ast_utils::compute_expression_end_pub;
8pub use diagnostics::analyze;
9pub use types::*;
10
11use bbnf::types::AST;
12
13use crate::analysis::LineIndex;
14
15use diagnostics::analyze_from_cache;
16use parsing::{OwnedAst, parse_once};
17
18pub struct DocumentState {
20 pub text: String,
21 pub info: DocumentInfo,
22 pub line_index: LineIndex,
24 ast_cell: OwnedAst,
26}
27
28impl DocumentState {
29 pub fn new(text: String) -> Self {
30 let line_index = LineIndex::new(&text);
31 let parse_diag = std::cell::Cell::new(None::<ParseDiagnostics>);
34 let ast_cell = OwnedAst::new(text.clone(), |src| {
35 let (cached, diag) = parse_once(src);
36 parse_diag.set(Some(diag));
37 cached
38 });
39 let diag = parse_diag.into_inner().unwrap();
40
41 let info = analyze_from_cache(
42 &text,
43 &line_index,
44 ast_cell.borrow_dependent().as_ref(),
45 &diag,
46 );
47 Self {
48 text,
49 info,
50 line_index,
51 ast_cell,
52 }
53 }
54
55 pub fn update(&mut self, text: String) {
56 if *self.ast_cell.borrow_owner() == text {
61 return;
62 }
63
64 let line_index = LineIndex::new(&text);
65 let parse_diag = std::cell::Cell::new(None::<ParseDiagnostics>);
66 let ast_cell = OwnedAst::new(text.clone(), |src| {
67 let (cached, diag) = parse_once(src);
68 parse_diag.set(Some(diag));
69 cached
70 });
71 let diag = parse_diag.into_inner().unwrap();
72
73 self.info = analyze_from_cache(
74 &text,
75 &line_index,
76 ast_cell.borrow_dependent().as_ref(),
77 &diag,
78 );
79
80 self.line_index = line_index;
81 self.ast_cell = ast_cell;
82 self.text = text;
83 }
84
85 pub fn ast(&self) -> Option<&AST<'_>> {
87 self.ast_cell.borrow_dependent().as_ref().map(|c| &c.ast)
88 }
89}