use {Level, RenderSpan, CodeSuggestion, DiagnosticBuilder, CodeMapper};
use RenderSpan::*;
use Level::*;
-use snippet::{RenderedLineKind, SnippetData, Style};
+use snippet::{RenderedLineKind, SnippetData, Style, FormatMode};
use std::{cmp, fmt};
use std::io::prelude::*;
first: bool,
// For now, allow an old-school mode while we transition
- old_school: bool,
+ format_mode: FormatMode
}
impl CoreEmitter for EmitterWriter {
impl EmitterWriter {
pub fn stderr(color_config: ColorConfig,
registry: Option<registry::Registry>,
- code_map: Rc<CodeMapper>)
+ code_map: Rc<CodeMapper>,
+ format_mode: FormatMode)
-> EmitterWriter {
- let old_school = check_old_skool();
if color_config.use_color() {
let dst = Destination::from_stderr();
EmitterWriter { dst: dst,
registry: registry,
cm: code_map,
first: true,
- old_school: old_school }
+ format_mode: format_mode.clone() }
} else {
EmitterWriter { dst: Raw(Box::new(io::stderr())),
registry: registry,
cm: code_map,
first: true,
- old_school: old_school }
+ format_mode: format_mode.clone() }
}
}
pub fn new(dst: Box<Write + Send>,
registry: Option<registry::Registry>,
- code_map: Rc<CodeMapper>)
+ code_map: Rc<CodeMapper>,
+ format_mode: FormatMode)
-> EmitterWriter {
- let old_school = check_old_skool();
EmitterWriter { dst: Raw(dst),
registry: registry,
cm: code_map,
first: true,
- old_school: old_school }
+ format_mode: format_mode.clone() }
}
fn emit_message_(&mut self,
is_header: bool,
show_snippet: bool)
-> io::Result<()> {
+ let old_school = match self.format_mode {
+ FormatMode::NewErrorFormat => false,
+ FormatMode::OriginalErrorFormat => true,
+ FormatMode::EnvironmentSelected => check_old_skool()
+ };
+
if is_header {
if self.first {
self.first = false;
} else {
- if !self.old_school {
+ if !old_school {
write!(self.dst, "\n")?;
}
}
.and_then(|registry| registry.find_description(code))
.is_some() => {
let code_with_explain = String::from("--explain ") + code;
- if self.old_school {
+ if 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),
}
}
_ => {
- if self.old_school {
+ if 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),
}
}
}
- if self.old_school {
+ if old_school {
match code {
Some(code) if self.registry.as_ref()
.and_then(|registry| registry.find_description(code))
lvl: Level)
-> io::Result<()>
{
+ let old_school = match self.format_mode {
+ FormatMode::NewErrorFormat => false,
+ FormatMode::OriginalErrorFormat => true,
+ FormatMode::EnvironmentSelected => check_old_skool()
+ };
+
let mut snippet_data = SnippetData::new(self.cm.clone(),
- msp.primary_span());
- if self.old_school {
+ msp.primary_span(),
+ self.format_mode.clone());
+ if old_school {
let mut output_vec = vec![];
for span_label in msp.span_labels() {
let mut snippet_data = SnippetData::new(self.cm.clone(),
- Some(span_label.span));
+ Some(span_label.span),
+ self.format_mode.clone());
snippet_data.push(span_label.span,
span_label.is_primary,
use std::rc::Rc;
use std::mem;
+#[derive(Clone)]
+pub enum FormatMode {
+ NewErrorFormat,
+ OriginalErrorFormat,
+ EnvironmentSelected
+}
+
#[derive(Clone)]
pub struct SnippetData {
codemap: Rc<CodeMapper>,
files: Vec<FileInfo>,
+ format_mode: FormatMode,
}
#[derive(Clone)]
primary_span: Option<Span>,
lines: Vec<Line>,
+
+ /// The type of error format to render. We keep it here so that
+ /// it's easy to configure for both tests and regular usage
+ format_mode: FormatMode,
}
#[derive(Clone, Debug)]
impl SnippetData {
pub fn new(codemap: Rc<CodeMapper>,
- primary_span: Option<Span>) // (*)
+ primary_span: Option<Span>,
+ format_mode: FormatMode) // (*)
-> Self {
// (*) The primary span indicates the file that must appear
// first, and which will have a line number etc in its
let mut data = SnippetData {
codemap: codemap.clone(),
- files: vec![]
+ files: vec![],
+ format_mode: format_mode.clone()
};
if let Some(primary_span) = primary_span {
let lo = codemap.lookup_char_pos(primary_span.lo);
file: lo.file,
primary_span: Some(primary_span),
lines: vec![],
+ format_mode: format_mode.clone(),
});
}
data
file: file_map.clone(),
lines: vec![],
primary_span: None,
+ format_mode: self.format_mode.clone()
});
self.files.last_mut().unwrap()
}
self.files.iter()
.flat_map(|f| f.render_file_lines(&self.codemap))
.collect();
- prepend_prefixes(&mut rendered_lines);
+ prepend_prefixes(&mut rendered_lines, &self.format_mode);
trim_lines(&mut rendered_lines);
rendered_lines
}
}
fn render_file_lines(&self, codemap: &Rc<CodeMapper>) -> Vec<RenderedLine> {
- let old_school = check_old_skool();
+ let old_school = match self.format_mode {
+ FormatMode::OriginalErrorFormat => true,
+ FormatMode::NewErrorFormat => false,
+ FormatMode::EnvironmentSelected => check_old_skool()
+ };
// As a first step, we elide any instance of more than one
// continuous unannotated line.
}
fn render_line(&self, line: &Line) -> Vec<RenderedLine> {
- let old_school = check_old_skool();
+ let old_school = match self.format_mode {
+ FormatMode::OriginalErrorFormat => true,
+ FormatMode::NewErrorFormat => false,
+ FormatMode::EnvironmentSelected => check_old_skool()
+ };
+
let source_string = self.file.get_line(line.line_index)
.unwrap_or("");
let source_kind = RenderedLineKind::SourceText {
}
}
-fn prepend_prefixes(rendered_lines: &mut [RenderedLine]) {
- let old_school = check_old_skool();
+fn prepend_prefixes(rendered_lines: &mut [RenderedLine], format_mode: &FormatMode) {
+ let old_school = match *format_mode {
+ FormatMode::OriginalErrorFormat => true,
+ FormatMode::NewErrorFormat => false,
+ FormatMode::EnvironmentSelected => check_old_skool()
+ };
if old_school {
return;
}
use syntax_pos::*;
use errors::{Level, CodeSuggestion};
use errors::emitter::EmitterWriter;
- use errors::snippet::{SnippetData, RenderedLine};
+ use errors::snippet::{SnippetData, RenderedLine, FormatMode};
use std::sync::{Arc, Mutex};
use std::io::{self, Write};
use std::str::from_utf8;
fn test_hilight_suggestion_issue_11715() {
let data = Arc::new(Mutex::new(Vec::new()));
let cm = Rc::new(CodeMap::new());
- let mut ew = EmitterWriter::new(Box::new(Sink(data.clone())), None, cm.clone());
+ let mut ew = EmitterWriter::new(Box::new(Sink(data.clone())),
+ None,
+ cm.clone(),
+ FormatMode::NewErrorFormat);
let content = "abcdefg
koksi
line3
fn test_multispan_highlight() {
let data = Arc::new(Mutex::new(Vec::new()));
let cm = Rc::new(CodeMap::new());
- let mut diag = EmitterWriter::new(Box::new(Sink(data.clone())), None, cm.clone());
+ let mut diag = EmitterWriter::new(Box::new(Sink(data.clone())),
+ None,
+ cm.clone(),
+ FormatMode::NewErrorFormat);
let inp = "_____aaaaaa____bbbbbb__cccccdd_";
let sp1 = " ~~~~~~ ";
fn test_huge_multispan_highlight() {
let data = Arc::new(Mutex::new(Vec::new()));
let cm = Rc::new(CodeMap::new());
- let mut diag = EmitterWriter::new(Box::new(Sink(data.clone())), None, cm.clone());
+ let mut diag = EmitterWriter::new(Box::new(Sink(data.clone())),
+ None,
+ cm.clone(),
+ FormatMode::NewErrorFormat);
let inp = "aaaaa\n\
aaaaa\n\
let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
let span_bar = cm.span_substr(&foo, file_text, "bar", 0);
- let mut snippet = SnippetData::new(cm, Some(span_bar));
+ let mut snippet = SnippetData::new(cm, Some(span_bar), FormatMode::NewErrorFormat);
snippet.push(span_bar, true, None);
let lines = snippet.render_lines();
let span_vec1 = cm.span_substr(&foo, file_text, "vec", 1);
let span_semi = cm.span_substr(&foo, file_text, ";", 0);
- let mut snippet = SnippetData::new(cm, None);
+ let mut snippet = SnippetData::new(cm, None, FormatMode::NewErrorFormat);
snippet.push(span_vec0, false, Some(format!("previous borrow of `vec` occurs here")));
snippet.push(span_vec1, false, Some(format!("error occurs here")));
snippet.push(span_semi, false, Some(format!("previous borrow ends here")));
let span_bar_vec1 = cm.span_substr(&bar_map, file_text_bar, "vec", 1);
let span_bar_semi = cm.span_substr(&bar_map, file_text_bar, ";", 0);
- let mut snippet = SnippetData::new(cm, Some(span_foo_vec1));
+ let mut snippet = SnippetData::new(cm, Some(span_foo_vec1), FormatMode::NewErrorFormat);
snippet.push(span_foo_vec0, false, Some(format!("a")));
snippet.push(span_foo_vec1, true, Some(format!("b")));
snippet.push(span_foo_semi, false, Some(format!("c")));
let span_data1 = cm.span_substr(&foo, file_text, "data", 1);
let span_rbrace = cm.span_substr(&foo, file_text, "}", 3);
- let mut snippet = SnippetData::new(cm, None);
+ let mut snippet = SnippetData::new(cm, None, FormatMode::NewErrorFormat);
snippet.push(span_data0, false, Some(format!("immutable borrow begins here")));
snippet.push(span_data1, false, Some(format!("mutable borrow occurs here")));
snippet.push(span_rbrace, false, Some(format!("immutable borrow ends here")));
let span2 = cm.span_substr(&foo, file_text, "ec.push", 0);
let span3 = cm.span_substr(&foo, file_text, "unwrap", 0);
- let mut snippet = SnippetData::new(cm, None);
+ let mut snippet = SnippetData::new(cm, None, FormatMode::NewErrorFormat);
snippet.push(span0, false, Some(format!("A")));
snippet.push(span1, false, Some(format!("B")));
snippet.push(span2, false, Some(format!("C")));
let span_semi = cm.span_substr(&foo, file_text, ";", 0);
// intentionally don't push the snippets left to right
- let mut snippet = SnippetData::new(cm, None);
+ let mut snippet = SnippetData::new(cm, None, FormatMode::NewErrorFormat);
snippet.push(span_vec1, false, Some(format!("error occurs here")));
snippet.push(span_vec0, false, Some(format!("previous borrow of `vec` occurs here")));
snippet.push(span_semi, false, Some(format!("previous borrow ends here")));
let span_vec0 = cm.span_substr(&foo, file_text, "vec", 3);
let span_vec1 = cm.span_substr(&foo, file_text, "vec", 8);
- let mut snippet = SnippetData::new(cm, None);
+ let mut snippet = SnippetData::new(cm, None, FormatMode::NewErrorFormat);
snippet.push(span_vec0, false, Some(format!("`vec` moved here because it \
has type `collections::vec::Vec<i32>`")));
snippet.push(span_vec1, false, Some(format!("use of moved value: `vec`")));
let cm = Rc::new(CodeMap::new());
let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
- let mut snippet = SnippetData::new(cm.clone(), None);
+ let mut snippet = SnippetData::new(cm.clone(), None, FormatMode::NewErrorFormat);
for i in 0..4 {
let span_veci = cm.span_substr(&foo, file_text, "vec", i);
snippet.push(span_veci, false, None);
let cm = Rc::new(CodeMap::new());
let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
- let mut snippet = SnippetData::new(cm.clone(), None);
+ let mut snippet = SnippetData::new(cm.clone(), None, FormatMode::NewErrorFormat);
let fn_span = cm.span_substr(&foo, file_text, "fn", 0);
let rbrace_span = cm.span_substr(&foo, file_text, "}", 0);
snippet.push(splice(fn_span, rbrace_span), false, None);
let cm = Rc::new(CodeMap::new());
let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
- let mut snippet = SnippetData::new(cm.clone(), None);
+ let mut snippet = SnippetData::new(cm.clone(), None, FormatMode::NewErrorFormat);
let fn_span = cm.span_substr(&foo, file_text, "fn foo(x: u32)", 0);
let x_span = cm.span_substr(&foo, file_text, "x", 0);
snippet.push(fn_span, false, Some(format!("fn_span")));
let cm = Rc::new(CodeMap::new());
let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
- let mut snippet = SnippetData::new(cm.clone(), None);
+ let mut snippet = SnippetData::new(cm.clone(), None, FormatMode::NewErrorFormat);
let fn_span = cm.span_substr(&foo, file_text, "fn foo(x", 0);
let x_span = cm.span_substr(&foo, file_text, "x: u32)", 0);
snippet.push(fn_span, false, Some(format!("fn_span")));
let cm = Rc::new(CodeMap::new());
let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
- let mut snippet = SnippetData::new(cm.clone(), None);
+ let mut snippet = SnippetData::new(cm.clone(), None, FormatMode::NewErrorFormat);
let closure_span = {
let closure_start_span = cm.span_substr(&foo, file_text, "||", 0);
let mut rbrace_span = cm.span_substr(&foo, file_text, "}", 1);
rbrace_span.lo = rbrace_span.hi;
- let mut snippet = SnippetData::new(cm.clone(), Some(rbrace_span));
+ let mut snippet = SnippetData::new(cm.clone(),
+ Some(rbrace_span),
+ FormatMode::NewErrorFormat);
snippet.push(rbrace_span, false, None);
let lines = snippet.render_lines();
let text: String = make_string(&lines);