diff options
Diffstat (limited to 'support/texlab/crates/diagnostics/src/manager.rs')
-rw-r--r-- | support/texlab/crates/diagnostics/src/manager.rs | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/support/texlab/crates/diagnostics/src/manager.rs b/support/texlab/crates/diagnostics/src/manager.rs new file mode 100644 index 0000000000..1ce5e194b8 --- /dev/null +++ b/support/texlab/crates/diagnostics/src/manager.rs @@ -0,0 +1,75 @@ +use base_db::{util::filter_regex_patterns, Document, Owner, Workspace}; +use multimap::MultiMap; +use rustc_hash::FxHashMap; +use url::Url; + +use crate::types::Diagnostic; + +/// Manages all diagnostics for a workspace. +#[derive(Debug, Default)] +pub struct Manager { + grammar: MultiMap<Url, Diagnostic>, + chktex: FxHashMap<Url, Vec<Diagnostic>>, + build_log: FxHashMap<Url, MultiMap<Url, Diagnostic>>, +} + +impl Manager { + /// Updates the syntax-based diagnostics for the given document. + pub fn update_syntax(&mut self, workspace: &Workspace, document: &Document) { + self.grammar.remove(&document.uri); + super::grammar::tex::update(document, workspace.config(), &mut self.grammar); + super::grammar::bib::update(document, &mut self.grammar); + + self.build_log.remove(&document.uri); + super::build_log::update(workspace, document, &mut self.build_log); + } + + /// Updates the ChkTeX diagnostics for the given document. + pub fn update_chktex(&mut self, uri: Url, diagnostics: Vec<Diagnostic>) { + self.chktex.insert(uri, diagnostics); + } + + /// Returns all filtered diagnostics for the given workspace. + pub fn get(&self, workspace: &Workspace) -> MultiMap<Url, Diagnostic> { + let mut results = MultiMap::default(); + for (uri, diagnostics) in &self.grammar { + results.insert_many_from_slice(uri.clone(), diagnostics); + } + + for (uri, diagnostics) in self.build_log.values().flatten() { + results.insert_many_from_slice(uri.clone(), diagnostics); + } + + for (uri, diagnostics) in &self.chktex { + if workspace + .lookup(uri) + .map_or(false, |document| document.owner == Owner::Client) + { + results.insert_many_from_slice(uri.clone(), diagnostics); + } + } + + for document in workspace.iter() { + let project = workspace.project(document); + super::citations::detect_undefined_citations(&project, document, &mut results); + super::citations::detect_unused_entries(&project, document, &mut results); + } + + super::citations::detect_duplicate_entries(workspace, &mut results); + super::labels::detect_duplicate_labels(workspace, &mut results); + super::labels::detect_undefined_and_unused_labels(workspace, &mut results); + + let config = &workspace.config().diagnostics; + for (_, diagnostics) in &mut results { + diagnostics.retain(|diagnostic| { + filter_regex_patterns( + &diagnostic.message(), + &config.allowed_patterns, + &config.ignored_patterns, + ) + }); + } + + results + } +} |