cairo_lang_diagnostics/
location_marks.rs1use cairo_lang_filesystem::span::{TextPosition, TextSpan, TextWidth};
2
3use crate::DiagnosticLocation;
4
5#[cfg(test)]
6#[path = "location_marks_test.rs"]
7mod test;
8
9pub fn get_location_marks(
10 db: &dyn cairo_lang_filesystem::db::FilesGroup,
11 location: &DiagnosticLocation,
12) -> String {
13 let content = db.file_content(location.file_id).expect("File missing from DB.");
15 let summary = db.file_summary(location.file_id).expect("File missing from DB.");
16
17 let span = &location.span;
18
19 let TextPosition { line: first_line_idx, col } = span
20 .start
21 .position_in_file(db, location.file_id)
22 .expect("Failed to find location in file.");
23 let first_line_start = summary.line_offsets[first_line_idx];
24 let first_line_end = match summary.line_offsets.get(first_line_idx + 1) {
25 Some(offset) => offset.sub_width(TextWidth::from_char('\n')),
26 None => summary.last_offset,
27 };
28
29 let first_line_span = TextSpan { start: first_line_start, end: first_line_end };
30 let mut res = first_line_span.take(&content).to_string();
31 res.push('\n');
32 for _ in 0..col {
33 res.push(' ');
34 }
35 res.push('^');
36
37 let subspan_in_first_line =
38 TextSpan { start: span.start, end: std::cmp::min(first_line_end, span.end) };
39 let marker_length = subspan_in_first_line.n_chars(&content);
40 if marker_length > 1 {
41 for _ in 0..marker_length - 2 {
42 res.push('*');
43 }
44 res.push('^');
45 }
46
47 res
48}