only emit ^
at the start of a multi-line error
as a result, simplify elision code
This commit is contained in:
parent
24f4b151b1
commit
1fdbfcdbd0
@ -543,7 +543,7 @@ fn test_hilight_suggestion_issue_11715() {
|
||||
dreizehn
|
||||
";
|
||||
let file = cm.new_filemap_and_lines("dummy.txt", content);
|
||||
let start = file.lines.borrow()[7];
|
||||
let start = file.lines.borrow()[10];
|
||||
let end = file.lines.borrow()[11];
|
||||
let sp = mk_sp(start, end);
|
||||
let lvl = Level::Error;
|
||||
@ -555,12 +555,9 @@ fn test_hilight_suggestion_issue_11715() {
|
||||
let str = from_utf8(vec).unwrap();
|
||||
println!("r#\"\n{}\"#", str);
|
||||
assert_eq!(str, &r#"
|
||||
--> dummy.txt:8:1
|
||||
8 |> line8
|
||||
|> ^^^^^^^^^^^^^
|
||||
...
|
||||
--> dummy.txt:11:1
|
||||
11 |> e-lä-vän
|
||||
|> ^^^^^^^^^^^^^^^^
|
||||
|> ^
|
||||
"#[1..]);
|
||||
}
|
||||
|
||||
@ -696,9 +693,8 @@ fn test_huge_multispan_highlight() {
|
||||
let expect0 = &r#"
|
||||
--> dummy.txt:5:1
|
||||
5 |> ccccc
|
||||
|> ^^^^^
|
||||
|> ^
|
||||
...
|
||||
8 |> _____
|
||||
9 |> ddd__eee_
|
||||
|> ^^^ ^^^
|
||||
10 |> elided
|
||||
@ -709,9 +705,8 @@ fn test_huge_multispan_highlight() {
|
||||
let expect = &r#"
|
||||
--> dummy.txt:1:1
|
||||
1 |> aaaaa
|
||||
|> ^^^^^
|
||||
|> ^
|
||||
...
|
||||
8 |> _____
|
||||
9 |> ddd__eee_
|
||||
|> ^^^ ^^^
|
||||
10 |> elided
|
||||
|
@ -49,7 +49,7 @@ struct Annotation {
|
||||
/// column.
|
||||
start_col: usize,
|
||||
|
||||
/// End column within the line.
|
||||
/// End column within the line (exclusive)
|
||||
end_col: usize,
|
||||
|
||||
/// Is this annotation derived from primary span
|
||||
@ -349,24 +349,40 @@ fn push_lines(&mut self,
|
||||
label: Option<String>) {
|
||||
assert!(lines.len() > 0);
|
||||
|
||||
// If a span covers multiple lines, just put the label on the
|
||||
// first one. This is a sort of arbitrary choice and not
|
||||
// obviously correct.
|
||||
let (line0, remaining_lines) = lines.split_first().unwrap();
|
||||
let index = self.ensure_source_line(line0.line_index);
|
||||
self.lines[index].push_annotation(line0.start_col,
|
||||
line0.end_col,
|
||||
// If a span covers multiple lines, we reduce it to a single
|
||||
// point at the start of the span. This means that instead
|
||||
// of producing output like this:
|
||||
//
|
||||
// ```
|
||||
// --> foo.rs:2:1
|
||||
// 2 |> fn conflicting_items<'grammar>(state: &LR0State<'grammar>)
|
||||
// |> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
// 3 |> -> Set<LR0Item<'grammar>>
|
||||
// |> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
// (and so on)
|
||||
// ```
|
||||
//
|
||||
// we produce:
|
||||
//
|
||||
// ```
|
||||
// --> foo.rs:2:1
|
||||
// 2 |> fn conflicting_items<'grammar>(state: &LR0State<'grammar>)
|
||||
// ^
|
||||
// ```
|
||||
//
|
||||
// Basically, although this loses information, multi-line spans just
|
||||
// never look good.
|
||||
|
||||
let (line, start_col, end_col) = if lines.len() == 1 {
|
||||
(lines[0].line_index, lines[0].start_col, lines[0].end_col)
|
||||
} else {
|
||||
(lines[0].line_index, lines[0].start_col, CharPos(lines[0].start_col.0 + 1))
|
||||
};
|
||||
let index = self.ensure_source_line(line);
|
||||
self.lines[index].push_annotation(start_col,
|
||||
end_col,
|
||||
is_primary,
|
||||
label);
|
||||
for line in remaining_lines {
|
||||
if line.end_col > line.start_col {
|
||||
let index = self.ensure_source_line(line.line_index);
|
||||
self.lines[index].push_annotation(line.start_col,
|
||||
line.end_col,
|
||||
is_primary,
|
||||
None);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensure that we have a `Line` struct corresponding to
|
||||
@ -414,57 +430,10 @@ fn ensure_source_line(&mut self, line_index: usize) -> usize {
|
||||
}
|
||||
|
||||
fn render_file_lines(&self, codemap: &Rc<CodeMap>) -> Vec<RenderedLine> {
|
||||
// Group our lines by those with annotations and those without
|
||||
let mut lines_iter = self.lines.iter().peekable();
|
||||
|
||||
let mut line_groups = vec![];
|
||||
|
||||
loop {
|
||||
match lines_iter.next() {
|
||||
None => break,
|
||||
Some(line) if line.annotations.is_empty() => {
|
||||
// Collect unannotated group
|
||||
let mut unannotated_group : Vec<&Line> = vec![];
|
||||
|
||||
unannotated_group.push(line);
|
||||
|
||||
loop {
|
||||
let next_line =
|
||||
match lines_iter.peek() {
|
||||
None => break,
|
||||
Some(x) if !x.annotations.is_empty() => break,
|
||||
Some(x) => x.clone()
|
||||
};
|
||||
|
||||
unannotated_group.push(next_line);
|
||||
lines_iter.next();
|
||||
}
|
||||
|
||||
line_groups.push((false, unannotated_group));
|
||||
}
|
||||
Some(line) => {
|
||||
// Collect annotated group
|
||||
let mut annotated_group : Vec<&Line> = vec![];
|
||||
|
||||
annotated_group.push(line);
|
||||
|
||||
loop {
|
||||
let next_line =
|
||||
match lines_iter.peek() {
|
||||
None => break,
|
||||
Some(x) if x.annotations.is_empty() => break,
|
||||
Some(x) => x.clone()
|
||||
};
|
||||
|
||||
annotated_group.push(next_line);
|
||||
lines_iter.next();
|
||||
}
|
||||
|
||||
line_groups.push((true, annotated_group));
|
||||
}
|
||||
}
|
||||
}
|
||||
// As a first step, we elide any instance of more than one
|
||||
// continuous unannotated line.
|
||||
|
||||
let mut lines_iter = self.lines.iter();
|
||||
let mut output = vec![];
|
||||
|
||||
// First insert the name of the file.
|
||||
@ -493,65 +462,30 @@ fn render_file_lines(&self, codemap: &Rc<CodeMap>) -> Vec<RenderedLine> {
|
||||
}
|
||||
}
|
||||
|
||||
for &(is_annotated, ref group) in line_groups.iter() {
|
||||
if is_annotated {
|
||||
let mut annotation_ends_at_eol = false;
|
||||
let mut prev_ends_at_eol = false;
|
||||
let mut elide_unlabeled_region = false;
|
||||
let mut next_line = lines_iter.next();
|
||||
while next_line.is_some() {
|
||||
// Consume lines with annotations.
|
||||
while let Some(line) = next_line {
|
||||
if line.annotations.is_empty() { break; }
|
||||
output.append(&mut self.render_line(line));
|
||||
next_line = lines_iter.next();
|
||||
}
|
||||
|
||||
for group_line in group.iter() {
|
||||
let source_string_len =
|
||||
self.file.get_line(group_line.line_index)
|
||||
.map(|s| s.len())
|
||||
.unwrap_or(0);
|
||||
|
||||
for annotation in &group_line.annotations {
|
||||
if annotation.end_col == source_string_len {
|
||||
annotation_ends_at_eol = true;
|
||||
}
|
||||
}
|
||||
|
||||
let is_single_unlabeled_annotated_line =
|
||||
if group_line.annotations.len() == 1 {
|
||||
if let Some(annotation) = group_line.annotations.first() {
|
||||
match annotation.label {
|
||||
Some(_) => false,
|
||||
None => annotation.start_col == 0 &&
|
||||
annotation.end_col == source_string_len
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
if prev_ends_at_eol && is_single_unlabeled_annotated_line {
|
||||
if !elide_unlabeled_region {
|
||||
output.push(RenderedLine::from((String::new(),
|
||||
Style::NoStyle,
|
||||
RenderedLineKind::Elision)));
|
||||
elide_unlabeled_region = true;
|
||||
prev_ends_at_eol = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut v = self.render_line(group_line);
|
||||
output.append(&mut v);
|
||||
|
||||
prev_ends_at_eol = annotation_ends_at_eol;
|
||||
}
|
||||
} else {
|
||||
if group.len() > 1 {
|
||||
output.push(RenderedLine::from((String::new(),
|
||||
Style::NoStyle,
|
||||
RenderedLineKind::Elision)));
|
||||
} else {
|
||||
let mut v: Vec<RenderedLine> =
|
||||
group.iter().flat_map(|line| self.render_line(line)).collect();
|
||||
output.append(&mut v);
|
||||
}
|
||||
// Emit lines without annotations, but only if they are
|
||||
// followed by a line with an annotation.
|
||||
let unannotated_line = next_line;
|
||||
let mut unannotated_lines = 0;
|
||||
while let Some(line) = next_line {
|
||||
if !line.annotations.is_empty() { break; }
|
||||
unannotated_lines += 1;
|
||||
next_line = lines_iter.next();
|
||||
}
|
||||
if unannotated_lines > 1 {
|
||||
output.push(RenderedLine::from((String::new(),
|
||||
Style::NoStyle,
|
||||
RenderedLineKind::Elision)));
|
||||
} else if let Some(line) = unannotated_line {
|
||||
output.append(&mut self.render_line(line));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -406,8 +406,7 @@ fn foo(x: u32) {
|
||||
assert_eq!(text, &r#"
|
||||
>>>>>> foo.rs
|
||||
3 |> fn foo(x: u32) {
|
||||
|> ----------------
|
||||
...
|
||||
|> -
|
||||
"#[1..]);
|
||||
}
|
||||
|
||||
@ -515,12 +514,8 @@ fn foo() {
|
||||
assert_eq!(text, &r#"
|
||||
>>>> foo.rs
|
||||
3 |> let closure = || {
|
||||
|> ---- foo
|
||||
|> - foo
|
||||
4 |> inner
|
||||
|> ----------------
|
||||
|> |
|
||||
|> bar
|
||||
5 |> };
|
||||
|> --------
|
||||
|> ---- bar
|
||||
"#[1..]);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user