syntax: Refactor diagnostics to focus on Writers
This commit alters the diagnostic emission machinery to be focused around a Writer for emitting errors. This allows it to not hard-code emission of errors to stderr (useful for other applications).
This commit is contained in:
parent
9b1be3d182
commit
324547140e
5 changed files with 122 additions and 111 deletions
|
@ -931,7 +931,7 @@ pub fn build_session(sopts: @session::Options,
|
||||||
-> Session {
|
-> Session {
|
||||||
let codemap = @codemap::CodeMap::new();
|
let codemap = @codemap::CodeMap::new();
|
||||||
let diagnostic_handler =
|
let diagnostic_handler =
|
||||||
diagnostic::mk_handler();
|
diagnostic::default_handler();
|
||||||
let span_diagnostic_handler =
|
let span_diagnostic_handler =
|
||||||
diagnostic::mk_span_handler(diagnostic_handler, codemap);
|
diagnostic::mk_span_handler(diagnostic_handler, codemap);
|
||||||
|
|
||||||
|
@ -1149,7 +1149,8 @@ pub fn build_output_filenames(input: &Input,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn early_error(msg: &str) -> ! {
|
pub fn early_error(msg: &str) -> ! {
|
||||||
diagnostic::DefaultEmitter.emit(None, msg, diagnostic::Fatal);
|
let mut emitter = diagnostic::EmitterWriter::stderr();
|
||||||
|
emitter.emit(None, msg, diagnostic::Fatal);
|
||||||
fail!(diagnostic::FatalError);
|
fail!(diagnostic::FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -394,7 +394,8 @@ pub fn monitor(f: proc()) {
|
||||||
Err(value) => {
|
Err(value) => {
|
||||||
// Task failed without emitting a fatal diagnostic
|
// Task failed without emitting a fatal diagnostic
|
||||||
if !value.is::<diagnostic::FatalError>() {
|
if !value.is::<diagnostic::FatalError>() {
|
||||||
diagnostic::DefaultEmitter.emit(
|
let mut emitter = diagnostic::EmitterWriter::stderr();
|
||||||
|
emitter.emit(
|
||||||
None,
|
None,
|
||||||
diagnostic::ice_msg("unexpected failure"),
|
diagnostic::ice_msg("unexpected failure"),
|
||||||
diagnostic::Error);
|
diagnostic::Error);
|
||||||
|
@ -404,9 +405,7 @@ pub fn monitor(f: proc()) {
|
||||||
this is a bug",
|
this is a bug",
|
||||||
];
|
];
|
||||||
for note in xs.iter() {
|
for note in xs.iter() {
|
||||||
diagnostic::DefaultEmitter.emit(None,
|
emitter.emit(None, *note, diagnostic::Note)
|
||||||
*note,
|
|
||||||
diagnostic::Note)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("{}", r.read_to_str());
|
println!("{}", r.read_to_str());
|
||||||
|
|
|
@ -25,6 +25,7 @@ use rustc::metadata::creader::Loader;
|
||||||
use getopts;
|
use getopts;
|
||||||
use syntax::diagnostic;
|
use syntax::diagnostic;
|
||||||
use syntax::parse;
|
use syntax::parse;
|
||||||
|
use syntax::codemap::CodeMap;
|
||||||
|
|
||||||
use core;
|
use core;
|
||||||
use clean;
|
use clean;
|
||||||
|
@ -35,7 +36,6 @@ use passes;
|
||||||
use visit_ast::RustdocVisitor;
|
use visit_ast::RustdocVisitor;
|
||||||
|
|
||||||
pub fn run(input: &str, matches: &getopts::Matches) -> int {
|
pub fn run(input: &str, matches: &getopts::Matches) -> int {
|
||||||
let parsesess = parse::new_parse_sess();
|
|
||||||
let input_path = Path::new(input);
|
let input_path = Path::new(input);
|
||||||
let input = driver::FileInput(input_path.clone());
|
let input = driver::FileInput(input_path.clone());
|
||||||
let libs = matches.opt_strs("L").map(|s| Path::new(s.as_slice()));
|
let libs = matches.opt_strs("L").map(|s| Path::new(s.as_slice()));
|
||||||
|
@ -49,9 +49,12 @@ pub fn run(input: &str, matches: &getopts::Matches) -> int {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
let cm = @CodeMap::new();
|
||||||
let diagnostic_handler = diagnostic::mk_handler();
|
let diagnostic_handler = diagnostic::mk_handler();
|
||||||
let span_diagnostic_handler =
|
let span_diagnostic_handler =
|
||||||
diagnostic::mk_span_handler(diagnostic_handler, parsesess.cm);
|
diagnostic::mk_span_handler(diagnostic_handler, cm);
|
||||||
|
let parsesess = parse::new_parse_sess_special_handler(span_diagnostic_handler,
|
||||||
|
cm);
|
||||||
|
|
||||||
let sess = driver::build_session_(sessopts,
|
let sess = driver::build_session_(sessopts,
|
||||||
Some(input_path),
|
Some(input_path),
|
||||||
|
|
|
@ -11,12 +11,10 @@
|
||||||
use codemap::{Pos, Span};
|
use codemap::{Pos, Span};
|
||||||
use codemap;
|
use codemap;
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::{RefCell, Cell};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io::stdio::StdWriter;
|
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::iter::range;
|
use std::iter::range;
|
||||||
use std::local_data;
|
|
||||||
use term;
|
use term;
|
||||||
|
|
||||||
static BUG_REPORT_URL: &'static str =
|
static BUG_REPORT_URL: &'static str =
|
||||||
|
@ -25,9 +23,9 @@ static BUG_REPORT_URL: &'static str =
|
||||||
static MAX_LINES: uint = 6u;
|
static MAX_LINES: uint = 6u;
|
||||||
|
|
||||||
pub trait Emitter {
|
pub trait Emitter {
|
||||||
fn emit(&self, cmsp: Option<(&codemap::CodeMap, Span)>,
|
fn emit(&mut self, cmsp: Option<(&codemap::CodeMap, Span)>,
|
||||||
msg: &str, lvl: Level);
|
msg: &str, lvl: Level);
|
||||||
fn custom_emit(&self, cm: &codemap::CodeMap,
|
fn custom_emit(&mut self, cm: &codemap::CodeMap,
|
||||||
sp: Span, msg: &str, lvl: Level);
|
sp: Span, msg: &str, lvl: Level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,16 +76,16 @@ impl SpanHandler {
|
||||||
// others log errors for later reporting.
|
// others log errors for later reporting.
|
||||||
pub struct Handler {
|
pub struct Handler {
|
||||||
err_count: Cell<uint>,
|
err_count: Cell<uint>,
|
||||||
emit: DefaultEmitter,
|
emit: RefCell<~Emitter>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Handler {
|
impl Handler {
|
||||||
pub fn fatal(&self, msg: &str) -> ! {
|
pub fn fatal(&self, msg: &str) -> ! {
|
||||||
self.emit.emit(None, msg, Fatal);
|
self.emit.borrow_mut().get().emit(None, msg, Fatal);
|
||||||
fail!(FatalError);
|
fail!(FatalError);
|
||||||
}
|
}
|
||||||
pub fn err(&self, msg: &str) {
|
pub fn err(&self, msg: &str) {
|
||||||
self.emit.emit(None, msg, Error);
|
self.emit.borrow_mut().get().emit(None, msg, Error);
|
||||||
self.bump_err_count();
|
self.bump_err_count();
|
||||||
}
|
}
|
||||||
pub fn bump_err_count(&self) {
|
pub fn bump_err_count(&self) {
|
||||||
|
@ -112,10 +110,10 @@ impl Handler {
|
||||||
self.fatal(s);
|
self.fatal(s);
|
||||||
}
|
}
|
||||||
pub fn warn(&self, msg: &str) {
|
pub fn warn(&self, msg: &str) {
|
||||||
self.emit.emit(None, msg, Warning);
|
self.emit.borrow_mut().get().emit(None, msg, Warning);
|
||||||
}
|
}
|
||||||
pub fn note(&self, msg: &str) {
|
pub fn note(&self, msg: &str) {
|
||||||
self.emit.emit(None, msg, Note);
|
self.emit.borrow_mut().get().emit(None, msg, Note);
|
||||||
}
|
}
|
||||||
pub fn bug(&self, msg: &str) -> ! {
|
pub fn bug(&self, msg: &str) -> ! {
|
||||||
self.fatal(ice_msg(msg));
|
self.fatal(ice_msg(msg));
|
||||||
|
@ -127,11 +125,11 @@ impl Handler {
|
||||||
cmsp: Option<(&codemap::CodeMap, Span)>,
|
cmsp: Option<(&codemap::CodeMap, Span)>,
|
||||||
msg: &str,
|
msg: &str,
|
||||||
lvl: Level) {
|
lvl: Level) {
|
||||||
self.emit.emit(cmsp, msg, lvl);
|
self.emit.borrow_mut().get().emit(cmsp, msg, lvl);
|
||||||
}
|
}
|
||||||
pub fn custom_emit(&self, cm: &codemap::CodeMap,
|
pub fn custom_emit(&self, cm: &codemap::CodeMap,
|
||||||
sp: Span, msg: &str, lvl: Level) {
|
sp: Span, msg: &str, lvl: Level) {
|
||||||
self.emit.custom_emit(cm, sp, msg, lvl);
|
self.emit.borrow_mut().get().custom_emit(cm, sp, msg, lvl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,10 +146,14 @@ pub fn mk_span_handler(handler: @Handler, cm: @codemap::CodeMap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mk_handler() -> @Handler {
|
pub fn default_handler() -> @Handler {
|
||||||
|
mk_handler(~EmitterWriter::stderr())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mk_handler(e: ~Emitter) -> @Handler {
|
||||||
@Handler {
|
@Handler {
|
||||||
err_count: Cell::new(0),
|
err_count: Cell::new(0),
|
||||||
emit: DefaultEmitter,
|
emit: RefCell::new(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,73 +187,79 @@ impl Level {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_maybe_styled(msg: &str, color: term::attr::Attr) -> io::IoResult<()> {
|
fn print_maybe_styled(w: &mut EmitterWriter,
|
||||||
local_data_key!(tls_terminal: Option<term::Terminal<StdWriter>>)
|
msg: &str,
|
||||||
|
color: term::attr::Attr) -> io::IoResult<()> {
|
||||||
|
match w.dst {
|
||||||
fn is_stderr_screen() -> bool {
|
Terminal(ref mut t) => {
|
||||||
use std::libc;
|
try!(t.attr(color));
|
||||||
unsafe { libc::isatty(libc::STDERR_FILENO) != 0 }
|
try!(t.write_str(msg));
|
||||||
}
|
try!(t.reset());
|
||||||
fn write_pretty<T: Writer>(term: &mut term::Terminal<T>, s: &str,
|
|
||||||
c: term::attr::Attr) -> io::IoResult<()> {
|
|
||||||
try!(term.attr(c));
|
|
||||||
try!(term.write(s.as_bytes()));
|
|
||||||
try!(term.reset());
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Raw(ref mut w) => {
|
||||||
if is_stderr_screen() {
|
w.write_str(msg)
|
||||||
local_data::get_mut(tls_terminal, |term| {
|
|
||||||
match term {
|
|
||||||
Some(term) => {
|
|
||||||
match *term {
|
|
||||||
Some(ref mut term) => write_pretty(term, msg, color),
|
|
||||||
None => io::stderr().write(msg.as_bytes())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
|
||||||
let (t, ret) = match term::Terminal::new(io::stderr()) {
|
|
||||||
Ok(mut term) => {
|
|
||||||
let r = write_pretty(&mut term, msg, color);
|
|
||||||
(Some(term), r)
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
(None, io::stderr().write(msg.as_bytes()))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
local_data::set(tls_terminal, t);
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
io::stderr().write(msg.as_bytes())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_diagnostic(topic: &str, lvl: Level, msg: &str) -> io::IoResult<()> {
|
fn print_diagnostic(dst: &mut EmitterWriter,
|
||||||
|
topic: &str, lvl: Level, msg: &str) -> io::IoResult<()> {
|
||||||
if !topic.is_empty() {
|
if !topic.is_empty() {
|
||||||
let mut stderr = io::stderr();
|
try!(write!(&mut dst.dst, "{} ", topic));
|
||||||
try!(write!(&mut stderr as &mut io::Writer, "{} ", topic));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try!(print_maybe_styled(format!("{}: ", lvl.to_str()),
|
try!(print_maybe_styled(dst, format!("{}: ", lvl.to_str()),
|
||||||
term::attr::ForegroundColor(lvl.color())));
|
term::attr::ForegroundColor(lvl.color())));
|
||||||
try!(print_maybe_styled(format!("{}\n", msg), term::attr::Bold));
|
try!(print_maybe_styled(dst, format!("{}\n", msg), term::attr::Bold));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DefaultEmitter;
|
pub struct EmitterWriter {
|
||||||
|
priv dst: Destination,
|
||||||
|
}
|
||||||
|
|
||||||
impl Emitter for DefaultEmitter {
|
enum Destination {
|
||||||
fn emit(&self,
|
Terminal(term::Terminal<io::stdio::StdWriter>),
|
||||||
|
Raw(~Writer),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EmitterWriter {
|
||||||
|
pub fn stderr() -> EmitterWriter {
|
||||||
|
let stderr = io::stderr();
|
||||||
|
if stderr.isatty() {
|
||||||
|
let dst = match term::Terminal::new(stderr) {
|
||||||
|
Ok(t) => Terminal(t),
|
||||||
|
Err(..) => Raw(~io::stderr()),
|
||||||
|
};
|
||||||
|
EmitterWriter { dst: dst }
|
||||||
|
} else {
|
||||||
|
EmitterWriter { dst: Raw(~stderr) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(dst: ~Writer) -> EmitterWriter {
|
||||||
|
EmitterWriter { dst: Raw(dst) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Writer for Destination {
|
||||||
|
fn write(&mut self, bytes: &[u8]) -> io::IoResult<()> {
|
||||||
|
match *self {
|
||||||
|
Terminal(ref mut t) => t.write(bytes),
|
||||||
|
Raw(ref mut w) => w.write(bytes),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Emitter for EmitterWriter {
|
||||||
|
fn emit(&mut self,
|
||||||
cmsp: Option<(&codemap::CodeMap, Span)>,
|
cmsp: Option<(&codemap::CodeMap, Span)>,
|
||||||
msg: &str,
|
msg: &str,
|
||||||
lvl: Level) {
|
lvl: Level) {
|
||||||
let error = match cmsp {
|
let error = match cmsp {
|
||||||
Some((cm, sp)) => emit(cm, sp, msg, lvl, false),
|
Some((cm, sp)) => emit(self, cm, sp, msg, lvl, false),
|
||||||
None => print_diagnostic("", lvl, msg),
|
None => print_diagnostic(self, "", lvl, msg),
|
||||||
};
|
};
|
||||||
|
|
||||||
match error {
|
match error {
|
||||||
|
@ -260,16 +268,16 @@ impl Emitter for DefaultEmitter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn custom_emit(&self, cm: &codemap::CodeMap,
|
fn custom_emit(&mut self, cm: &codemap::CodeMap,
|
||||||
sp: Span, msg: &str, lvl: Level) {
|
sp: Span, msg: &str, lvl: Level) {
|
||||||
match emit(cm, sp, msg, lvl, true) {
|
match emit(self, cm, sp, msg, lvl, true) {
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
Err(e) => fail!("failed to print diagnostics: {}", e),
|
Err(e) => fail!("failed to print diagnostics: {}", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit(cm: &codemap::CodeMap, sp: Span,
|
fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, sp: Span,
|
||||||
msg: &str, lvl: Level, custom: bool) -> io::IoResult<()> {
|
msg: &str, lvl: Level, custom: bool) -> io::IoResult<()> {
|
||||||
let ss = cm.span_to_str(sp);
|
let ss = cm.span_to_str(sp);
|
||||||
let lines = cm.span_to_lines(sp);
|
let lines = cm.span_to_lines(sp);
|
||||||
|
@ -279,22 +287,21 @@ fn emit(cm: &codemap::CodeMap, sp: Span,
|
||||||
// the span)
|
// the span)
|
||||||
let span_end = Span { lo: sp.hi, hi: sp.hi, expn_info: sp.expn_info};
|
let span_end = Span { lo: sp.hi, hi: sp.hi, expn_info: sp.expn_info};
|
||||||
let ses = cm.span_to_str(span_end);
|
let ses = cm.span_to_str(span_end);
|
||||||
try!(print_diagnostic(ses, lvl, msg));
|
try!(print_diagnostic(dst, ses, lvl, msg));
|
||||||
try!(custom_highlight_lines(cm, sp, lvl, lines));
|
try!(custom_highlight_lines(dst, cm, sp, lvl, lines));
|
||||||
} else {
|
} else {
|
||||||
try!(print_diagnostic(ss, lvl, msg));
|
try!(print_diagnostic(dst, ss, lvl, msg));
|
||||||
try!(highlight_lines(cm, sp, lvl, lines));
|
try!(highlight_lines(dst, cm, sp, lvl, lines));
|
||||||
}
|
}
|
||||||
print_macro_backtrace(cm, sp)
|
print_macro_backtrace(dst, cm, sp)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn highlight_lines(cm: &codemap::CodeMap,
|
fn highlight_lines(err: &mut EmitterWriter,
|
||||||
|
cm: &codemap::CodeMap,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
lvl: Level,
|
lvl: Level,
|
||||||
lines: &codemap::FileLines) -> io::IoResult<()> {
|
lines: &codemap::FileLines) -> io::IoResult<()> {
|
||||||
let fm = lines.file;
|
let fm = lines.file;
|
||||||
let mut err = io::stderr();
|
|
||||||
let err = &mut err as &mut io::Writer;
|
|
||||||
|
|
||||||
let mut elided = false;
|
let mut elided = false;
|
||||||
let mut display_lines = lines.lines.as_slice();
|
let mut display_lines = lines.lines.as_slice();
|
||||||
|
@ -304,13 +311,13 @@ fn highlight_lines(cm: &codemap::CodeMap,
|
||||||
}
|
}
|
||||||
// Print the offending lines
|
// Print the offending lines
|
||||||
for line in display_lines.iter() {
|
for line in display_lines.iter() {
|
||||||
try!(write!(err, "{}:{} {}\n", fm.name, *line + 1,
|
try!(write!(&mut err.dst, "{}:{} {}\n", fm.name, *line + 1,
|
||||||
fm.get_line(*line as int)));
|
fm.get_line(*line as int)));
|
||||||
}
|
}
|
||||||
if elided {
|
if elided {
|
||||||
let last_line = display_lines[display_lines.len() - 1u];
|
let last_line = display_lines[display_lines.len() - 1u];
|
||||||
let s = format!("{}:{} ", fm.name, last_line + 1u);
|
let s = format!("{}:{} ", fm.name, last_line + 1u);
|
||||||
try!(write!(err, "{0:1$}...\n", "", s.len()));
|
try!(write!(&mut err.dst, "{0:1$}...\n", "", s.len()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME (#3260)
|
// FIXME (#3260)
|
||||||
|
@ -342,7 +349,7 @@ fn highlight_lines(cm: &codemap::CodeMap,
|
||||||
_ => s.push_char(' '),
|
_ => s.push_char(' '),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
try!(write!(err, "{}", s));
|
try!(write!(&mut err.dst, "{}", s));
|
||||||
let mut s = ~"^";
|
let mut s = ~"^";
|
||||||
let hi = cm.lookup_char_pos(sp.hi);
|
let hi = cm.lookup_char_pos(sp.hi);
|
||||||
if hi.col != lo.col {
|
if hi.col != lo.col {
|
||||||
|
@ -350,7 +357,7 @@ fn highlight_lines(cm: &codemap::CodeMap,
|
||||||
let num_squigglies = hi.col.to_uint()-lo.col.to_uint()-1u;
|
let num_squigglies = hi.col.to_uint()-lo.col.to_uint()-1u;
|
||||||
for _ in range(0, num_squigglies) { s.push_char('~'); }
|
for _ in range(0, num_squigglies) { s.push_char('~'); }
|
||||||
}
|
}
|
||||||
try!(print_maybe_styled(s + "\n",
|
try!(print_maybe_styled(err, s + "\n",
|
||||||
term::attr::ForegroundColor(lvl.color())));
|
term::attr::ForegroundColor(lvl.color())));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -362,25 +369,24 @@ fn highlight_lines(cm: &codemap::CodeMap,
|
||||||
// than 6 lines), `custom_highlight_lines` will print the first line, then
|
// than 6 lines), `custom_highlight_lines` will print the first line, then
|
||||||
// dot dot dot, then last line, whereas `highlight_lines` prints the first
|
// dot dot dot, then last line, whereas `highlight_lines` prints the first
|
||||||
// six lines.
|
// six lines.
|
||||||
fn custom_highlight_lines(cm: &codemap::CodeMap,
|
fn custom_highlight_lines(w: &mut EmitterWriter,
|
||||||
|
cm: &codemap::CodeMap,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
lvl: Level,
|
lvl: Level,
|
||||||
lines: &codemap::FileLines) -> io::IoResult<()> {
|
lines: &codemap::FileLines) -> io::IoResult<()> {
|
||||||
let fm = lines.file;
|
let fm = lines.file;
|
||||||
let mut err = io::stderr();
|
|
||||||
let err = &mut err as &mut io::Writer;
|
|
||||||
|
|
||||||
let lines = lines.lines.as_slice();
|
let lines = lines.lines.as_slice();
|
||||||
if lines.len() > MAX_LINES {
|
if lines.len() > MAX_LINES {
|
||||||
try!(write!(err, "{}:{} {}\n", fm.name,
|
try!(write!(&mut w.dst, "{}:{} {}\n", fm.name,
|
||||||
lines[0] + 1, fm.get_line(lines[0] as int)));
|
lines[0] + 1, fm.get_line(lines[0] as int)));
|
||||||
try!(write!(err, "...\n"));
|
try!(write!(&mut w.dst, "...\n"));
|
||||||
let last_line = lines[lines.len()-1];
|
let last_line = lines[lines.len()-1];
|
||||||
try!(write!(err, "{}:{} {}\n", fm.name,
|
try!(write!(&mut w.dst, "{}:{} {}\n", fm.name,
|
||||||
last_line + 1, fm.get_line(last_line as int)));
|
last_line + 1, fm.get_line(last_line as int)));
|
||||||
} else {
|
} else {
|
||||||
for line in lines.iter() {
|
for line in lines.iter() {
|
||||||
try!(write!(err, "{}:{} {}\n", fm.name,
|
try!(write!(&mut w.dst, "{}:{} {}\n", fm.name,
|
||||||
*line + 1, fm.get_line(*line as int)));
|
*line + 1, fm.get_line(*line as int)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -391,22 +397,24 @@ fn custom_highlight_lines(cm: &codemap::CodeMap,
|
||||||
let mut s = ~"";
|
let mut s = ~"";
|
||||||
for _ in range(0, skip) { s.push_char(' '); }
|
for _ in range(0, skip) { s.push_char(' '); }
|
||||||
s.push_char('^');
|
s.push_char('^');
|
||||||
print_maybe_styled(s + "\n", term::attr::ForegroundColor(lvl.color()))
|
print_maybe_styled(w, s + "\n", term::attr::ForegroundColor(lvl.color()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_macro_backtrace(cm: &codemap::CodeMap, sp: Span) -> io::IoResult<()> {
|
fn print_macro_backtrace(w: &mut EmitterWriter,
|
||||||
|
cm: &codemap::CodeMap,
|
||||||
|
sp: Span) -> io::IoResult<()> {
|
||||||
for ei in sp.expn_info.iter() {
|
for ei in sp.expn_info.iter() {
|
||||||
let ss = ei.callee.span.as_ref().map_or(~"", |span| cm.span_to_str(*span));
|
let ss = ei.callee.span.as_ref().map_or(~"", |span| cm.span_to_str(*span));
|
||||||
let (pre, post) = match ei.callee.format {
|
let (pre, post) = match ei.callee.format {
|
||||||
codemap::MacroAttribute => ("#[", "]"),
|
codemap::MacroAttribute => ("#[", "]"),
|
||||||
codemap::MacroBang => ("", "!")
|
codemap::MacroBang => ("", "!")
|
||||||
};
|
};
|
||||||
try!(print_diagnostic(ss, Note,
|
try!(print_diagnostic(w, ss, Note,
|
||||||
format!("in expansion of {}{}{}", pre,
|
format!("in expansion of {}{}{}", pre,
|
||||||
ei.callee.name, post)));
|
ei.callee.name, post)));
|
||||||
let ss = cm.span_to_str(ei.call_site);
|
let ss = cm.span_to_str(ei.call_site);
|
||||||
try!(print_diagnostic(ss, Note, "expansion site"));
|
try!(print_diagnostic(w, ss, Note, "expansion site"));
|
||||||
try!(print_macro_backtrace(cm, ei.call_site));
|
try!(print_macro_backtrace(w, cm, ei.call_site));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
use ast;
|
use ast;
|
||||||
use codemap::{Span, CodeMap, FileMap};
|
use codemap::{Span, CodeMap, FileMap};
|
||||||
use codemap;
|
use codemap;
|
||||||
use diagnostic::{SpanHandler, mk_span_handler, mk_handler};
|
use diagnostic::{SpanHandler, mk_span_handler, default_handler};
|
||||||
use parse::attr::ParserAttr;
|
use parse::attr::ParserAttr;
|
||||||
use parse::parser::Parser;
|
use parse::parser::Parser;
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ pub fn new_parse_sess() -> @ParseSess {
|
||||||
let cm = @CodeMap::new();
|
let cm = @CodeMap::new();
|
||||||
@ParseSess {
|
@ParseSess {
|
||||||
cm: cm,
|
cm: cm,
|
||||||
span_diagnostic: mk_span_handler(mk_handler(), cm),
|
span_diagnostic: mk_span_handler(default_handler(), cm),
|
||||||
included_mod_stack: RefCell::new(~[]),
|
included_mod_stack: RefCell::new(~[]),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue