From 324547140e0b67b109b43dfa79cc39cdf06151e5 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 28 Feb 2014 11:37:04 -0800 Subject: 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). --- src/libsyntax/parse/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 9d0c9d0f4d3..2d1c327ec3d 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -14,7 +14,7 @@ use ast; use codemap::{Span, CodeMap, FileMap}; use codemap; -use diagnostic::{SpanHandler, mk_span_handler, mk_handler}; +use diagnostic::{SpanHandler, mk_span_handler, default_handler}; use parse::attr::ParserAttr; use parse::parser::Parser; @@ -49,7 +49,7 @@ pub fn new_parse_sess() -> @ParseSess { let cm = @CodeMap::new(); @ParseSess { cm: cm, - span_diagnostic: mk_span_handler(mk_handler(), cm), + span_diagnostic: mk_span_handler(default_handler(), cm), included_mod_stack: RefCell::new(~[]), } } -- cgit 1.4.1-3-g733a5 From 0e1a860789896fd2e6331648f1268c5b2cdb3573 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 28 Feb 2014 12:33:49 -0800 Subject: rustdoc: Capture all output from rustc by default This helps prevent interleaving of error messages when running rustdoc tests. This has an interesting bit of shuffling with I/O handles, but other than that this is just using the APIs laid out in the previous commit. Closes #12623 --- src/librustdoc/core.rs | 2 +- src/librustdoc/html/highlight.rs | 2 +- src/librustdoc/test.rs | 28 ++++++++++++++++++++++++++-- src/libsyntax/parse/lexer.rs | 6 +++++- 4 files changed, 33 insertions(+), 5 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index f4062195978..26650d22fe9 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -58,7 +58,7 @@ fn get_ast_and_resolve(cpath: &Path, }; - let diagnostic_handler = syntax::diagnostic::mk_handler(); + let diagnostic_handler = syntax::diagnostic::default_handler(); let span_diagnostic_handler = syntax::diagnostic::mk_span_handler(diagnostic_handler, parsesess.cm); diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 40b892cd9b4..8f90a39539a 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -28,7 +28,7 @@ use t = syntax::parse::token; /// Highlights some source code, returning the HTML output. pub fn highlight(src: &str) -> ~str { let sess = parse::new_parse_sess(); - let handler = diagnostic::mk_handler(); + let handler = diagnostic::default_handler(); let span_handler = diagnostic::mk_span_handler(handler, sess.cm); let fm = parse::string_to_filemap(sess, src.to_owned(), ~""); diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 179a848b7d0..f97dd98e457 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -50,7 +50,7 @@ pub fn run(input: &str, matches: &getopts::Matches) -> int { let cm = @CodeMap::new(); - let diagnostic_handler = diagnostic::mk_handler(); + let diagnostic_handler = diagnostic::default_handler(); let span_diagnostic_handler = diagnostic::mk_span_handler(diagnostic_handler, cm); let parsesess = parse::new_parse_sess_special_handler(span_diagnostic_handler, @@ -115,7 +115,30 @@ fn runtest(test: &str, cratename: &str, libs: HashSet, should_fail: bool) .. (*session::basic_options()).clone() }; - let diagnostic_handler = diagnostic::mk_handler(); + // Shuffle around a few input and output handles here. We're going to pass + // an explicit handle into rustc to collect output messages, but we also + // want to catch the error message that rustc prints when it fails. + // + // We take our task-local stderr (likely set by the test runner), and move + // it into another task. This helper task then acts as a sink for both the + // stderr of this task and stderr of rustc itself, copying all the info onto + // the stderr channel we originally started with. + // + // The basic idea is to not use a default_handler() for rustc, and then also + // not print things by default to the actual stderr. + let (p, c) = Chan::new(); + let w1 = io::ChanWriter::new(c); + let w2 = w1.clone(); + let old = io::stdio::set_stderr(~w1); + spawn(proc() { + let mut p = io::PortReader::new(p); + let mut err = old.unwrap_or(~io::stderr() as ~Writer); + io::util::copy(&mut p, &mut err).unwrap(); + }); + let emitter = diagnostic::EmitterWriter::new(~w2); + + // Compile the code + let diagnostic_handler = diagnostic::mk_handler(~emitter); let span_diagnostic_handler = diagnostic::mk_span_handler(diagnostic_handler, parsesess.cm); @@ -129,6 +152,7 @@ fn runtest(test: &str, cratename: &str, libs: HashSet, should_fail: bool) let cfg = driver::build_configuration(sess); driver::compile_input(sess, cfg, &input, &out, &None); + // Run the code! let exe = outdir.path().join("rust_out"); let out = Process::output(exe.as_str().unwrap(), []); match out { diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index 5bace75a5ea..344aab63d5b 100644 --- a/src/libsyntax/parse/lexer.rs +++ b/src/libsyntax/parse/lexer.rs @@ -1004,6 +1004,7 @@ mod test { use diagnostic; use parse::token; use parse::token::{str_to_ident}; + use std::io::util; // represents a testing reader (incl. both reader and interner) struct Env { @@ -1014,7 +1015,10 @@ mod test { fn setup(teststr: ~str) -> Env { let cm = CodeMap::new(); let fm = cm.new_filemap(~"zebra.rs", teststr); - let span_handler = diagnostic::mk_span_handler(diagnostic::mk_handler(), @cm); + let writer = ~util::NullWriter; + let emitter = diagnostic::EmitterWriter::new(writer); + let handler = diagnostic::mk_handler(~emitter); + let span_handler = diagnostic::mk_span_handler(handler, @cm); Env { string_reader: new_string_reader(span_handler,fm) } -- cgit 1.4.1-3-g733a5