Add back in a 'old school' error format

This commit is contained in:
Jonathan Turner 2016-04-28 16:39:59 -07:00 committed by Niko Matsakis
parent 49dfac4872
commit 84cb56f8ee
2 changed files with 202 additions and 51 deletions

View File

@ -135,6 +135,9 @@ pub struct EmitterWriter {
/// Is this the first error emitted thus far? If not, we emit a
/// `\n` before the top-level errors.
first: bool,
// For now, allow an old-school mode while we transition
old_school: bool,
}
impl CoreEmitter for EmitterWriter {
@ -170,14 +173,23 @@ impl EmitterWriter {
registry: Option<diagnostics::registry::Registry>,
code_map: Rc<codemap::CodeMap>)
-> EmitterWriter {
let old_school = match ::std::env::var("RUST_NEW_ERROR_FORMAT") {
Ok(_) => false,
Err(_) => true,
};
if color_config.use_color() {
let dst = Destination::from_stderr();
EmitterWriter { dst: dst, registry: registry, cm: code_map, first: true }
EmitterWriter { dst: dst,
registry: registry,
cm: code_map,
first: true,
old_school: old_school }
} else {
EmitterWriter { dst: Raw(Box::new(io::stderr())),
registry: registry,
cm: code_map,
first: true }
first: true,
old_school: old_school }
}
}
@ -185,7 +197,15 @@ impl EmitterWriter {
registry: Option<diagnostics::registry::Registry>,
code_map: Rc<codemap::CodeMap>)
-> EmitterWriter {
EmitterWriter { dst: Raw(dst), registry: registry, cm: code_map, first: true }
let old_school = match ::std::env::var("RUST_NEW_ERROR_FORMAT") {
Ok(_) => false,
Err(_) => true,
};
EmitterWriter { dst: Raw(dst),
registry: registry,
cm: code_map,
first: true,
old_school: old_school }
}
fn emit_message_(&mut self,
@ -199,7 +219,9 @@ impl EmitterWriter {
if self.first {
self.first = false;
} else {
write!(self.dst, "\n")?;
if !self.old_school {
write!(self.dst, "\n")?;
}
}
}
@ -208,7 +230,17 @@ impl EmitterWriter {
.and_then(|registry| registry.find_description(code))
.is_some() => {
let code_with_explain = String::from("--explain ") + code;
print_diagnostic(&mut self.dst, "", lvl, msg, Some(&code_with_explain))?
if self.old_school {
let loc = match rsp.span().primary_span() {
Some(COMMAND_LINE_SP) | Some(DUMMY_SP) => "".to_string(),
Some(ps) => self.cm.span_to_string(ps),
None => "".to_string()
};
print_diagnostic(&mut self.dst, &loc, lvl, msg, Some(code))?
}
else {
print_diagnostic(&mut self.dst, "", lvl, msg, Some(&code_with_explain))?
}
}
_ => {
print_diagnostic(&mut self.dst, "", lvl, msg, code)?
@ -239,7 +271,24 @@ impl EmitterWriter {
}
}
}
if self.old_school {
match code {
Some(code) if self.registry.as_ref()
.and_then(|registry| registry.find_description(code))
.is_some() => {
let loc = match rsp.span().primary_span() {
Some(COMMAND_LINE_SP) | Some(DUMMY_SP) => "".to_string(),
Some(ps) => self.cm.span_to_string(ps),
None => "".to_string()
};
let msg = "run `rustc --explain ".to_string() + &code.to_string() +
"` to see a detailed explanation";
print_diagnostic(&mut self.dst, &loc, Level::Help, &msg,
None)?
}
_ => ()
}
}
Ok(())
}
@ -282,19 +331,48 @@ impl EmitterWriter {
{
let mut snippet_data = SnippetData::new(self.cm.clone(),
msp.primary_span());
for span_label in msp.span_labels() {
snippet_data.push(span_label.span,
span_label.is_primary,
span_label.label);
}
let rendered_lines = snippet_data.render_lines();
for rendered_line in &rendered_lines {
for styled_string in &rendered_line.text {
self.dst.apply_style(lvl, &rendered_line.kind, styled_string.style)?;
write!(&mut self.dst, "{}", styled_string.text)?;
self.dst.reset_attrs()?;
if self.old_school {
let mut output_vec = vec![];
for span_label in msp.span_labels() {
let mut snippet_data = snippet_data.clone();
snippet_data.push(span_label.span,
span_label.is_primary,
span_label.label);
if span_label.is_primary {
output_vec.insert(0, snippet_data);
}
else {
output_vec.push(snippet_data);
}
}
for snippet_data in output_vec.iter() {
let rendered_lines = snippet_data.render_lines();
for rendered_line in &rendered_lines {
for styled_string in &rendered_line.text {
self.dst.apply_style(lvl, &rendered_line.kind, styled_string.style)?;
write!(&mut self.dst, "{}", styled_string.text)?;
self.dst.reset_attrs()?;
}
write!(&mut self.dst, "\n")?;
}
}
}
else {
for span_label in msp.span_labels() {
snippet_data.push(span_label.span,
span_label.is_primary,
span_label.label);
}
let rendered_lines = snippet_data.render_lines();
for rendered_line in &rendered_lines {
for styled_string in &rendered_line.text {
self.dst.apply_style(lvl, &rendered_line.kind, styled_string.style)?;
write!(&mut self.dst, "{}", styled_string.text)?;
self.dst.reset_attrs()?;
}
write!(&mut self.dst, "\n")?;
}
write!(&mut self.dst, "\n")?;
}
Ok(())
}
@ -327,7 +405,6 @@ fn line_num_max_digits(line: &codemap::LineInfo) -> usize {
digits
}
fn print_diagnostic(dst: &mut Destination,
topic: &str,
lvl: Level,
@ -335,7 +412,6 @@ fn print_diagnostic(dst: &mut Destination,
code: Option<&str>)
-> io::Result<()> {
if !topic.is_empty() {
dst.start_attr(term::Attr::ForegroundColor(lvl.color()))?;
write!(dst, "{}: ", topic)?;
dst.reset_attrs()?;
}
@ -346,10 +422,12 @@ fn print_diagnostic(dst: &mut Destination,
write!(dst, ": ")?;
dst.start_attr(term::Attr::Bold)?;
write!(dst, "{}", msg)?;
if let Some(code) = code {
let style = term::Attr::ForegroundColor(term::color::BRIGHT_MAGENTA);
print_maybe_styled!(dst, style, " [{}]", code.clone())?;
}
dst.reset_attrs()?;
write!(dst, "\n")?;
Ok(())

View File

@ -17,11 +17,13 @@ use std::mem;
mod test;
#[derive(Clone)]
pub struct SnippetData {
codemap: Rc<CodeMap>,
files: Vec<FileInfo>,
}
#[derive(Clone)]
pub struct FileInfo {
file: Rc<FileMap>,
@ -35,6 +37,7 @@ pub struct FileInfo {
lines: Vec<Line>,
}
#[derive(Clone)]
struct Line {
line_index: usize,
annotations: Vec<Annotation>,
@ -429,6 +432,10 @@ impl FileInfo {
}
fn render_file_lines(&self, codemap: &Rc<CodeMap>) -> Vec<RenderedLine> {
let old_school = match ::std::env::var("RUST_NEW_ERROR_FORMAT") {
Ok(_) => false,
Err(_) => true,
};
// As a first step, we elide any instance of more than one
// continuous unannotated line.
@ -436,28 +443,30 @@ impl FileInfo {
let mut output = vec![];
// First insert the name of the file.
match self.primary_span {
Some(span) => {
let lo = codemap.lookup_char_pos(span.lo);
output.push(RenderedLine {
text: vec![StyledString {
text: lo.file.name.clone(),
style: Style::FileNameStyle,
}, StyledString {
text: format!(":{}:{}", lo.line, lo.col.0 + 1),
style: Style::LineAndColumn,
}],
kind: RenderedLineKind::PrimaryFileName,
});
}
None => {
output.push(RenderedLine {
text: vec![StyledString {
text: self.file.name.clone(),
style: Style::FileNameStyle,
}],
kind: RenderedLineKind::OtherFileName,
});
if !old_school {
match self.primary_span {
Some(span) => {
let lo = codemap.lookup_char_pos(span.lo);
output.push(RenderedLine {
text: vec![StyledString {
text: lo.file.name.clone(),
style: Style::FileNameStyle,
}, StyledString {
text: format!(":{}:{}", lo.line, lo.col.0 + 1),
style: Style::LineAndColumn,
}],
kind: RenderedLineKind::PrimaryFileName,
});
}
None => {
output.push(RenderedLine {
text: vec![StyledString {
text: self.file.name.clone(),
style: Style::FileNameStyle,
}],
kind: RenderedLineKind::OtherFileName,
});
}
}
}
@ -466,7 +475,31 @@ impl FileInfo {
// Consume lines with annotations.
while let Some(line) = next_line {
if line.annotations.is_empty() { break; }
output.append(&mut self.render_line(line));
let mut rendered_line = self.render_line(line);
if old_school {
match self.primary_span {
Some(span) => {
let lo = codemap.lookup_char_pos(span.lo);
rendered_line[0].text.insert(0, StyledString {
text: format!(":{} ", lo.line),
style: Style::LineAndColumn,
});
rendered_line[0].text.insert(0, StyledString {
text: lo.file.name.clone(),
style: Style::FileNameStyle,
});
let gap_amount = rendered_line[0].text[0].text.len() +
rendered_line[0].text[1].text.len();
rendered_line[1].text.insert(0, StyledString {
text: vec![" "; gap_amount].join(""),
style: Style::NoStyle
});
}
_ =>()
}
}
output.append(&mut rendered_line);
next_line = lines_iter.next();
}
@ -492,6 +525,10 @@ impl FileInfo {
}
fn render_line(&self, line: &Line) -> Vec<RenderedLine> {
let old_school = match ::std::env::var("RUST_NEW_ERROR_FORMAT") {
Ok(_) => false,
Err(_) => true,
};
let source_string = self.file.get_line(line.line_index)
.unwrap_or("");
let source_kind = RenderedLineKind::SourceText {
@ -535,12 +572,34 @@ impl FileInfo {
// Next, create the highlight line.
for annotation in &annotations {
for p in annotation.start_col .. annotation.end_col {
if annotation.is_primary {
styled_buffer.putc(1, p, '^', Style::UnderlinePrimary);
styled_buffer.set_style(0, p, Style::UnderlinePrimary);
} else {
styled_buffer.putc(1, p, '-', Style::UnderlineSecondary);
if old_school {
for p in annotation.start_col .. annotation.end_col {
if p == annotation.start_col {
styled_buffer.putc(1, p, '^',
if annotation.is_primary {
Style::UnderlinePrimary
} else {
Style::UnderlineSecondary
});
}
else {
styled_buffer.putc(1, p, '~',
if annotation.is_primary {
Style::UnderlinePrimary
} else {
Style::UnderlineSecondary
});
}
}
}
else {
for p in annotation.start_col .. annotation.end_col {
if annotation.is_primary {
styled_buffer.putc(1, p, '^', Style::UnderlinePrimary);
styled_buffer.set_style(0, p, Style::UnderlinePrimary);
} else {
styled_buffer.putc(1, p, '-', Style::UnderlineSecondary);
}
}
}
}
@ -555,6 +614,9 @@ impl FileInfo {
if labeled_annotations.is_empty() {
return styled_buffer.render(source_kind);
}
if old_school {
return styled_buffer.render(source_kind);
}
// Now add the text labels. We try, when possible, to stick the rightmost
// annotation at the end of the highlight line:
@ -647,6 +709,14 @@ impl FileInfo {
}
fn prepend_prefixes(rendered_lines: &mut [RenderedLine]) {
let old_school = match ::std::env::var("RUST_NEW_ERROR_FORMAT") {
Ok(_) => false,
Err(_) => true,
};
if old_school {
return;
}
let prefixes: Vec<_> =
rendered_lines.iter()
.map(|rl| rl.kind.prefix())
@ -686,11 +756,14 @@ fn prepend_prefixes(rendered_lines: &mut [RenderedLine]) {
style: Style::LineNumber})
}
RenderedLineKind::OtherFileName => {
// >>>>> filename
// ::: filename
// 22 |>
// ^
// padding_len
let dashes = (0..padding_len + 2).map(|_| '>')
let dashes = (0..padding_len - 1).map(|_| ' ')
.chain(Some(':'))
.chain(Some(':'))
.chain(Some(':'))
.chain(Some(' '));
line.text.insert(0, StyledString {text: dashes.collect(),
style: Style::LineNumber})