diff options
author | Norbert Preining <norbert@preining.info> | 2022-07-04 03:03:43 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2022-07-04 03:03:43 +0000 |
commit | 1c10375ec46d7d83b2f1efc2a71b7ea114c889f0 (patch) | |
tree | 47b3469111105b7767111dcb89858fbc1e73377f /support/texlab/src/diagnostics/build.rs | |
parent | 34d318af65decbdb242ae03b64bf3f53266067b6 (diff) |
CTAN sync 202207040303
Diffstat (limited to 'support/texlab/src/diagnostics/build.rs')
-rw-r--r-- | support/texlab/src/diagnostics/build.rs | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/support/texlab/src/diagnostics/build.rs b/support/texlab/src/diagnostics/build.rs new file mode 100644 index 0000000000..4b4ffcc8b4 --- /dev/null +++ b/support/texlab/src/diagnostics/build.rs @@ -0,0 +1,68 @@ +use std::{path::PathBuf, sync::Arc}; + +use dashmap::DashMap; +use lsp_types::{DiagnosticSeverity, Position, Range, Url}; + +use crate::{syntax::build_log::BuildErrorLevel, Workspace}; + +use super::{Diagnostic, DiagnosticCode}; + +pub fn collect_build_diagnostics( + all_diagnostics: &DashMap<Arc<Url>, Vec<Diagnostic>>, + workspace: &Workspace, + build_log_uri: &Url, +) -> Option<()> { + let build_log_document = workspace.documents_by_uri.get(build_log_uri)?; + let build_log = build_log_document.data.as_build_log()?; + + all_diagnostics.alter_all(|_, mut diagnostics| { + diagnostics.retain( + |diag| !matches!(&diag.code, DiagnosticCode::Build(uri) if uri.as_ref() == build_log_uri), + ); + diagnostics + }); + + let root_document = workspace.documents_by_uri.values().find(|document| { + document.data.as_latex().map_or(false, |data| { + !document.uri.as_str().ends_with(".aux") + && data + .extras + .implicit_links + .log + .iter() + .any(|u| u.as_ref() == build_log_uri) + }) + })?; + + let base_path = PathBuf::from(root_document.uri.path()); + for error in &build_log.errors { + let position = Position::new(error.line.unwrap_or(0), 0); + let severity = match error.level { + BuildErrorLevel::Error => DiagnosticSeverity::ERROR, + BuildErrorLevel::Warning => DiagnosticSeverity::WARNING, + }; + let range = Range::new(position, position); + let diagnostic = Diagnostic { + severity, + range, + code: DiagnosticCode::Build(Arc::clone(&build_log_document.uri)), + message: error.message.clone(), + }; + + let full_path = base_path.join(&error.relative_path); + + let uri = if full_path.starts_with(&base_path) { + error + .relative_path + .to_str() + .and_then(|path| root_document.uri.join(path).map(Into::into).ok()) + .map_or_else(|| Arc::clone(&root_document.uri), Arc::new) + } else { + Arc::clone(&root_document.uri) + }; + + all_diagnostics.entry(uri).or_default().push(diagnostic); + } + + Some(()) +} |