Skip to content

Commit

Permalink
Add back in old school mode
Browse files Browse the repository at this point in the history
  • Loading branch information
Jonathan Turner committed Jul 14, 2016
1 parent 71ec286 commit 8612838
Showing 1 changed file with 265 additions and 26 deletions.
291 changes: 265 additions & 26 deletions src/librustc_errors/emitter.rs
Expand Up @@ -34,31 +34,14 @@ pub trait Emitter {

impl Emitter for EmitterWriter {
fn emit(&mut self, db: &DiagnosticBuilder) {
if check_old_skool() {
self.emit_message(&FullSpan(db.span.clone()),
&db.message,
db.code.as_ref().map(|s| &**s),
db.level,
true,
true);
let db_span = FullSpan(db.span.clone());

for child in &db.children {
let render_span = child.render_span
.clone()
.unwrap_or_else(
|| FullSpan(child.span.clone()));
let (render_span, show_snippet) = match render_span.span().primary_span() {
None => (db_span.clone(), false),
_ => (render_span, true)
};
self.emit_message(&render_span,
&child.message,
None,
child.level,
false,
show_snippet);
}
let old_school = match self.format_mode {
FormatMode::NewErrorFormat => false,
FormatMode::OriginalErrorFormat => true,
FormatMode::EnvironmentSelected => check_old_skool()
};

if old_school {
self.emit_messages_old_school(db);
} else {
self.emit_messages_default(db);
}
Expand Down Expand Up @@ -718,6 +701,239 @@ impl EmitterWriter {
}
write!(&mut self.dst, "\n");
}
fn emit_message_old_school(&mut self,
msp: &MultiSpan,
msg: &str,
code: &Option<String>,
level: &Level,
show_snippet: bool)
-> io::Result<()> {
let mut buffer = StyledBuffer::new();

let loc = match msp.primary_span() {
Some(COMMAND_LINE_SP) | Some(DUMMY_SP) => "".to_string(),
Some(ps) => if let Some(ref cm) = self.cm {
cm.span_to_string(ps)
} else {
"".to_string()
},
None => {
"".to_string()
}
};
if loc != "" {
buffer.append(0, &loc, Style::NoStyle);
buffer.append(0, " ", Style::NoStyle);
}
buffer.append(0, &level.to_string(), Style::Level(level.clone()));
buffer.append(0, ": ", Style::HeaderMsg);
buffer.append(0, msg, Style::HeaderMsg);
buffer.append(0, " ", Style::NoStyle);
match code {
&Some(ref code) => {
buffer.append(0, "[", Style::ErrorCode);
buffer.append(0, &code, Style::ErrorCode);
buffer.append(0, "]", Style::ErrorCode);
}
_ => {}
}

if !show_snippet {
emit_to_destination(&buffer.render(), level, &mut self.dst);
return Ok(());
}

// Watch out for various nasty special spans; don't try to
// print any filename or anything for those.
match msp.primary_span() {
Some(COMMAND_LINE_SP) | Some(DUMMY_SP) => {
emit_to_destination(&buffer.render(), level, &mut self.dst);
return Ok(());
}
_ => { }
}

let mut annotated_files = self.preprocess_annotations(msp);

if let (Some(ref cm), Some(ann_file), Some(ref primary_span)) =
(self.cm.as_ref(), annotated_files.first(), msp.primary_span().as_ref()) {

// Next, print the source line and its squiggle
// for old school mode, we will render them to the buffer, then insert the file loc
// (or space the same amount) in front of the line and the squiggle
let source_string = ann_file.file.get_line(ann_file.lines[0].line_index - 1)
.unwrap_or("");

let line_offset = buffer.num_lines();

let lo = cm.lookup_char_pos(primary_span.lo);
//Before each secondary line in old skool-mode, print the label
//as an old-style note
let file_pos = format!("{}:{} ", lo.file.name.clone(), lo.line);
let file_pos_len = file_pos.len();

// First create the source line we will highlight.
buffer.puts(line_offset, 0, &file_pos, Style::FileNameStyle);
buffer.puts(line_offset, file_pos_len, &source_string, Style::Quotation);
// Sort the annotations by (start, end col)
let mut annotations = ann_file.lines[0].annotations.clone();

// Next, create the highlight line.
for annotation in &annotations {
for p in annotation.start_col..annotation.end_col {
if p == annotation.start_col {
buffer.putc(line_offset + 1,
file_pos_len + p,
'^',
if annotation.is_primary {
Style::UnderlinePrimary
} else {
Style::OldSchoolNote
});
} else {
buffer.putc(line_offset + 1,
file_pos_len + p,
'~',
if annotation.is_primary {
Style::UnderlinePrimary
} else {
Style::OldSchoolNote
});
}
}
}
}
if let Some(ref primary_span) = msp.primary_span().as_ref() {
self.render_macro_backtrace_old_school(primary_span, &mut buffer)?;
}

match code {
&Some(ref code) if self.registry.as_ref()
.and_then(|registry| registry.find_description(code))
.is_some() => {
let msg = "run `rustc --explain ".to_string() + &code.to_string() +
"` to see a detailed explanation";

let line_offset = buffer.num_lines();
buffer.append(line_offset, &loc, Style::NoStyle);
buffer.append(line_offset, " ", Style::NoStyle);
buffer.append(line_offset, &Level::Help.to_string(), Style::Level(Level::Help));
buffer.append(line_offset, ": ", Style::HeaderMsg);
buffer.append(line_offset, &msg, Style::HeaderMsg);
}
_ => ()
}

// final step: take our styled buffer, render it, then output it
emit_to_destination(&buffer.render(), level, &mut self.dst);
Ok(())
}
fn emit_suggestion_old_school(&mut self,
suggestion: &CodeSuggestion,
level: &Level,
msg: &str)
-> io::Result<()> {
use std::borrow::Borrow;

let primary_span = suggestion.msp.primary_span().unwrap();
if let Some(ref cm) = self.cm {
let mut buffer = StyledBuffer::new();

let loc = cm.span_to_string(primary_span);

if loc != "" {
buffer.append(0, &loc, Style::NoStyle);
buffer.append(0, " ", Style::NoStyle);
}

buffer.append(0, &level.to_string(), Style::Level(level.clone()));
buffer.append(0, ": ", Style::HeaderMsg);
buffer.append(0, msg, Style::HeaderMsg);

let lines = cm.span_to_lines(primary_span).unwrap();

assert!(!lines.lines.is_empty());

let complete = suggestion.splice_lines(cm.borrow());
let line_count = cmp::min(lines.lines.len(), MAX_HIGHLIGHT_LINES);
let display_lines = &lines.lines[..line_count];

let fm = &*lines.file;
// Calculate the widest number to format evenly
let max_digits = line_num_max_digits(display_lines.last().unwrap());

// print the suggestion without any line numbers, but leave
// space for them. This helps with lining up with previous
// snippets from the actual error being reported.
let mut lines = complete.lines();
let mut row_num = 1;
for line in lines.by_ref().take(MAX_HIGHLIGHT_LINES) {
buffer.append(row_num, &fm.name, Style::FileNameStyle);
for i in 0..max_digits+2 {
buffer.append(row_num, &" ", Style::NoStyle);
}
buffer.append(row_num, line, Style::NoStyle);
row_num += 1;
}

// if we elided some lines, add an ellipsis
if let Some(_) = lines.next() {
buffer.append(row_num, "...", Style::NoStyle);
}
emit_to_destination(&buffer.render(), level, &mut self.dst);
}
Ok(())
}

fn emit_messages_old_school(&mut self, db: &DiagnosticBuilder) {
match self.emit_message_old_school(&db.span,
&db.message,
&db.code,
&db.level,
true) {
Ok(()) => {
for child in &db.children {
let (span, show_snippet) = if child.span.primary_spans().is_empty() {
(db.span.clone(), false)
} else {
(child.span.clone(), true)
};

match child.render_span {
Some(FullSpan(ref msp)) => {
match self.emit_message_old_school(&span,
&child.message,
&None,
&child.level,
show_snippet) {
Err(e) => panic!("failed to emit error: {}", e),
_ => ()
}
},
Some(Suggestion(ref cs)) => {
match self.emit_suggestion_old_school(cs,
&child.level,
&child.message) {
Err(e) => panic!("failed to emit error: {}", e),
_ => ()
}
},
None => {
match self.emit_message_old_school(&span,
&child.message,
&None,
&child.level,
show_snippet) {
Err(e) => panic!("failed to emit error: {}", e),
_ => ()
}
}
}
}
}
Err(e) => panic!("failed to emit error: {}", e)
}
}

fn emit_message_(&mut self,
rsp: &RenderSpan,
Expand Down Expand Up @@ -948,6 +1164,29 @@ impl EmitterWriter {
Ok(())
}

fn render_macro_backtrace_old_school(&mut self,
sp: &Span,
buffer: &mut StyledBuffer) -> io::Result<()> {
if let Some(ref cm) = self.cm {
for trace in cm.macro_backtrace(sp.clone()) {
let line_offset = buffer.num_lines();

let mut diag_string =
format!("in this expansion of {}", trace.macro_decl_name);
if let Some(def_site_span) = trace.def_site_span {
diag_string.push_str(
&format!(" (defined in {})",
cm.span_to_filename(def_site_span)));
}
let snippet = cm.span_to_string(trace.call_site);
buffer.append(line_offset, &format!("{} ", snippet), Style::NoStyle);
buffer.append(line_offset, "Note", Style::Level(Level::Note));
buffer.append(line_offset, ": ", Style::NoStyle);
buffer.append(line_offset, &diag_string, Style::OldSchoolNoteText);
}
}
Ok(())
}
fn print_macro_backtrace(&mut self,
sp: Span)
-> io::Result<()> {
Expand Down Expand Up @@ -1087,7 +1326,7 @@ impl Destination {
}
Style::ErrorCode => {
try!(self.start_attr(term::Attr::Bold));
//try!(self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_MAGENTA)));
try!(self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_MAGENTA)));
}
Style::Quotation => {}
Style::OldSchoolNote => {
Expand Down

0 comments on commit 8612838

Please sign in to comment.