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
3 changed files with 67 additions and 143 deletions
|
@ -543,7 +543,7 @@ mod test {
|
||||||
dreizehn
|
dreizehn
|
||||||
";
|
";
|
||||||
let file = cm.new_filemap_and_lines("dummy.txt", content);
|
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 end = file.lines.borrow()[11];
|
||||||
let sp = mk_sp(start, end);
|
let sp = mk_sp(start, end);
|
||||||
let lvl = Level::Error;
|
let lvl = Level::Error;
|
||||||
|
@ -555,12 +555,9 @@ mod test {
|
||||||
let str = from_utf8(vec).unwrap();
|
let str = from_utf8(vec).unwrap();
|
||||||
println!("r#\"\n{}\"#", str);
|
println!("r#\"\n{}\"#", str);
|
||||||
assert_eq!(str, &r#"
|
assert_eq!(str, &r#"
|
||||||
--> dummy.txt:8:1
|
--> dummy.txt:11:1
|
||||||
8 |> line8
|
|
||||||
|> ^^^^^^^^^^^^^
|
|
||||||
...
|
|
||||||
11 |> e-lä-vän
|
11 |> e-lä-vän
|
||||||
|> ^^^^^^^^^^^^^^^^
|
|> ^
|
||||||
"#[1..]);
|
"#[1..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -696,9 +693,8 @@ mod test {
|
||||||
let expect0 = &r#"
|
let expect0 = &r#"
|
||||||
--> dummy.txt:5:1
|
--> dummy.txt:5:1
|
||||||
5 |> ccccc
|
5 |> ccccc
|
||||||
|> ^^^^^
|
|> ^
|
||||||
...
|
...
|
||||||
8 |> _____
|
|
||||||
9 |> ddd__eee_
|
9 |> ddd__eee_
|
||||||
|> ^^^ ^^^
|
|> ^^^ ^^^
|
||||||
10 |> elided
|
10 |> elided
|
||||||
|
@ -709,9 +705,8 @@ mod test {
|
||||||
let expect = &r#"
|
let expect = &r#"
|
||||||
--> dummy.txt:1:1
|
--> dummy.txt:1:1
|
||||||
1 |> aaaaa
|
1 |> aaaaa
|
||||||
|> ^^^^^
|
|> ^
|
||||||
...
|
...
|
||||||
8 |> _____
|
|
||||||
9 |> ddd__eee_
|
9 |> ddd__eee_
|
||||||
|> ^^^ ^^^
|
|> ^^^ ^^^
|
||||||
10 |> elided
|
10 |> elided
|
||||||
|
|
|
@ -49,7 +49,7 @@ struct Annotation {
|
||||||
/// column.
|
/// column.
|
||||||
start_col: usize,
|
start_col: usize,
|
||||||
|
|
||||||
/// End column within the line.
|
/// End column within the line (exclusive)
|
||||||
end_col: usize,
|
end_col: usize,
|
||||||
|
|
||||||
/// Is this annotation derived from primary span
|
/// Is this annotation derived from primary span
|
||||||
|
@ -349,24 +349,40 @@ impl FileInfo {
|
||||||
label: Option<String>) {
|
label: Option<String>) {
|
||||||
assert!(lines.len() > 0);
|
assert!(lines.len() > 0);
|
||||||
|
|
||||||
// If a span covers multiple lines, just put the label on the
|
// If a span covers multiple lines, we reduce it to a single
|
||||||
// first one. This is a sort of arbitrary choice and not
|
// point at the start of the span. This means that instead
|
||||||
// obviously correct.
|
// of producing output like this:
|
||||||
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,
|
// --> foo.rs:2:1
|
||||||
line0.end_col,
|
// 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,
|
is_primary,
|
||||||
label);
|
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
|
/// Ensure that we have a `Line` struct corresponding to
|
||||||
|
@ -414,57 +430,10 @@ impl FileInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_file_lines(&self, codemap: &Rc<CodeMap>) -> Vec<RenderedLine> {
|
fn render_file_lines(&self, codemap: &Rc<CodeMap>) -> Vec<RenderedLine> {
|
||||||
// Group our lines by those with annotations and those without
|
// As a first step, we elide any instance of more than one
|
||||||
let mut lines_iter = self.lines.iter().peekable();
|
// continuous unannotated line.
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
let mut lines_iter = self.lines.iter();
|
||||||
let mut output = vec![];
|
let mut output = vec![];
|
||||||
|
|
||||||
// First insert the name of the file.
|
// First insert the name of the file.
|
||||||
|
@ -493,65 +462,30 @@ impl FileInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for &(is_annotated, ref group) in line_groups.iter() {
|
let mut next_line = lines_iter.next();
|
||||||
if is_annotated {
|
while next_line.is_some() {
|
||||||
let mut annotation_ends_at_eol = false;
|
// Consume lines with annotations.
|
||||||
let mut prev_ends_at_eol = false;
|
while let Some(line) = next_line {
|
||||||
let mut elide_unlabeled_region = false;
|
if line.annotations.is_empty() { break; }
|
||||||
|
output.append(&mut self.render_line(line));
|
||||||
|
next_line = lines_iter.next();
|
||||||
|
}
|
||||||
|
|
||||||
for group_line in group.iter() {
|
// Emit lines without annotations, but only if they are
|
||||||
let source_string_len =
|
// followed by a line with an annotation.
|
||||||
self.file.get_line(group_line.line_index)
|
let unannotated_line = next_line;
|
||||||
.map(|s| s.len())
|
let mut unannotated_lines = 0;
|
||||||
.unwrap_or(0);
|
while let Some(line) = next_line {
|
||||||
|
if !line.annotations.is_empty() { break; }
|
||||||
for annotation in &group_line.annotations {
|
unannotated_lines += 1;
|
||||||
if annotation.end_col == source_string_len {
|
next_line = lines_iter.next();
|
||||||
annotation_ends_at_eol = true;
|
}
|
||||||
}
|
if unannotated_lines > 1 {
|
||||||
}
|
output.push(RenderedLine::from((String::new(),
|
||||||
|
Style::NoStyle,
|
||||||
let is_single_unlabeled_annotated_line =
|
RenderedLineKind::Elision)));
|
||||||
if group_line.annotations.len() == 1 {
|
} else if let Some(line) = unannotated_line {
|
||||||
if let Some(annotation) = group_line.annotations.first() {
|
output.append(&mut self.render_line(line));
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -406,8 +406,7 @@ impl SomeTrait for () {
|
||||||
assert_eq!(text, &r#"
|
assert_eq!(text, &r#"
|
||||||
>>>>>> foo.rs
|
>>>>>> foo.rs
|
||||||
3 |> fn foo(x: u32) {
|
3 |> fn foo(x: u32) {
|
||||||
|> ----------------
|
|> -
|
||||||
...
|
|
||||||
"#[1..]);
|
"#[1..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -515,12 +514,8 @@ fn span_overlap_label3() {
|
||||||
assert_eq!(text, &r#"
|
assert_eq!(text, &r#"
|
||||||
>>>> foo.rs
|
>>>> foo.rs
|
||||||
3 |> let closure = || {
|
3 |> let closure = || {
|
||||||
|> ---- foo
|
|> - foo
|
||||||
4 |> inner
|
4 |> inner
|
||||||
|> ----------------
|
|> ---- bar
|
||||||
|> |
|
|
||||||
|> bar
|
|
||||||
5 |> };
|
|
||||||
|> --------
|
|
||||||
"#[1..]);
|
"#[1..]);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue