Group related diagnostics with a graphical line

This commit is contained in:
Marcel Müller 2022-05-06 10:42:31 +02:00
parent 2b9b6af79e
commit c7ebcaf51e
3 changed files with 108 additions and 40 deletions

View File

@ -35,6 +35,7 @@ indenter = "0.3.0"
rustversion = "1.0" rustversion = "1.0"
trybuild = { version = "1.0.19", features = ["diff"] } trybuild = { version = "1.0.19", features = ["diff"] }
syn = { version = "1.0", features = ["full"] } syn = { version = "1.0", features = ["full"] }
pretty_assertions = "1.2.1"
[features] [features]
default = [] default = []

View File

@ -272,20 +272,47 @@ impl GraphicalReportHandler {
parent_src: Option<&dyn SourceCode>, parent_src: Option<&dyn SourceCode>,
) -> fmt::Result { ) -> fmt::Result {
if let Some(related) = diagnostic.related() { if let Some(related) = diagnostic.related() {
writeln!(f)?; let related: Vec<_> = related.collect();
for rel in related { writeln!(
f,
"{}{}There were {} related diagnostics:",
if related.is_empty() {
self.theme.characters.lcross
} else {
self.theme.characters.ltop
},
self.theme.characters.hbar,
related.len()
)?;
let width = self.termwidth.saturating_sub(2);
let mut inner = String::new();
for (idx, rel) in related.into_iter().enumerate() {
let init_ident = format!(
"{}{} {}.",
self.theme.characters.lcross,
self.theme.characters.hbar,
idx + 1
);
let subseq_ident = format!("{} ", self.theme.characters.vbar);
let opts = textwrap::Options::new(width)
.initial_indent(&init_ident)
.subsequent_indent(&subseq_ident);
match diagnostic.severity() { match diagnostic.severity() {
Some(Severity::Error) | None => write!(f, "Error: ")?, Some(Severity::Error) | None => write!(&mut inner, "Error: ")?,
Some(Severity::Warning) => write!(f, "Warning: ")?, Some(Severity::Warning) => write!(&mut inner, "Warning: ")?,
Some(Severity::Advice) => write!(f, "Advice: ")?, Some(Severity::Advice) => write!(&mut inner, "Advice: ")?,
}; };
self.render_header(f, rel)?; self.render_header(&mut inner, rel)?;
writeln!(f)?; writeln!(&mut inner)?;
self.render_causes(f, rel)?; self.render_causes(&mut inner, rel)?;
let src = rel.source_code().or(parent_src); let src = rel.source_code().or(parent_src);
self.render_snippets(f, rel, src)?; self.render_snippets(&mut inner, rel, src)?;
self.render_footer(f, rel)?; self.render_footer(&mut inner, rel)?;
self.render_related(f, rel, src)?; self.render_related(&mut inner, rel, src)?;
writeln!(f, "{}", textwrap::fill(&inner, opts))?;
inner.clear();
} }
} }
Ok(()) Ok(())

View File

@ -5,6 +5,7 @@ use miette::{
NarratableReportHandler, Report, SourceSpan, NarratableReportHandler, Report, SourceSpan,
}; };
use thiserror::Error; use thiserror::Error;
use pretty_assertions::assert_eq;
fn fmt_report(diag: Report) -> String { fn fmt_report(diag: Report) -> String {
let mut out = String::new(); let mut out = String::new();
@ -784,11 +785,22 @@ fn related() -> Result<(), MietteError> {
let err = MyBad { let err = MyBad {
src: NamedSource::new("bad_file.rs", src.clone()), src: NamedSource::new("bad_file.rs", src.clone()),
highlight: (9, 4).into(), highlight: (9, 4).into(),
related: vec![MyBad { related: vec![
src: NamedSource::new("bad_file.rs", src), MyBad {
highlight: (0, 6).into(), src: NamedSource::new("bad_file.rs", src.clone()),
related: vec![], highlight: (0, 6).into(),
}], related: vec![MyBad {
src: NamedSource::new("bad_file.rs", src.clone()),
highlight: (0, 6).into(),
related: vec![],
}],
},
MyBad {
src: NamedSource::new("bad_file.rs", src.clone()),
highlight: (0, 6).into(),
related: vec![],
},
],
}; };
let out = fmt_report(err.into()); let out = fmt_report(err.into());
println!("Error: {}", out); println!("Error: {}", out);
@ -803,19 +815,46 @@ fn related() -> Result<(), MietteError> {
3 here 3 here
help: try doing it better next time? help: try doing it better next time?
There were 2 related diagnostics:
Error: oops::my::bad 1.Error: oops::my::bad
× oops! × oops!
[bad_file.rs:1:1] [bad_file.rs:1:1]
1 source 1 source
· ·
· this bit here · this bit here
2 text 2 text
help: try doing it better next time? help: try doing it better next time?
There were 1 related diagnostics:
1.Error: oops::my::bad
× oops!
[bad_file.rs:1:1]
1 source
·
· this bit here
2 text
help: try doing it better next time?
There were 0 related diagnostics:
2.Error: oops::my::bad
× oops!
[bad_file.rs:1:1]
1 source
·
· this bit here
2 text
help: try doing it better next time?
There were 0 related diagnostics:
"# "#
.trim_start() .trim_start()
.to_string(); .to_string();
@ -866,17 +905,18 @@ fn related_source_code_propagation() -> Result<(), MietteError> {
3 here 3 here
help: try doing it better next time? help: try doing it better next time?
There were 1 related diagnostics:
Error: oops::my::bad 1.Error: oops::my::bad
× oops! × oops!
[bad_file.rs:1:1] [bad_file.rs:1:1]
1 source 1 source
· ·
· this bit here · this bit here
2 text 2 text
"# "#
.trim_start() .trim_start()
.to_string(); .to_string();