1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
use std::{path::PathBuf, sync::Arc};
use lsp_types::{Diagnostic, DiagnosticSeverity, Position, Range};
use multimap::MultiMap;
use crate::{syntax::build_log::BuildErrorLevel, Uri, Workspace};
pub fn analyze_build_log_static(
workspace: &dyn Workspace,
diagnostics_by_uri: &mut MultiMap<Arc<Uri>, Diagnostic>,
build_log_uri: &Uri,
) -> Option<()> {
let build_log_document = workspace.get(build_log_uri)?;
let parse = build_log_document.data.as_build_log()?;
let root_document = workspace.documents().into_iter().find(|document| {
if let Some(data) = document.data.as_latex() {
!document.uri.as_str().ends_with(".aux")
&& data
.extras
.implicit_links
.log
.iter()
.any(|u| u.as_ref() == build_log_uri)
} else {
false
}
})?;
let base_path = PathBuf::from(root_document.uri.path());
for error in &parse.errors {
let pos = 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(pos, pos);
let diagnostic = Diagnostic {
range,
severity: Some(severity),
code: None,
code_description: None,
source: Some("latex".into()),
message: error.message.clone(),
related_information: None,
tags: None,
data: None,
};
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(Arc::new)
.unwrap_or_else(|| Arc::clone(&root_document.uri))
} else {
Arc::clone(&root_document.uri)
};
diagnostics_by_uri.insert(uri, diagnostic);
}
Some(())
}
|