summaryrefslogtreecommitdiff
path: root/support/texlab/src/diagnostics/build.rs
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2022-07-04 03:03:43 +0000
committerNorbert Preining <norbert@preining.info>2022-07-04 03:03:43 +0000
commit1c10375ec46d7d83b2f1efc2a71b7ea114c889f0 (patch)
tree47b3469111105b7767111dcb89858fbc1e73377f /support/texlab/src/diagnostics/build.rs
parent34d318af65decbdb242ae03b64bf3f53266067b6 (diff)
CTAN sync 202207040303
Diffstat (limited to 'support/texlab/src/diagnostics/build.rs')
-rw-r--r--support/texlab/src/diagnostics/build.rs68
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(())
+}