summaryrefslogtreecommitdiff
path: root/support/texlab/crates/diagnostics/src/build_log.rs
diff options
context:
space:
mode:
Diffstat (limited to 'support/texlab/crates/diagnostics/src/build_log.rs')
-rw-r--r--support/texlab/crates/diagnostics/src/build_log.rs104
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> {