Skip to content
Permalink
Browse files

Rename `colorful-json` to `json-rendered` and make it a selection ins…

…tead of a bool
  • Loading branch information...
oli-obk committed Mar 25, 2019
1 parent 0a842e8 commit 39b21376dbe9489b7f4d39f3bf742a44d5f3770d
@@ -19,6 +19,7 @@ use syntax::parse::token;
use syntax::parse;
use syntax::symbol::Symbol;
use syntax::feature_gate::UnstableFeatures;
use errors::emitter::HumanReadableErrorType;

use errors::{ColorConfig, FatalError, Handler};

@@ -204,19 +205,18 @@ impl OutputType {

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ErrorOutputType {
HumanReadable(ColorConfig),
HumanReadable(HumanReadableErrorType),
Json {
/// Render the json in a human readable way (with indents and newlines)
pretty: bool,
/// The `rendered` field with the command line diagnostics include color codes
colorful_rendered: bool,
/// The way the `rendered` field is created
json_rendered: HumanReadableErrorType,
},
Short(ColorConfig),
}

impl Default for ErrorOutputType {
fn default() -> ErrorOutputType {
ErrorOutputType::HumanReadable(ColorConfig::Auto)
ErrorOutputType::HumanReadable(HumanReadableErrorType::Default(ColorConfig::Auto))
}
}

@@ -1350,8 +1350,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
"print some statistics about AST and HIR"),
always_encode_mir: bool = (false, parse_bool, [TRACKED],
"encode MIR of all functions into the crate metadata"),
colorful_json: bool = (false, parse_bool, [UNTRACKED],
"encode color codes in the `rendered` field of json diagnostics"),
json_rendered: Option<String> = (None, parse_opt_string, [UNTRACKED],
"describes how to render the `rendered` field of json diagnostics"),
unleash_the_miri_inside_of_you: bool = (false, parse_bool, [TRACKED],
"take the breaks off const evaluation. NOTE: this is unsound"),
osx_rpath_install_name: bool = (false, parse_bool, [TRACKED],
@@ -1807,9 +1807,9 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
),
opt::opt(
"",
"colorful-json",
"Emit ansi color codes to the `rendered` field of json diagnostics",
"TYPE",
"json-rendered",
"Choose `rendered` field of json diagnostics render scheme",
"plain|termcolor",
),
opt::opt_s(
"",
@@ -1951,22 +1951,32 @@ pub fn build_session_options_and_crate_config(
)
}

let colorful_rendered = matches.opt_present("colorful-json");
let json_rendered = matches.opt_str("json-rendered").and_then(|s| match s.as_str() {
"plain" => None,
"termcolor" => Some(HumanReadableErrorType::Default(ColorConfig::Always)),
_ => early_error(
ErrorOutputType::default(),
&format!(
"argument for --json-rendered must be `plain` or `termcolor` (instead was `{}`)",
s,
),
),
}).unwrap_or(HumanReadableErrorType::Default(ColorConfig::Never));

// We need the opts_present check because the driver will send us Matches
// with only stable options if no unstable options are used. Since error-format
// is unstable, it will not be present. We have to use opts_present not
// opt_present because the latter will panic.
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 { pretty: false, colorful_rendered },
Some("pretty-json") => ErrorOutputType::Json { pretty: true, colorful_rendered },
Some("short") => ErrorOutputType::Short(color),
None => ErrorOutputType::HumanReadable(color),
None |
Some("human") => ErrorOutputType::HumanReadable(HumanReadableErrorType::Default(color)),
Some("json") => ErrorOutputType::Json { pretty: false, json_rendered },
Some("pretty-json") => ErrorOutputType::Json { pretty: true, json_rendered },
Some("short") => ErrorOutputType::HumanReadable(HumanReadableErrorType::Short(color)),

Some(arg) => early_error(
ErrorOutputType::HumanReadable(color),
ErrorOutputType::HumanReadable(HumanReadableErrorType::Default(color)),
&format!(
"argument for --error-format must be `human`, `json` or \
`short` (instead was `{}`)",
@@ -1975,7 +1985,7 @@ pub fn build_session_options_and_crate_config(
),
}
} else {
ErrorOutputType::HumanReadable(color)
ErrorOutputType::HumanReadable(HumanReadableErrorType::Default(color))
};

let unparsed_crate_types = matches.opt_strs("crate-type");
@@ -1988,12 +1998,12 @@ pub fn build_session_options_and_crate_config(
let mut debugging_opts = build_debugging_options(matches, error_format);

if !debugging_opts.unstable_options {
if colorful_rendered {
early_error(error_format, "--colorful-json=true is unstable");
if matches.opt_str("json-rendered").is_some() {
early_error(error_format, "`--json-rendered=x` is unstable");
}
if let ErrorOutputType::Json { pretty: true, .. } = error_format {
if let ErrorOutputType::Json { pretty: true, json_rendered } = error_format {
early_error(
ErrorOutputType::Json { pretty: false, colorful_rendered: false },
ErrorOutputType::Json { pretty: false, json_rendered },
"--error-format=pretty-json is unstable",
);
}
@@ -2902,7 +2912,7 @@ mod tests {

const JSON: super::ErrorOutputType = super::ErrorOutputType::Json {
pretty: false,
colorful_rendered: false,
json_rendered: super::HumanReadableErrorType::Default(super::ColorConfig::Never),
};

// Reference
@@ -1037,44 +1037,42 @@ fn default_emitter(
emitter_dest: Option<Box<dyn Write + Send>>,
) -> Box<dyn Emitter + sync::Send> {
match (sopts.error_format, emitter_dest) {
(config::ErrorOutputType::HumanReadable(color_config), None) => Box::new(
EmitterWriter::stderr(
color_config,
Some(source_map.clone()),
false,
sopts.debugging_opts.teach,
).ui_testing(sopts.debugging_opts.ui_testing),
),
(config::ErrorOutputType::HumanReadable(_), Some(dst)) => Box::new(
EmitterWriter::new(
dst, Some(source_map.clone()), false, false, sopts.debugging_opts.colorful_json,
).ui_testing(sopts.debugging_opts.ui_testing),
),
(config::ErrorOutputType::Json { pretty, colorful_rendered }, None) => Box::new(
(config::ErrorOutputType::HumanReadable(kind), dst) => {
let (short, color_config) = kind.unzip();
let emitter = match dst {
None => EmitterWriter::stderr(
color_config,
Some(source_map.clone()),
short,
sopts.debugging_opts.teach,
),
Some(dst) => EmitterWriter::new(
dst,
Some(source_map.clone()),
short,
false,
color_config.suggests_using_colors(),
),
};
Box::new(emitter.ui_testing(sopts.debugging_opts.ui_testing))
},
(config::ErrorOutputType::Json { pretty, json_rendered }, None) => Box::new(
JsonEmitter::stderr(
Some(registry),
source_map.clone(),
pretty,
colorful_rendered,
json_rendered,
).ui_testing(sopts.debugging_opts.ui_testing),
),
(config::ErrorOutputType::Json { pretty, colorful_rendered }, Some(dst)) => Box::new(
(config::ErrorOutputType::Json { pretty, json_rendered }, Some(dst)) => Box::new(
JsonEmitter::new(
dst,
Some(registry),
source_map.clone(),
pretty,
colorful_rendered,
json_rendered,
).ui_testing(sopts.debugging_opts.ui_testing),
),
(config::ErrorOutputType::Short(color_config), None) => Box::new(
EmitterWriter::stderr(color_config, Some(source_map.clone()), true, false),
),
(config::ErrorOutputType::Short(_), Some(dst)) => {
Box::new(EmitterWriter::new(
dst, Some(source_map.clone()), true, false, sopts.debugging_opts.colorful_json,
))
}
}
}

@@ -1319,14 +1317,12 @@ pub enum IncrCompSession {

pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
let emitter: Box<dyn Emitter + sync::Send> = match output {
config::ErrorOutputType::HumanReadable(color_config) => {
Box::new(EmitterWriter::stderr(color_config, None, false, false))
}
config::ErrorOutputType::Json { pretty, colorful_rendered } =>
Box::new(JsonEmitter::basic(pretty, colorful_rendered)),
config::ErrorOutputType::Short(color_config) => {
Box::new(EmitterWriter::stderr(color_config, None, true, false))
config::ErrorOutputType::HumanReadable(kind) => {
let (short, color_config) = kind.unzip();
Box::new(EmitterWriter::stderr(color_config, None, short, false))
}
config::ErrorOutputType::Json { pretty, json_rendered } =>
Box::new(JsonEmitter::basic(pretty, json_rendered)),
};
let handler = errors::Handler::with_emitter(true, None, emitter);
handler.emit(&MultiSpan::new(), msg, errors::Level::Fatal);
@@ -1335,14 +1331,12 @@ pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {

pub fn early_warn(output: config::ErrorOutputType, msg: &str) {
let emitter: Box<dyn Emitter + sync::Send> = match output {
config::ErrorOutputType::HumanReadable(color_config) => {
Box::new(EmitterWriter::stderr(color_config, None, false, false))
}
config::ErrorOutputType::Json { pretty, colorful_rendered } =>
Box::new(JsonEmitter::basic(pretty, colorful_rendered)),
config::ErrorOutputType::Short(color_config) => {
Box::new(EmitterWriter::stderr(color_config, None, true, false))
config::ErrorOutputType::HumanReadable(kind) => {
let (short, color_config) = kind.unzip();
Box::new(EmitterWriter::stderr(color_config, None, short, false))
}
config::ErrorOutputType::Json { pretty, json_rendered } =>
Box::new(JsonEmitter::basic(pretty, json_rendered)),
};
let handler = errors::Handler::with_emitter(true, None, emitter);
handler.emit(&MultiSpan::new(), msg, errors::Level::Warning);
@@ -19,6 +19,32 @@ use std::cmp::{min, Reverse};
use termcolor::{StandardStream, ColorChoice, ColorSpec, BufferWriter, Ansi};
use termcolor::{WriteColor, Color, Buffer};

/// Describes the way the content of the `rendered` field of the json output is generated
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum HumanReadableErrorType {
Default(ColorConfig),
Short(ColorConfig),
}

impl HumanReadableErrorType {
/// Returns a (`short`, `color`) tuple
pub fn unzip(self) -> (bool, ColorConfig) {
match self {
HumanReadableErrorType::Default(cc) => (false, cc),
HumanReadableErrorType::Short(cc) => (true, cc),
}
}
pub fn new_emitter(
self,
dst: Box<dyn Write + Send>,
source_map: Option<Lrc<SourceMapperDyn>>,
teach: bool,
) -> EmitterWriter {
let (short, color_config) = self.unzip();
EmitterWriter::new(dst, source_map, short, teach, color_config.suggests_using_colors())
}
}

const ANONYMIZED_LINE_NUM: &str = "LL";

/// Emitter trait for emitting errors.
@@ -104,8 +130,8 @@ pub enum ColorConfig {
}

impl ColorConfig {
fn to_color_choice(&self) -> ColorChoice {
match *self {
fn to_color_choice(self) -> ColorChoice {
match self {
ColorConfig::Always => {
if atty::is(atty::Stream::Stderr) {
ColorChoice::Always
@@ -120,6 +146,14 @@ impl ColorConfig {
ColorConfig::Auto => ColorChoice::Never,
}
}
pub fn suggests_using_colors(self) -> bool {
match self {
| ColorConfig::Always
| ColorConfig::Auto
=> true,
ColorConfig::Never => false,
}
}
}

pub struct EmitterWriter {
@@ -1540,6 +1574,7 @@ fn emit_to_destination(rendered_buffer: &[Vec<StyledString>],
pub enum Destination {
Terminal(StandardStream),
Buffered(BufferWriter),
// The bool denotes whether we should be emitting ansi color codes or not
Raw(Box<(dyn Write + Send)>, bool),
}

@@ -3,7 +3,7 @@ use std::fmt;
use std::path::PathBuf;

use errors;
use errors::emitter::ColorConfig;
use errors::emitter::{ColorConfig, HumanReadableErrorType};
use getopts;
use rustc::lint::Level;
use rustc::session::early_error;
@@ -256,11 +256,17 @@ impl Options {
};
// FIXME: deduplicate this code from the identical code in librustc/session/config.rs
let error_format = match matches.opt_str("error-format").as_ref().map(|s| &s[..]) {
Some("human") => ErrorOutputType::HumanReadable(color),
Some("json") => ErrorOutputType::Json { pretty: false, colorful_rendered: false },
Some("pretty-json") => ErrorOutputType::Json { pretty: true, colorful_rendered: false },
Some("short") => ErrorOutputType::Short(color),
None => ErrorOutputType::HumanReadable(color),
None |
Some("human") => ErrorOutputType::HumanReadable(HumanReadableErrorType::Default(color)),
Some("json") => ErrorOutputType::Json {
pretty: false,
json_rendered: HumanReadableErrorType::Default(color),
},
Some("pretty-json") => ErrorOutputType::Json {
pretty: true,
json_rendered: HumanReadableErrorType::Default(color),
},
Some("short") => ErrorOutputType::HumanReadable(HumanReadableErrorType::Short(color)),
Some(arg) => {
early_error(ErrorOutputType::default(),
&format!("argument for --error-format must be `human`, `json` or \
@@ -299,33 +299,29 @@ pub fn new_handler(error_format: ErrorOutputType,
// stick to the defaults
let sessopts = Options::default();
let emitter: Box<dyn Emitter + sync::Send> = match error_format {
ErrorOutputType::HumanReadable(color_config) => Box::new(
EmitterWriter::stderr(
color_config,
source_map.map(|cm| cm as _),
false,
sessopts.debugging_opts.teach,
).ui_testing(ui_testing)
),
ErrorOutputType::Json { pretty, colorful_rendered } => {
ErrorOutputType::HumanReadable(kind) => {
let (short, color_config) = kind.unzip();
Box::new(
EmitterWriter::stderr(
color_config,
source_map.map(|cm| cm as _),
short,
sessopts.debugging_opts.teach,
).ui_testing(ui_testing)
)
},
ErrorOutputType::Json { pretty, json_rendered } => {
let source_map = source_map.unwrap_or_else(
|| Lrc::new(source_map::SourceMap::new(sessopts.file_path_mapping())));
Box::new(
JsonEmitter::stderr(
None,
source_map,
pretty,
colorful_rendered,
json_rendered,
).ui_testing(ui_testing)
)
},
ErrorOutputType::Short(color_config) => Box::new(
EmitterWriter::stderr(
color_config,
source_map.map(|cm| cm as _),
true,
false)
),
};

errors::Handler::with_emitter_and_flags(
Oops, something went wrong.

0 comments on commit 39b2137

Please sign in to comment.
You can’t perform that action at this time.