diff options
Diffstat (limited to 'support/texlab/crates/diagnostics/src/build_log.rs')
-rw-r--r-- | support/texlab/crates/diagnostics/src/build_log.rs | 104 |
1 files changed, 32 insertions, 72 deletions
diff --git a/support/texlab/crates/diagnostics/src/build_log.rs b/support/texlab/crates/diagnostics/src/build_log.rs index 4c53a35ff8..352e18d0d1 100644 --- a/support/texlab/crates/diagnostics/src/build_log.rs +++ b/support/texlab/crates/diagnostics/src/build_log.rs @@ -1,94 +1,54 @@ -use std::borrow::Cow; - use base_db::{Document, Workspace}; use line_index::LineCol; +use multimap::MultiMap; use rowan::{TextLen, TextRange, TextSize}; use rustc_hash::FxHashMap; use syntax::BuildError; use url::Url; -use crate::{ - types::{Diagnostic, DiagnosticData}, - DiagnosticBuilder, DiagnosticSource, -}; - -#[derive(Debug, Default)] -struct BuildLog { - errors: FxHashMap<Url, Vec<Diagnostic>>, -} +use crate::types::Diagnostic; -#[derive(Debug, Default)] -pub struct BuildErrors { - logs: FxHashMap<Url, BuildLog>, -} +pub fn update( + workspace: &Workspace, + log_document: &Document, + results: &mut FxHashMap<Url, MultiMap<Url, Diagnostic>>, +) -> Option<()> { + let mut errors = MultiMap::default(); -impl DiagnosticSource for BuildErrors { - fn update(&mut self, workspace: &Workspace, log_document: &Document) { - let mut errors: FxHashMap<Url, Vec<Diagnostic>> = FxHashMap::default(); + let data = log_document.data.as_log()?; - let Some(data) = log_document.data.as_log() else { - return; - }; + let parents = workspace.parents(log_document); + let root_document = parents.iter().next()?; - let parents = workspace.parents(log_document); - let Some(root_document) = parents.iter().next() else { - return; - }; + let base_path = root_document + .path + .as_deref() + .and_then(|path| path.parent())?; - let Some(base_path) = root_document.path.as_deref().and_then(|path| path.parent()) else { - return; + for error in &data.errors { + let full_path = base_path.join(&error.relative_path); + let Ok(full_path_uri) = Url::from_file_path(&full_path) else { + continue; }; - for error in &data.errors { - let full_path = base_path.join(&error.relative_path); - let Ok(full_path_uri) = Url::from_file_path(&full_path) else { - continue; - }; + let tex_document = workspace.lookup(&full_path_uri).unwrap_or(root_document); - let tex_document = workspace.lookup(&full_path_uri).unwrap_or(root_document); + let range = find_range_of_hint(tex_document, error).unwrap_or_else(|| { + let line = error.line.unwrap_or(0); + let offset = tex_document + .line_index + .offset(LineCol { line, col: 0 }) + .unwrap_or(TextSize::from(0)); - let range = find_range_of_hint(tex_document, error).unwrap_or_else(|| { - let line = error.line.unwrap_or(0); - let offset = tex_document - .line_index - .offset(LineCol { line, col: 0 }) - .unwrap_or(TextSize::from(0)); + TextRange::empty(offset) + }); - TextRange::empty(offset) - }); - - let diagnostic = Diagnostic { - range, - data: DiagnosticData::Build(error.clone()), - }; - - errors - .entry(tex_document.uri.clone()) - .or_default() - .push(diagnostic); - } - - self.logs - .insert(log_document.uri.clone(), BuildLog { errors }); + let diagnostic = Diagnostic::Build(range, error.clone()); + errors.insert(tex_document.uri.clone(), diagnostic); } - fn publish<'db>( - &'db mut self, - workspace: &'db Workspace, - builder: &mut DiagnosticBuilder<'db>, - ) { - self.logs.retain(|uri, _| workspace.lookup(uri).is_some()); - - for document in workspace.iter() { - let Some(log) = self.logs.get(&document.uri) else { - continue; - }; - - for (uri, errors) in &log.errors { - builder.push_many(uri, errors.iter().map(Cow::Borrowed)); - } - } - } + results.insert(log_document.uri.clone(), errors); + Some(()) } fn find_range_of_hint(document: &Document, error: &BuildError) -> Option<TextRange> { |