about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-01-13 16:05:58 -0800
committerBrian Anderson <banderson@mozilla.com>2012-01-13 16:06:56 -0800
commitced0aa13d385df40f21dcb8471326b2a6b08ba0f (patch)
tree05158b52a4a724704fbfc998eed34b5fc34ac7c5
parentbb1e8d2339cfb360c845b7435e97b4f5eb241991 (diff)
downloadrust-ced0aa13d385df40f21dcb8471326b2a6b08ba0f.tar.gz
rust-ced0aa13d385df40f21dcb8471326b2a6b08ba0f.zip
rustc: Extract driver::diagnostic from syntax::codemap
-rw-r--r--src/comp/driver/diagnostic.rs137
-rw-r--r--src/comp/driver/driver.rs2
-rw-r--r--src/comp/driver/session.rs16
-rw-r--r--src/comp/rustc.rc1
-rw-r--r--src/comp/syntax/codemap.rs132
-rw-r--r--src/comp/syntax/parse/lexer.rs3
-rw-r--r--src/comp/syntax/parse/parser.rs9
7 files changed, 154 insertions, 146 deletions
diff --git a/src/comp/driver/diagnostic.rs b/src/comp/driver/diagnostic.rs
new file mode 100644
index 00000000000..5a425eb8429
--- /dev/null
+++ b/src/comp/driver/diagnostic.rs
@@ -0,0 +1,137 @@
+import std::{io, term};
+import io::writer_util;
+import syntax::codemap;
+import codemap::span;
+
+export diagnostictype, warning, error, note;
+export print_diagnostic, emit_warning, emit_error, emit_note;
+
+tag diagnostictype {
+    warning;
+    error;
+    note;
+}
+
+fn diagnosticstr(t: diagnostictype) -> str {
+    alt t {
+      warning. { "warning" }
+      error. { "error" }
+      note. { "note" }
+    }
+}
+
+fn diagnosticcolor(t: diagnostictype) -> u8 {
+    alt t {
+      warning. { term::color_bright_yellow }
+      error. { term::color_bright_red }
+      note. { term::color_bright_green }
+    }
+}
+
+fn print_diagnostic(topic: str, t: diagnostictype, msg: str) {
+    if str::is_not_empty(topic) {
+        io::stdout().write_str(#fmt["%s ", topic]);
+    }
+    if term::color_supported() {
+        term::fg(io::stdout(), diagnosticcolor(t));
+    }
+    io::stdout().write_str(#fmt["%s:", diagnosticstr(t)]);
+    if term::color_supported() {
+        term::reset(io::stdout());
+    }
+    io::stdout().write_str(#fmt[" %s\n", msg]);
+}
+
+fn emit_diagnostic(cmsp: option<(codemap::codemap, span)>,
+                   msg: str, t: diagnostictype) {
+    alt cmsp {
+      some((cm, sp)) {
+        let ss = codemap::span_to_str(sp, cm);
+        let lines = codemap::span_to_lines(sp, cm);
+        print_diagnostic(ss, t, msg);
+        highlight_lines(cm, sp, lines);
+      }
+      none. {
+        print_diagnostic("", t, msg);
+      }
+    }
+}
+
+fn highlight_lines(cm: codemap::codemap, sp: span,
+                   lines: @codemap::file_lines) {
+
+    // If we're not looking at a real file then we can't re-open it to
+    // pull out the lines
+    if lines.name == "-" { ret; }
+
+    // FIXME: reading in the entire file is the worst possible way to
+    //        get access to the necessary lines.
+    let file = alt io::read_whole_file_str(lines.name) {
+      result::ok(file) { file }
+      result::err(e) {
+        emit_error(none, e);
+        fail;
+      }
+    };
+    let fm = codemap::get_filemap(cm, lines.name);
+
+    // arbitrarily only print up to six lines of the error
+    let max_lines = 6u;
+    let elided = false;
+    let display_lines = lines.lines;
+    if vec::len(display_lines) > max_lines {
+        display_lines = vec::slice(display_lines, 0u, max_lines);
+        elided = true;
+    }
+    // Print the offending lines
+    for line: uint in display_lines {
+        io::stdout().write_str(#fmt["%s:%u ", fm.name, line + 1u]);
+        let s = codemap::get_line(fm, line as int, file);
+        if !str::ends_with(s, "\n") { s += "\n"; }
+        io::stdout().write_str(s);
+    }
+    if elided {
+        let last_line = display_lines[vec::len(display_lines) - 1u];
+        let s = #fmt["%s:%u ", fm.name, last_line + 1u];
+        let indent = str::char_len(s);
+        let out = "";
+        while indent > 0u { out += " "; indent -= 1u; }
+        out += "...\n";
+        io::stdout().write_str(out);
+    }
+
+
+    // If there's one line at fault we can easily point to the problem
+    if vec::len(lines.lines) == 1u {
+        let lo = codemap::lookup_char_pos(cm, sp.lo);
+        let digits = 0u;
+        let num = (lines.lines[0] + 1u) / 10u;
+
+        // how many digits must be indent past?
+        while num > 0u { num /= 10u; digits += 1u; }
+
+        // indent past |name:## | and the 0-offset column location
+        let left = str::char_len(fm.name) + digits + lo.col + 3u;
+        let s = "";
+        while left > 0u { str::push_char(s, ' '); left -= 1u; }
+
+        s += "^";
+        let hi = codemap::lookup_char_pos(cm, sp.hi);
+        if hi.col != lo.col {
+            // the ^ already takes up one space
+            let width = hi.col - lo.col - 1u;
+            while width > 0u { str::push_char(s, '~'); width -= 1u; }
+        }
+        io::stdout().write_str(s + "\n");
+    }
+}
+
+fn emit_warning(cmsp: option<(codemap::codemap, span)>, msg: str) {
+    emit_diagnostic(cmsp, msg, warning);
+}
+fn emit_error(cmsp: option<(codemap::codemap, span)>, msg: str) {
+    emit_diagnostic(cmsp, msg, error);
+}
+fn emit_note(cmsp: option<(codemap::codemap, span)>, msg: str) {
+    emit_diagnostic(cmsp, msg, note);
+}
diff --git a/src/comp/driver/driver.rs b/src/comp/driver/driver.rs
index 8d33e83cb58..a2963e7bd91 100644
--- a/src/comp/driver/driver.rs
+++ b/src/comp/driver/driver.rs
@@ -580,7 +580,7 @@ fn build_output_filenames(ifile: str,
 }
 
 fn early_error(msg: str) -> ! {
-    codemap::print_diagnostic("", codemap::error, msg);
+    diagnostic::print_diagnostic("", diagnostic::error, msg);
     fail;
 }
 
diff --git a/src/comp/driver/session.rs b/src/comp/driver/session.rs
index 479fd97083c..fc8bc444e20 100644
--- a/src/comp/driver/session.rs
+++ b/src/comp/driver/session.rs
@@ -65,19 +65,19 @@ type session = @{targ_cfg: @config,
 
 impl session for session {
     fn span_fatal(sp: span, msg: str) -> ! {
-        codemap::emit_error(some((self.parse_sess.cm, sp)), msg);
+        diagnostic::emit_error(some((self.parse_sess.cm, sp)), msg);
         fail;
     }
     fn fatal(msg: str) -> ! {
-        codemap::emit_error(none, msg);
+        diagnostic::emit_error(none, msg);
         fail;
     }
     fn span_err(sp: span, msg: str) {
-        codemap::emit_error(some((self.parse_sess.cm, sp)), msg);
+        diagnostic::emit_error(some((self.parse_sess.cm, sp)), msg);
         self.err_count += 1u;
     }
     fn err(msg: str) {
-        codemap::emit_error(none, msg);
+        diagnostic::emit_error(none, msg);
         self.err_count += 1u;
     }
     fn has_errors() -> bool { self.err_count > 0u }
@@ -87,16 +87,16 @@ impl session for session {
         }
     }
     fn span_warn(sp: span, msg: str) {
-        codemap::emit_warning(some((self.parse_sess.cm, sp)), msg);
+        diagnostic::emit_warning(some((self.parse_sess.cm, sp)), msg);
     }
     fn warn(msg: str) {
-        codemap::emit_warning(none, msg);
+        diagnostic::emit_warning(none, msg);
     }
     fn span_note(sp: span, msg: str) {
-        codemap::emit_note(some((self.parse_sess.cm, sp)), msg);
+        diagnostic::emit_note(some((self.parse_sess.cm, sp)), msg);
     }
     fn note(msg: str) {
-        codemap::emit_note(none, msg);
+        diagnostic::emit_note(none, msg);
     }
     fn span_bug(sp: span, msg: str) -> ! {
         self.span_fatal(sp, #fmt["internal compiler error %s", msg]);
diff --git a/src/comp/rustc.rc b/src/comp/rustc.rc
index bc28ea0480a..f688be64374 100644
--- a/src/comp/rustc.rc
+++ b/src/comp/rustc.rc
@@ -123,6 +123,7 @@ mod metadata {
 mod driver {
     mod driver;
     mod session;
+    mod diagnostic;
 }
 
 mod util {
diff --git a/src/comp/syntax/codemap.rs b/src/comp/syntax/codemap.rs
index fc575d1c149..da5e9d13d8d 100644
--- a/src/comp/syntax/codemap.rs
+++ b/src/comp/syntax/codemap.rs
@@ -1,6 +1,4 @@
 import core::{vec, uint, str, option, result};
-import std::{term, io};
-import io::writer_util;
 import option::{some, none};
 
 type filename = str;
@@ -100,136 +98,6 @@ fn span_to_str(sp: span, cm: codemap) -> str {
     ret res;
 }
 
-tag diagnostictype {
-    warning;
-    error;
-    note;
-}
-
-fn diagnosticstr(t: diagnostictype) -> str {
-    alt t {
-      warning. { "warning" }
-      error. { "error" }
-      note. { "note" }
-    }
-}
-
-fn diagnosticcolor(t: diagnostictype) -> u8 {
-    alt t {
-      warning. { term::color_bright_yellow }
-      error. { term::color_bright_red }
-      note. { term::color_bright_green }
-    }
-}
-
-fn print_diagnostic(topic: str, t: diagnostictype, msg: str) {
-    if str::is_not_empty(topic) {
-        io::stdout().write_str(#fmt["%s ", topic]);
-    }
-    if term::color_supported() {
-        term::fg(io::stdout(), diagnosticcolor(t));
-    }
-    io::stdout().write_str(#fmt["%s:", diagnosticstr(t)]);
-    if term::color_supported() {
-        term::reset(io::stdout());
-    }
-    io::stdout().write_str(#fmt[" %s\n", msg]);
-}
-
-fn emit_diagnostic(cmsp: option<(codemap, span)>, msg: str,
-                   t: diagnostictype) {
-    alt cmsp {
-      some((cm, sp)) {
-        let ss = span_to_str(sp, cm);
-        let lines = span_to_lines(sp, cm);
-        print_diagnostic(ss, t, msg);
-        highlight_lines(cm, sp, lines);
-      }
-      none. {
-        print_diagnostic("", t, msg);
-      }
-    }
-}
-
-fn highlight_lines(cm: codemap, sp: span,
-                   lines: @file_lines) {
-
-    // If we're not looking at a real file then we can't re-open it to
-    // pull out the lines
-    if lines.name == "-" { ret; }
-
-    // FIXME: reading in the entire file is the worst possible way to
-    //        get access to the necessary lines.
-    let file = alt io::read_whole_file_str(lines.name) {
-      result::ok(file) { file }
-      result::err(e) {
-        emit_error(none, e);
-        fail;
-      }
-    };
-    let fm = get_filemap(cm, lines.name);
-
-    // arbitrarily only print up to six lines of the error
-    let max_lines = 6u;
-    let elided = false;
-    let display_lines = lines.lines;
-    if vec::len(display_lines) > max_lines {
-        display_lines = vec::slice(display_lines, 0u, max_lines);
-        elided = true;
-    }
-    // Print the offending lines
-    for line: uint in display_lines {
-        io::stdout().write_str(#fmt["%s:%u ", fm.name, line + 1u]);
-        let s = get_line(fm, line as int, file);
-        if !str::ends_with(s, "\n") { s += "\n"; }
-        io::stdout().write_str(s);
-    }
-    if elided {
-        let last_line = display_lines[vec::len(display_lines) - 1u];
-        let s = #fmt["%s:%u ", fm.name, last_line + 1u];
-        let indent = str::char_len(s);
-        let out = "";
-        while indent > 0u { out += " "; indent -= 1u; }
-        out += "...\n";
-        io::stdout().write_str(out);
-    }
-
-
-    // If there's one line at fault we can easily point to the problem
-    if vec::len(lines.lines) == 1u {
-        let lo = lookup_char_pos(cm, sp.lo);
-        let digits = 0u;
-        let num = (lines.lines[0] + 1u) / 10u;
-
-        // how many digits must be indent past?
-        while num > 0u { num /= 10u; digits += 1u; }
-
-        // indent past |name:## | and the 0-offset column location
-        let left = str::char_len(fm.name) + digits + lo.col + 3u;
-        let s = "";
-        while left > 0u { str::push_char(s, ' '); left -= 1u; }
-
-        s += "^";
-        let hi = lookup_char_pos(cm, sp.hi);
-        if hi.col != lo.col {
-            // the ^ already takes up one space
-            let width = hi.col - lo.col - 1u;
-            while width > 0u { str::push_char(s, '~'); width -= 1u; }
-        }
-        io::stdout().write_str(s + "\n");
-    }
-}
-
-fn emit_warning(cmsp: option<(codemap, span)>, msg: str) {
-    emit_diagnostic(cmsp, msg, warning);
-}
-fn emit_error(cmsp: option<(codemap, span)>, msg: str) {
-    emit_diagnostic(cmsp, msg, error);
-}
-fn emit_note(cmsp: option<(codemap, span)>, msg: str) {
-    emit_diagnostic(cmsp, msg, note);
-}
-
 type file_lines = {name: str, lines: [uint]};
 
 fn span_to_lines(sp: span, cm: codemap::codemap) -> @file_lines {
diff --git a/src/comp/syntax/parse/lexer.rs b/src/comp/syntax/parse/lexer.rs
index cb247e12a40..cc0850d88b0 100644
--- a/src/comp/syntax/parse/lexer.rs
+++ b/src/comp/syntax/parse/lexer.rs
@@ -6,6 +6,7 @@ import option::{some, none};
 import util::interner;
 import util::interner::intern;
 import codemap;
+import driver::diagnostic;
 
 type reader = @{
     cm: codemap::codemap,
@@ -47,7 +48,7 @@ impl reader for reader {
         } else { self.curr = -1 as char; }
     }
     fn err(m: str) {
-        codemap::emit_error(
+        diagnostic::emit_error(
             some((self.cm, ast_util::mk_sp(self.chpos, self.chpos))), m);
     }
 }
diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs
index ad8eb0d5175..097ac8e7162 100644
--- a/src/comp/syntax/parse/parser.rs
+++ b/src/comp/syntax/parse/parser.rs
@@ -10,6 +10,7 @@ import util::interner;
 import ast::{node_id, spanned};
 import front::attr;
 import lexer::reader;
+import driver::diagnostic;
 
 tag restriction {
     UNRESTRICTED;
@@ -71,11 +72,11 @@ impl parser for parser {
         self.span_fatal(self.span, m);
     }
     fn span_fatal(sp: span, m: str) -> ! {
-        codemap::emit_error(some((self.sess.cm, sp)), m);
+        diagnostic::emit_error(some((self.sess.cm, sp)), m);
         fail;
     }
     fn warn(m: str) {
-        codemap::emit_warning(some((self.sess.cm, self.span)), m);
+        diagnostic::emit_warning(some((self.sess.cm, self.span)), m);
     }
     fn get_str(i: token::str_num) -> str {
         interner::get(*self.reader.interner, i)
@@ -92,7 +93,7 @@ fn new_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg, path: str,
         src
       }
       result::err(e) {
-        codemap::emit_error(none, e);
+        diagnostic::emit_error(none, e);
         fail;
       }
     };
@@ -2525,7 +2526,7 @@ fn parse_crate_from_file(input: str, cfg: ast::crate_cfg, sess: parse_sess) ->
     } else if str::ends_with(input, ".rs") {
         parse_crate_from_source_file(input, cfg, sess)
     } else {
-        codemap::emit_error(none, "unknown input file type: " + input);
+        diagnostic::emit_error(none, "unknown input file type: " + input);
         fail
     }
 }