Skip to content

Pretty print json in ui tests #45737

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Nov 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 61 additions & 55 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ impl OutputType {
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ErrorOutputType {
HumanReadable(ColorConfig),
Json,
Json(bool),
Short(ColorConfig),
}

Expand Down Expand Up @@ -1433,7 +1433,8 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
let error_format = if matches.opts_present(&["error-format".to_owned()]) {
match matches.opt_str("error-format").as_ref().map(|s| &s[..]) {
Some("human") => ErrorOutputType::HumanReadable(color),
Some("json") => ErrorOutputType::Json,
Some("json") => ErrorOutputType::Json(false),
Some("pretty-json") => ErrorOutputType::Json(true),
Some("short") => ErrorOutputType::Short(color),

None => ErrorOutputType::HumanReadable(color),
Expand Down Expand Up @@ -1474,6 +1475,11 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)

let debugging_opts = build_debugging_options(matches, error_format);

if !debugging_opts.unstable_options && error_format == ErrorOutputType::Json(true) {
early_error(ErrorOutputType::Json(false),
"--error-format=pretty-json is unstable");
}

let mut output_types = BTreeMap::new();
if !debugging_opts.parse_only {
for list in matches.opt_strs("emit") {
Expand Down Expand Up @@ -2254,46 +2260,46 @@ mod tests {
let mut v5 = super::basic_options();

// Reference
v1.search_paths.add_path("native=abc", super::ErrorOutputType::Json);
v1.search_paths.add_path("crate=def", super::ErrorOutputType::Json);
v1.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json);
v1.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json);
v1.search_paths.add_path("all=mno", super::ErrorOutputType::Json);
v1.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false));
v1.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false));
v1.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false));
v1.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false));
v1.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false));

// Native changed
v2.search_paths.add_path("native=XXX", super::ErrorOutputType::Json);
v2.search_paths.add_path("crate=def", super::ErrorOutputType::Json);
v2.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json);
v2.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json);
v2.search_paths.add_path("all=mno", super::ErrorOutputType::Json);
v2.search_paths.add_path("native=XXX", super::ErrorOutputType::Json(false));
v2.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false));
v2.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false));
v2.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false));
v2.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false));

// Crate changed
v2.search_paths.add_path("native=abc", super::ErrorOutputType::Json);
v2.search_paths.add_path("crate=XXX", super::ErrorOutputType::Json);
v2.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json);
v2.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json);
v2.search_paths.add_path("all=mno", super::ErrorOutputType::Json);
v2.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false));
v2.search_paths.add_path("crate=XXX", super::ErrorOutputType::Json(false));
v2.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false));
v2.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false));
v2.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false));

// Dependency changed
v3.search_paths.add_path("native=abc", super::ErrorOutputType::Json);
v3.search_paths.add_path("crate=def", super::ErrorOutputType::Json);
v3.search_paths.add_path("dependency=XXX", super::ErrorOutputType::Json);
v3.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json);
v3.search_paths.add_path("all=mno", super::ErrorOutputType::Json);
v3.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false));
v3.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false));
v3.search_paths.add_path("dependency=XXX", super::ErrorOutputType::Json(false));
v3.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false));
v3.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false));

// Framework changed
v4.search_paths.add_path("native=abc", super::ErrorOutputType::Json);
v4.search_paths.add_path("crate=def", super::ErrorOutputType::Json);
v4.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json);
v4.search_paths.add_path("framework=XXX", super::ErrorOutputType::Json);
v4.search_paths.add_path("all=mno", super::ErrorOutputType::Json);
v4.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false));
v4.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false));
v4.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false));
v4.search_paths.add_path("framework=XXX", super::ErrorOutputType::Json(false));
v4.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false));

// All changed
v5.search_paths.add_path("native=abc", super::ErrorOutputType::Json);
v5.search_paths.add_path("crate=def", super::ErrorOutputType::Json);
v5.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json);
v5.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json);
v5.search_paths.add_path("all=XXX", super::ErrorOutputType::Json);
v5.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false));
v5.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false));
v5.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false));
v5.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false));
v5.search_paths.add_path("all=XXX", super::ErrorOutputType::Json(false));

assert!(v1.dep_tracking_hash() != v2.dep_tracking_hash());
assert!(v1.dep_tracking_hash() != v3.dep_tracking_hash());
Expand All @@ -2316,29 +2322,29 @@ mod tests {
let mut v4 = super::basic_options();

// Reference
v1.search_paths.add_path("native=abc", super::ErrorOutputType::Json);
v1.search_paths.add_path("crate=def", super::ErrorOutputType::Json);
v1.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json);
v1.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json);
v1.search_paths.add_path("all=mno", super::ErrorOutputType::Json);

v2.search_paths.add_path("native=abc", super::ErrorOutputType::Json);
v2.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json);
v2.search_paths.add_path("crate=def", super::ErrorOutputType::Json);
v2.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json);
v2.search_paths.add_path("all=mno", super::ErrorOutputType::Json);

v3.search_paths.add_path("crate=def", super::ErrorOutputType::Json);
v3.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json);
v3.search_paths.add_path("native=abc", super::ErrorOutputType::Json);
v3.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json);
v3.search_paths.add_path("all=mno", super::ErrorOutputType::Json);

v4.search_paths.add_path("all=mno", super::ErrorOutputType::Json);
v4.search_paths.add_path("native=abc", super::ErrorOutputType::Json);
v4.search_paths.add_path("crate=def", super::ErrorOutputType::Json);
v4.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json);
v4.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json);
v1.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false));
v1.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false));
v1.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false));
v1.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false));
v1.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false));

v2.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false));
v2.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false));
v2.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false));
v2.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false));
v2.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false));

v3.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false));
v3.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false));
v3.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false));
v3.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false));
v3.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false));

v4.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false));
v4.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false));
v4.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false));
v4.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false));
v4.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false));

assert!(v1.dep_tracking_hash() == v2.dep_tracking_hash());
assert!(v1.dep_tracking_hash() == v3.dep_tracking_hash());
Expand Down
14 changes: 7 additions & 7 deletions src/librustc/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ impl Session {
match self.opts.error_format {
// when outputting JSON for tool consumption, the tool might want
// the duplicates
config::ErrorOutputType::Json => {
config::ErrorOutputType::Json(_) => {
do_method()
},
_ => {
Expand Down Expand Up @@ -736,11 +736,11 @@ pub fn build_session_with_codemap(sopts: config::Options,
(config::ErrorOutputType::HumanReadable(_), Some(dst)) => {
Box::new(EmitterWriter::new(dst, Some(codemap.clone()), false))
}
(config::ErrorOutputType::Json, None) => {
Box::new(JsonEmitter::stderr(Some(registry), codemap.clone()))
(config::ErrorOutputType::Json(pretty), None) => {
Box::new(JsonEmitter::stderr(Some(registry), codemap.clone(), pretty))
}
(config::ErrorOutputType::Json, Some(dst)) => {
Box::new(JsonEmitter::new(dst, Some(registry), codemap.clone()))
(config::ErrorOutputType::Json(pretty), Some(dst)) => {
Box::new(JsonEmitter::new(dst, Some(registry), codemap.clone(), pretty))
}
(config::ErrorOutputType::Short(color_config), None) => {
Box::new(EmitterWriter::stderr(color_config, Some(codemap.clone()), true))
Expand Down Expand Up @@ -918,7 +918,7 @@ pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
config::ErrorOutputType::HumanReadable(color_config) => {
Box::new(EmitterWriter::stderr(color_config, None, false))
}
config::ErrorOutputType::Json => Box::new(JsonEmitter::basic()),
config::ErrorOutputType::Json(pretty) => Box::new(JsonEmitter::basic(pretty)),
config::ErrorOutputType::Short(color_config) => {
Box::new(EmitterWriter::stderr(color_config, None, true))
}
Expand All @@ -933,7 +933,7 @@ pub fn early_warn(output: config::ErrorOutputType, msg: &str) {
config::ErrorOutputType::HumanReadable(color_config) => {
Box::new(EmitterWriter::stderr(color_config, None, false))
}
config::ErrorOutputType::Json => Box::new(JsonEmitter::basic()),
config::ErrorOutputType::Json(pretty) => Box::new(JsonEmitter::basic(pretty)),
config::ErrorOutputType::Short(color_config) => {
Box::new(EmitterWriter::stderr(color_config, None, true))
}
Expand Down
30 changes: 18 additions & 12 deletions src/libsyntax/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,44 +30,54 @@ use std::rc::Rc;
use std::io::{self, Write};
use std::vec;

use rustc_serialize::json::as_json;
use rustc_serialize::json::{as_json, as_pretty_json};

pub struct JsonEmitter {
dst: Box<Write + Send>,
registry: Option<Registry>,
cm: Rc<CodeMapper + 'static>,
pretty: bool,
}

impl JsonEmitter {
pub fn stderr(registry: Option<Registry>,
code_map: Rc<CodeMap>) -> JsonEmitter {
code_map: Rc<CodeMap>,
pretty: bool) -> JsonEmitter {
JsonEmitter {
dst: Box::new(io::stderr()),
registry,
cm: code_map,
pretty,
}
}

pub fn basic() -> JsonEmitter {
pub fn basic(pretty: bool) -> JsonEmitter {
let file_path_mapping = FilePathMapping::empty();
JsonEmitter::stderr(None, Rc::new(CodeMap::new(file_path_mapping)))
JsonEmitter::stderr(None, Rc::new(CodeMap::new(file_path_mapping)), pretty)
}

pub fn new(dst: Box<Write + Send>,
registry: Option<Registry>,
code_map: Rc<CodeMap>) -> JsonEmitter {
code_map: Rc<CodeMap>,
pretty: bool) -> JsonEmitter {
JsonEmitter {
dst,
registry,
cm: code_map,
pretty,
}
}
}

impl Emitter for JsonEmitter {
fn emit(&mut self, db: &DiagnosticBuilder) {
let data = Diagnostic::from_diagnostic_builder(db, self);
if let Err(e) = writeln!(&mut self.dst, "{}", as_json(&data)) {
let result = if self.pretty {
writeln!(&mut self.dst, "{}", as_pretty_json(&data))
} else {
writeln!(&mut self.dst, "{}", as_json(&data))
};
if let Err(e) = result {
panic!("failed to print diagnostics: {:?}", e);
}
}
Expand All @@ -85,9 +95,7 @@ struct Diagnostic {
spans: Vec<DiagnosticSpan>,
/// Associated diagnostic messages.
children: Vec<Diagnostic>,
/// The message as rustc would render it. Currently this is only
/// `Some` for "suggestions", but eventually it will include all
/// snippets.
/// The message as rustc would render it. Currently this is always `None`
rendered: Option<String>,
}

Expand All @@ -110,9 +118,7 @@ struct DiagnosticSpan {
/// Label that should be placed at this location (if any)
label: Option<String>,
/// If we are suggesting a replacement, this will contain text
/// that should be sliced in atop this span. You may prefer to
/// load the fully rendered version from the parent `Diagnostic`,
/// however.
/// that should be sliced in atop this span.
suggested_replacement: Option<String>,
/// Macro invocations that created the code at this span, if any.
expansion: Option<Box<DiagnosticSpanMacroExpansion>>,
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/lint/unused_parens_json_suggestion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: --error-format json
// compile-flags: --error-format pretty-json -Zunstable-options

// The output for humans should just highlight the whole span without showing
// the suggested replacement, but we also want to test that suggested
Expand Down
92 changes: 91 additions & 1 deletion src/test/ui/lint/unused_parens_json_suggestion.stderr
Original file line number Diff line number Diff line change
@@ -1 +1,91 @@
{"message":"unnecessary parentheses around assigned value","code":{"code":"unused_parens","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":1001,"byte_end":1014,"line_start":24,"line_end":24,"column_start":14,"column_end":27,"is_primary":true,"text":[{"text":" let _a = (1 / (2 + 3));","highlight_start":14,"highlight_end":27}],"label":null,"suggested_replacement":null,"expansion":null}],"children":[{"message":"lint level defined here","code":null,"level":"note","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":847,"byte_end":860,"line_start":19,"line_end":19,"column_start":9,"column_end":22,"is_primary":true,"text":[{"text":"#![warn(unused_parens)]","highlight_start":9,"highlight_end":22}],"label":null,"suggested_replacement":null,"expansion":null}],"children":[],"rendered":null},{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":1001,"byte_end":1014,"line_start":24,"line_end":24,"column_start":14,"column_end":27,"is_primary":true,"text":[{"text":" let _a = (1 / (2 + 3));","highlight_start":14,"highlight_end":27}],"label":null,"suggested_replacement":"1 / (2 + 3)","expansion":null}],"children":[],"rendered":null}],"rendered":null}
{
"message": "unnecessary parentheses around assigned value",
"code": {
"code": "unused_parens",
"explanation": null
},
"level": "warning",
"spans": [
{
"file_name": "$DIR/unused_parens_json_suggestion.rs",
"byte_start": 1027,
"byte_end": 1040,
"line_start": 24,
"line_end": 24,
"column_start": 14,
"column_end": 27,
"is_primary": true,
"text": [
{
"text": " let _a = (1 / (2 + 3));",
"highlight_start": 14,
"highlight_end": 27
}
],
"label": null,
"suggested_replacement": null,
"expansion": null
}
],
"children": [
{
"message": "lint level defined here",
"code": null,
"level": "note",
"spans": [
{
"file_name": "$DIR/unused_parens_json_suggestion.rs",
"byte_start": 873,
"byte_end": 886,
"line_start": 19,
"line_end": 19,
"column_start": 9,
"column_end": 22,
"is_primary": true,
"text": [
{
"text": "#![warn(unused_parens)]",
"highlight_start": 9,
"highlight_end": 22
}
],
"label": null,
"suggested_replacement": null,
"expansion": null
}
],
"children": [],
"rendered": null
},
{
"message": "remove these parentheses",
"code": null,
"level": "help",
"spans": [
{
"file_name": "$DIR/unused_parens_json_suggestion.rs",
"byte_start": 1027,
"byte_end": 1040,
"line_start": 24,
"line_end": 24,
"column_start": 14,
"column_end": 27,
"is_primary": true,
"text": [
{
"text": " let _a = (1 / (2 + 3));",
"highlight_start": 14,
"highlight_end": 27
}
],
"label": null,
"suggested_replacement": "1 / (2 + 3)",
"expansion": null
}
],
"children": [],
"rendered": null
}
],
"rendered": null
}
2 changes: 1 addition & 1 deletion src/test/ui/lint/use_suggestion_json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: --error-format json
// compile-flags: --error-format pretty-json -Zunstable-options

// The output for humans should just highlight the whole span without showing
// the suggested replacement, but we also want to test that suggested
Expand Down
Loading