Skip to content

Commit

Permalink
refactor to use new snippet code and model
Browse files Browse the repository at this point in the history
Major changes:
- Remove old snippet rendering code and use the new stuff.
- Introduce `span_label` method to add a label
- Remove EndSpan mode and replace with a fn to get the last
  character of a span.
- Stop using `Option<MultiSpan>` and just use an empty `MultiSpan`
- and probably a bunch of other stuff :)
  • Loading branch information
nikomatsakis committed May 2, 2016
1 parent 5b150cf commit 11dc974
Show file tree
Hide file tree
Showing 7 changed files with 357 additions and 744 deletions.
4 changes: 2 additions & 2 deletions src/librustc/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
}
config::ErrorOutputType::Json => Box::new(JsonEmitter::basic()),
};
emitter.emit(None, msg, None, errors::Level::Fatal);
emitter.emit(&MultiSpan::new(), msg, None, errors::Level::Fatal);
panic!(errors::FatalError);
}

Expand All @@ -578,7 +578,7 @@ pub fn early_warn(output: config::ErrorOutputType, msg: &str) {
}
config::ErrorOutputType::Json => Box::new(JsonEmitter::basic()),
};
emitter.emit(None, msg, None, errors::Level::Warning);
emitter.emit(&MultiSpan::new(), msg, None, errors::Level::Warning);
}

// Err(0) means compilation was stopped, but no errors were found.
Expand Down
16 changes: 9 additions & 7 deletions src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,9 @@ use std::thread;

use rustc::session::early_error;

use syntax::{ast, errors, diagnostics};
use syntax::codemap::{CodeMap, FileLoader, RealFileLoader};
use syntax::{ast, errors, diagnostic};
use syntax::codemap::MultiSpan;
use syntax::parse::{self, PResult};
use syntax::errors::emitter::Emitter;
use syntax::feature_gate::{GatedCfg, UnstableFeatures};
use syntax::parse::{self, PResult, token};
Expand Down Expand Up @@ -136,7 +137,8 @@ pub fn run(args: Vec<String>) -> isize {
None => {
let mut emitter =
errors::emitter::BasicEmitter::stderr(errors::ColorConfig::Auto);
emitter.emit(None, &abort_msg(err_count), None, errors::Level::Fatal);
emitter.emit(&MultiSpan::new(), &abort_msg(err_count), None,
errors::Level::Fatal);
exit_on_err();
}
}
Expand Down Expand Up @@ -379,7 +381,7 @@ fn check_cfg(sopts: &config::Options,
match item.node {
ast::MetaItemKind::List(ref pred, _) => {
saw_invalid_predicate = true;
emitter.emit(None,
emitter.emit(&MultiSpan::new(),
&format!("invalid predicate in --cfg command line argument: `{}`",
pred),
None,
Expand Down Expand Up @@ -1028,19 +1030,19 @@ pub fn monitor<F: FnOnce() + Send + 'static>(f: F) {
// a .span_bug or .bug call has already printed what
// it wants to print.
if !value.is::<errors::ExplicitBug>() {
emitter.emit(None, "unexpected panic", None, errors::Level::Bug);
emitter.emit(&MultiSpan::new(), "unexpected panic", None, errors::Level::Bug);
}

let xs = ["the compiler unexpectedly panicked. this is a bug.".to_string(),
format!("we would appreciate a bug report: {}", BUG_REPORT_URL)];
for note in &xs {
emitter.emit(None, &note[..], None, errors::Level::Note)
emitter.emit(&MultiSpan::new(), &note[..], None, errors::Level::Note)
}
if match env::var_os("RUST_BACKTRACE") {
Some(val) => &val != "0",
None => false,
} {
emitter.emit(None,
emitter.emit(&MultiSpan::new(),
"run with `RUST_BACKTRACE=1` for a backtrace",
None,
errors::Level::Note);
Expand Down
4 changes: 0 additions & 4 deletions src/librustc_driver/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,6 @@ impl Emitter for ExpectErrorEmitter {
lvl: Level) {
remove_message(self, msg, lvl);
}

fn custom_emit(&mut self, _sp: &RenderSpan, msg: &str, lvl: Level) {
remove_message(self, msg, lvl);
}
}

fn errors(msgs: &[&str]) -> (Box<Emitter + Send>, usize) {
Expand Down
19 changes: 11 additions & 8 deletions src/librustc_trans/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use llvm::SMDiagnosticRef;
use {CrateTranslation, ModuleTranslation};
use util::common::time;
use util::common::path2cstr;
use syntax::codemap;
use syntax::codemap::{self, MultiSpan};
use syntax::errors::{self, Handler, Level};
use syntax::errors::emitter::Emitter;

Expand Down Expand Up @@ -84,13 +84,13 @@ impl SharedEmitter {
for diag in &*buffer {
match diag.code {
Some(ref code) => {
handler.emit_with_code(None,
handler.emit_with_code(&MultiSpan::new(),
&diag.msg,
&code[..],
diag.lvl);
},
None => {
handler.emit(None,
handler.emit(&MultiSpan::new(),
&diag.msg,
diag.lvl);
},
Expand All @@ -101,9 +101,12 @@ impl SharedEmitter {
}

impl Emitter for SharedEmitter {
fn emit(&mut self, sp: Option<&codemap::MultiSpan>,
msg: &str, code: Option<&str>, lvl: Level) {
assert!(sp.is_none(), "SharedEmitter doesn't support spans");
fn emit(&mut self,
sp: &codemap::MultiSpan,
msg: &str,
code: Option<&str>,
lvl: Level) {
assert!(sp.primary_span().is_none(), "SharedEmitter doesn't support spans");

self.buffer.lock().unwrap().push(Diagnostic {
msg: msg.to_string(),
Expand All @@ -112,8 +115,8 @@ impl Emitter for SharedEmitter {
});
}

fn custom_emit(&mut self, _sp: &errors::RenderSpan, _msg: &str, _lvl: Level) {
bug!("SharedEmitter doesn't support custom_emit");
fn emit_struct(&mut self, _db: &errors::DiagnosticBuilder) {
bug!("SharedEmitter doesn't support emit_struct");
}
}

Expand Down
87 changes: 13 additions & 74 deletions src/libsyntax/codemap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,12 @@ pub const COMMAND_LINE_SP: Span = Span { lo: BytePos(0),
expn_id: COMMAND_LINE_EXPN };

impl Span {
/// Returns a new span representing just the end-point of this span
pub fn end_point(self) -> Span {
let lo = cmp::max(self.hi.0 - 1, self.lo.0);
Span { lo: BytePos(lo), hi: self.hi, expn_id: self.expn_id}
}

/// Returns `self` if `self` is not the dummy span, and `other` otherwise.
pub fn substitute_dummy(self, other: Span) -> Span {
if self.source_equal(&DUMMY_SP) { other } else { self }
Expand Down Expand Up @@ -794,7 +800,7 @@ impl CodeMap {
/// Creates a new filemap and sets its line information.
pub fn new_filemap_and_lines(&self, filename: &str, src: &str) -> Rc<FileMap> {
let fm = self.new_filemap(filename.to_string(), src.to_owned());
let mut byte_pos: u32 = 0;
let mut byte_pos: u32 = fm.start_pos.0;
for line in src.lines() {
// register the start of this line
fm.next_line(BytePos(byte_pos));
Expand Down Expand Up @@ -1126,7 +1132,9 @@ impl CodeMap {
// numbers in Loc are 1-based, so we subtract 1 to get 0-based
// lines.
for line_index in lo.line-1 .. hi.line-1 {
let line_len = lo.file.get_line(line_index).map(|s| s.len()).unwrap_or(0);
let line_len = lo.file.get_line(line_index)
.map(|s| s.chars().count())
.unwrap_or(0);
lines.push(LineInfo { line_index: line_index,
start_col: start_col,
end_col: CharPos::from_usize(line_len) });
Expand Down Expand Up @@ -1584,13 +1592,13 @@ mod tests {
assert_eq!(file_lines.lines[0].line_index, 1);
}

/// Given a string like " ^~~~~~~~~~~~ ", produces a span
/// Given a string like " ~~~~~~~~~~~~ ", produces a span
/// coverting that range. The idea is that the string has the same
/// length as the input, and we uncover the byte positions. Note
/// that this can span lines and so on.
fn span_from_selection(input: &str, selection: &str) -> Span {
assert_eq!(input.len(), selection.len());
let left_index = selection.find('^').unwrap() as u32;
let left_index = selection.find('~').unwrap() as u32;
let right_index = selection.rfind('~').map(|x|x as u32).unwrap_or(left_index);
Span { lo: BytePos(left_index), hi: BytePos(right_index + 1), expn_id: NO_EXPANSION }
}
Expand All @@ -1601,7 +1609,7 @@ mod tests {
fn span_to_snippet_and_lines_spanning_multiple_lines() {
let cm = CodeMap::new();
let inputtext = "aaaaa\nbbbbBB\nCCC\nDDDDDddddd\neee\n";
let selection = " \n ^~\n~~~\n~~~~~ \n \n";
let selection = " \n ~~\n~~~\n~~~~~ \n \n";
cm.new_filemap_and_lines("blork.rs", inputtext);
let span = span_from_selection(inputtext, selection);

Expand Down Expand Up @@ -1751,73 +1759,4 @@ r"blork2.rs:2:1: 2:12
";
assert_eq!(sstr, res_str);
}

#[test]
fn t13() {
// Test that collecting multiple spans into line-groups works correctly
let cm = CodeMap::new();
let inp = "_aaaaa__bbb\nvv\nw\nx\ny\nz\ncccccc__ddddee__";
let sp1 = " ^~~~~ \n \n \n \n \n \n ";
let sp2 = " \n \n \n \n \n^\n ";
let sp3 = " ^~~\n~~\n \n \n \n \n ";
let sp4 = " \n \n \n \n \n \n^~~~~~ ";
let sp5 = " \n \n \n \n \n \n ^~~~ ";
let sp6 = " \n \n \n \n \n \n ^~~~ ";
let sp_trim = " \n \n \n \n \n \n ^~ ";
let sp_merge = " \n \n \n \n \n \n ^~~~~~ ";
let sp7 = " \n ^\n \n \n \n \n ";
let sp8 = " \n \n^\n \n \n \n ";
let sp9 = " \n \n \n^\n \n \n ";
let sp10 = " \n \n \n \n^\n \n ";

let span = |sp, expected| {
let sp = span_from_selection(inp, sp);
assert_eq!(&cm.span_to_snippet(sp).unwrap(), expected);
sp
};

cm.new_filemap_and_lines("blork.rs", inp);
let sp1 = span(sp1, "aaaaa");
let sp2 = span(sp2, "z");
let sp3 = span(sp3, "bbb\nvv");
let sp4 = span(sp4, "cccccc");
let sp5 = span(sp5, "dddd");
let sp6 = span(sp6, "ddee");
let sp7 = span(sp7, "v");
let sp8 = span(sp8, "w");
let sp9 = span(sp9, "x");
let sp10 = span(sp10, "y");
let sp_trim = span(sp_trim, "ee");
let sp_merge = span(sp_merge, "ddddee");

let spans = vec![sp5, sp2, sp4, sp9, sp10, sp7, sp3, sp8, sp1, sp6];

macro_rules! check_next {
($groups: expr, $expected: expr) => ({
let actual = $groups.next().map(|g|&g.spans[..]);
let expected = $expected;
println!("actual:\n{:?}\n", actual);
println!("expected:\n{:?}\n", expected);
assert_eq!(actual, expected.as_ref().map(|x|&x[..]));
});
}

let _groups = cm.group_spans(spans.clone());
let it = &mut _groups.iter();

check_next!(it, Some([sp1, sp7, sp8, sp9, sp10, sp2]));
// New group because we're exceeding MAX_HIGHLIGHT_LINES
check_next!(it, Some([sp4, sp_merge]));
check_next!(it, Some([sp3]));
check_next!(it, None::<[Span; 0]>);

let _groups = cm.end_group_spans(spans);
let it = &mut _groups.iter();

check_next!(it, Some([sp1, sp7, sp8, sp9, sp10, sp2]));
// New group because we're exceeding MAX_HIGHLIGHT_LINES
check_next!(it, Some([sp4, sp5, sp_trim]));
check_next!(it, Some([sp3]));
check_next!(it, None::<[Span; 0]>);
}
}
Loading

0 comments on commit 11dc974

Please sign in to comment.