esl_compiler/
context.rs

1use std::collections::BTreeMap;
2use std::rc::Rc;
3
4use crate::builder::file;
5use crate::builder::specification::Specification;
6use crate::cursor::Cursor;
7use crate::diagnostics::{DiagnosticError, DiagnosticWarning, Diagnostics};
8use crate::location::{FileLocation, Uri};
9use crate::parser::parse_file_text;
10
11/// Builder context.
12#[derive(Clone, Debug, Default, PartialEq)]
13pub struct Context {
14    /// In-progress specification.
15    pub specification: Specification,
16    /// Accumulated diagnostics per Uri.
17    pub diagnostics: BTreeMap<Uri, Diagnostics>,
18}
19impl Context {
20    /// Build a text document.
21    pub fn build_doc(&mut self, doc: &lsp_types::TextDocumentItem) {
22        let uri = doc.uri.to_owned().into();
23        let text = doc.text.as_str();
24        match parse_file_text(text) {
25            Ok(pairs) => {
26                for pair in pairs {
27                    self.build_file(Cursor::new(pair, Rc::clone(&uri)));
28                }
29            }
30            Err(e) => self.add_diagnostic(e.as_diagnostic(&uri), &uri),
31        };
32    }
33    /// Build the contents of a single file into this context. Infallible, but might report errors!
34    pub fn build_file(&mut self, file: Cursor) {
35        if let Err(e) = file::build_file(self, file) {
36            let diagnostic = e.as_diagnostic();
37            self.add_diagnostic(diagnostic, &e.as_location().uri);
38        }
39    }
40    /// Report a DiagnosticError at this location.
41    pub fn error(&mut self, error: DiagnosticError, loc: &FileLocation) {
42        self.add_diagnostic(error.diagnostic(loc.range, None), &loc.uri);
43    }
44    /// Report a DiagnosticWarning at this location.
45    pub fn warn(&mut self, warning: DiagnosticWarning, loc: &FileLocation) {
46        self.add_diagnostic(warning.diagnostic(loc.range, None), &loc.uri);
47    }
48    /// Add any diagnostic to its Uri entry.
49    pub fn add_diagnostic(&mut self, diagnostic: lsp_types::Diagnostic, uri: &Uri) {
50        self.diagnostics
51            .entry(Rc::clone(uri))
52            .or_insert(vec![])
53            .push(diagnostic);
54    }
55}