diff --git a/src/libsyntax/errors/json.rs b/src/libsyntax/errors/json.rs index 5bb5f4757e013..212a54447a861 100644 --- a/src/libsyntax/errors/json.rs +++ b/src/libsyntax/errors/json.rs @@ -20,7 +20,7 @@ // FIXME spec the JSON output properly. -use codemap::{MultiSpan, CodeMap}; +use codemap::{Span, MultiSpan, CodeMap}; use diagnostics::registry::Registry; use errors::{Level, DiagnosticBuilder, SubDiagnostic, RenderSpan, CodeSuggestion}; use errors::emitter::Emitter; @@ -99,6 +99,16 @@ struct DiagnosticSpan { /// 1-based, character offset. column_start: usize, column_end: usize, + /// Source text from the start of line_start to the end of line_end. + text: Vec, +} + +#[derive(RustcEncodable)] +struct DiagnosticSpanLine { + text: String, + /// 1-based, character offset in self.text. + highlight_start: usize, + highlight_end: usize, } #[derive(RustcEncodable)] @@ -180,6 +190,7 @@ impl DiagnosticSpan { line_end: end.line, column_start: start.col.0 + 1, column_end: end.col.0 + 1, + text: DiagnosticSpanLine::from_span(span, je), } }).collect() } @@ -202,6 +213,7 @@ impl DiagnosticSpan { line_end: end.line, column_start: 0, column_end: end.col.0 + 1, + text: DiagnosticSpanLine::from_span(span, je), } }).collect() } @@ -217,6 +229,7 @@ impl DiagnosticSpan { line_end: end.line, column_start: 0, column_end: 0, + text: DiagnosticSpanLine::from_span(span, je), } }).collect() } @@ -224,6 +237,31 @@ impl DiagnosticSpan { } } +impl DiagnosticSpanLine { + fn from_span(span: &Span, je: &JsonEmitter) -> Vec { + let lines = match je.cm.span_to_lines(*span) { + Ok(lines) => lines, + Err(_) => { + debug!("unprintable span"); + return Vec::new(); + } + }; + + let mut result = Vec::new(); + let fm = &*lines.file; + + for line in &lines.lines { + result.push(DiagnosticSpanLine { + text: fm.get_line(line.line_index).unwrap().to_owned(), + highlight_start: line.start_col.0 + 1, + highlight_end: line.end_col.0 + 1, + }); + } + + result + } +} + impl DiagnosticCode { fn map_opt_string(s: Option, je: &JsonEmitter) -> Option { s.map(|s| { diff --git a/src/test/run-make/json-errors/Makefile b/src/test/run-make/json-errors/Makefile index bf97f12055550..cd3a2af30ab8f 100644 --- a/src/test/run-make/json-errors/Makefile +++ b/src/test/run-make/json-errors/Makefile @@ -6,5 +6,5 @@ all: cp foo.rs $(TMPDIR) cd $(TMPDIR) -$(RUSTC) -Z unstable-options --error-format=json foo.rs 2>$(LOG) - grep -q '{"message":"unresolved name `y`","code":{"code":"E0425","explanation":"\\nAn unresolved name was used. Example of erroneous codes.*"},"level":"error","spans":\[{"file_name":"foo.rs","byte_start":496,"byte_end":497,"line_start":12,"line_end":12,"column_start":18,"column_end":19}\],"children":\[\]}' $(LOG) - grep -q '{"message":".*","code":{"code":"E0277","explanation":"\\nYou tried.*"},"level":"error","spans":\[{.*}\],"children":\[{"message":"the .*","code":null,"level":"help","spans":\[{"file_name":"foo.rs","byte_start":504,"byte_end":516,"line_start":14,"line_end":14,"column_start":0,"column_end":0}\],"children":\[\]},{"message":" ","code":null,"level":"help",' $(LOG) + grep -q '{"message":"unresolved name `y`","code":{"code":"E0425","explanation":"\\nAn unresolved name was used. Example of erroneous codes.*"},"level":"error","spans":\[{"file_name":"foo.rs","byte_start":496,"byte_end":497,"line_start":12,"line_end":12,"column_start":18,"column_end":19,"text":\[{"text":" let x = 42 + y;","highlight_start":18,"highlight_end":19}\]}\],"children":\[\]}' $(LOG) + grep -q '{"message":".*","code":{"code":"E0277","explanation":"\\nYou tried.*"},"level":"error","spans":\[{.*}\],"children":\[{"message":"the .*","code":null,"level":"help","spans":\[{"file_name":"foo.rs","byte_start":504,"byte_end":516,"line_start":14,"line_end":14,"column_start":0,"column_end":0,"text":\[{.*}\]}\],"children":\[\]},{"message":" ","code":null,"level":"help",' $(LOG)