-
Notifications
You must be signed in to change notification settings - Fork 178
Expand file tree
/
Copy pathdiagnostic.rs
More file actions
87 lines (81 loc) · 2.64 KB
/
diagnostic.rs
File metadata and controls
87 lines (81 loc) · 2.64 KB
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
use clarity::vm::diagnostic::{Diagnostic, Level};
fn level_to_string(level: &Level) -> String {
match level {
Level::Note => blue!("note:"),
Level::Warning => yellow!("warning:"),
Level::Error => red!("error:"),
}
.to_string()
}
// Generate the formatted output for this diagnostic, given the source code.
// TODO: Preferably a filename would be saved in the Span, but for now, pass a name here.
pub fn output_diagnostic(diagnostic: &Diagnostic, name: &str, lines: &[String]) -> Vec<String> {
let mut output = Vec::new();
if !diagnostic.spans.is_empty() {
output.push(format!(
"{}:{}:{}: {} {}",
name, // diagnostic.spans[0].filename,
diagnostic.spans[0].start_line,
diagnostic.spans[0].start_column,
level_to_string(&diagnostic.level),
diagnostic.message,
));
} else {
output.push(format!(
"{} {}",
level_to_string(&diagnostic.level),
diagnostic.message,
));
}
output.append(&mut output_code(diagnostic, lines));
output
}
pub fn output_code(diagnostic: &Diagnostic, lines: &[String]) -> Vec<String> {
let mut output = Vec::new();
if diagnostic.spans.is_empty() {
return output;
}
let span = &diagnostic.spans[0];
let first_line = span.start_line.saturating_sub(1) as usize;
output.push(lines[first_line].clone());
let mut pointer = format!(
"{: <1$}^",
"",
(span.start_column.saturating_sub(1)) as usize
);
if span.start_line == span.end_line {
pointer = format!(
"{}{:~<2$}",
pointer,
"",
(span.end_column - span.start_column) as usize
);
}
pointer = pointer.to_string();
output.push(pointer);
for span in diagnostic.spans.iter().skip(1) {
let first_line = span.start_line.saturating_sub(1) as usize;
let last_line = span.end_line.saturating_sub(1) as usize;
output.push(lines[first_line].clone());
let mut pointer = format!(
"{: <1$}^",
"",
(span.start_column.saturating_sub(1)) as usize
);
if span.start_line == span.end_line {
pointer = format!(
"{}{:~<2$}",
pointer,
"",
(span.end_column - span.start_column) as usize
);
} else {
#[allow(clippy::needless_range_loop)]
for line_num in (first_line + 1)..last_line {
output.push(lines[line_num].clone());
}
}
output.push(pointer);
}
output
}