Skip to content

Commit 96404ee

Browse files
committed
Emit ansi color codes in the rendered field of json diagnostics
1 parent f694222 commit 96404ee

File tree

6 files changed

+123
-80
lines changed

6 files changed

+123
-80
lines changed

src/librustc/session/config.rs

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,12 @@ impl OutputType {
205205
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
206206
pub enum ErrorOutputType {
207207
HumanReadable(ColorConfig),
208-
Json(bool),
208+
Json {
209+
/// Render the json in a human readable way (with indents and newlines)
210+
pretty: bool,
211+
/// The `rendered` field with the command line diagnostics include color codes
212+
colorful_rendered: bool,
213+
},
209214
Short(ColorConfig),
210215
}
211216

@@ -1345,6 +1350,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
13451350
"print some statistics about AST and HIR"),
13461351
always_encode_mir: bool = (false, parse_bool, [TRACKED],
13471352
"encode MIR of all functions into the crate metadata"),
1353+
colorful_json: bool = (false, parse_bool, [UNTRACKED],
1354+
"encode color codes in the `rendered` field of json diagnostics"),
13481355
unleash_the_miri_inside_of_you: bool = (false, parse_bool, [TRACKED],
13491356
"take the breaks off const evaluation. NOTE: this is unsound"),
13501357
osx_rpath_install_name: bool = (false, parse_bool, [TRACKED],
@@ -1798,6 +1805,12 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
17981805
"How errors and other messages are produced",
17991806
"human|json|short",
18001807
),
1808+
opt::opt(
1809+
"",
1810+
"colorful-json",
1811+
"Emit ansi color codes to the `rendered` field of json diagnostics",
1812+
"TYPE",
1813+
),
18011814
opt::opt_s(
18021815
"",
18031816
"color",
@@ -1938,6 +1951,7 @@ pub fn build_session_options_and_crate_config(
19381951
)
19391952
}
19401953

1954+
let colorful_rendered = matches.opt_present("colorful-json");
19411955

19421956
// We need the opts_present check because the driver will send us Matches
19431957
// with only stable options if no unstable options are used. Since error-format
@@ -1946,8 +1960,8 @@ pub fn build_session_options_and_crate_config(
19461960
let error_format = if matches.opts_present(&["error-format".to_owned()]) {
19471961
match matches.opt_str("error-format").as_ref().map(|s| &s[..]) {
19481962
Some("human") => ErrorOutputType::HumanReadable(color),
1949-
Some("json") => ErrorOutputType::Json(false),
1950-
Some("pretty-json") => ErrorOutputType::Json(true),
1963+
Some("json") => ErrorOutputType::Json { pretty: false, colorful_rendered },
1964+
Some("pretty-json") => ErrorOutputType::Json { pretty: true, colorful_rendered },
19511965
Some("short") => ErrorOutputType::Short(color),
19521966
None => ErrorOutputType::HumanReadable(color),
19531967

@@ -1973,11 +1987,16 @@ pub fn build_session_options_and_crate_config(
19731987

19741988
let mut debugging_opts = build_debugging_options(matches, error_format);
19751989

1976-
if !debugging_opts.unstable_options && error_format == ErrorOutputType::Json(true) {
1977-
early_error(
1978-
ErrorOutputType::Json(false),
1979-
"--error-format=pretty-json is unstable",
1980-
);
1990+
if !debugging_opts.unstable_options {
1991+
if colorful_rendered {
1992+
early_error(error_format, "--colorful-json=true is unstable");
1993+
}
1994+
if let ErrorOutputType::Json { pretty: true, .. } = error_format {
1995+
early_error(
1996+
ErrorOutputType::Json { pretty: false, colorful_rendered: false },
1997+
"--error-format=pretty-json is unstable",
1998+
);
1999+
}
19812000
}
19822001

19832002
if debugging_opts.pgo_gen.is_some() && !debugging_opts.pgo_use.is_empty() {

src/librustc/session/mod.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,29 +1046,34 @@ fn default_emitter(
10461046
).ui_testing(sopts.debugging_opts.ui_testing),
10471047
),
10481048
(config::ErrorOutputType::HumanReadable(_), Some(dst)) => Box::new(
1049-
EmitterWriter::new(dst, Some(source_map.clone()), false, false)
1050-
.ui_testing(sopts.debugging_opts.ui_testing),
1049+
EmitterWriter::new(
1050+
dst, Some(source_map.clone()), false, false, sopts.debugging_opts.colorful_json,
1051+
).ui_testing(sopts.debugging_opts.ui_testing),
10511052
),
1052-
(config::ErrorOutputType::Json(pretty), None) => Box::new(
1053+
(config::ErrorOutputType::Json { pretty, colorful_rendered }, None) => Box::new(
10531054
JsonEmitter::stderr(
10541055
Some(registry),
10551056
source_map.clone(),
10561057
pretty,
1058+
colorful_rendered,
10571059
).ui_testing(sopts.debugging_opts.ui_testing),
10581060
),
1059-
(config::ErrorOutputType::Json(pretty), Some(dst)) => Box::new(
1061+
(config::ErrorOutputType::Json { pretty, colorful_rendered }, Some(dst)) => Box::new(
10601062
JsonEmitter::new(
10611063
dst,
10621064
Some(registry),
10631065
source_map.clone(),
10641066
pretty,
1067+
colorful_rendered,
10651068
).ui_testing(sopts.debugging_opts.ui_testing),
10661069
),
10671070
(config::ErrorOutputType::Short(color_config), None) => Box::new(
10681071
EmitterWriter::stderr(color_config, Some(source_map.clone()), true, false),
10691072
),
10701073
(config::ErrorOutputType::Short(_), Some(dst)) => {
1071-
Box::new(EmitterWriter::new(dst, Some(source_map.clone()), true, false))
1074+
Box::new(EmitterWriter::new(
1075+
dst, Some(source_map.clone()), true, false, sopts.debugging_opts.colorful_json,
1076+
))
10721077
}
10731078
}
10741079
}
@@ -1317,7 +1322,8 @@ pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
13171322
config::ErrorOutputType::HumanReadable(color_config) => {
13181323
Box::new(EmitterWriter::stderr(color_config, None, false, false))
13191324
}
1320-
config::ErrorOutputType::Json(pretty) => Box::new(JsonEmitter::basic(pretty)),
1325+
config::ErrorOutputType::Json { pretty, colorful_rendered } =>
1326+
Box::new(JsonEmitter::basic(pretty, colorful_rendered)),
13211327
config::ErrorOutputType::Short(color_config) => {
13221328
Box::new(EmitterWriter::stderr(color_config, None, true, false))
13231329
}
@@ -1332,7 +1338,8 @@ pub fn early_warn(output: config::ErrorOutputType, msg: &str) {
13321338
config::ErrorOutputType::HumanReadable(color_config) => {
13331339
Box::new(EmitterWriter::stderr(color_config, None, false, false))
13341340
}
1335-
config::ErrorOutputType::Json(pretty) => Box::new(JsonEmitter::basic(pretty)),
1341+
config::ErrorOutputType::Json { pretty, colorful_rendered } =>
1342+
Box::new(JsonEmitter::basic(pretty, colorful_rendered)),
13361343
config::ErrorOutputType::Short(color_config) => {
13371344
Box::new(EmitterWriter::stderr(color_config, None, true, false))
13381345
}

src/librustc_errors/emitter.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use std::borrow::Cow;
1616
use std::io::prelude::*;
1717
use std::io;
1818
use std::cmp::{min, Reverse};
19-
use termcolor::{StandardStream, ColorChoice, ColorSpec, BufferWriter};
19+
use termcolor::{StandardStream, ColorChoice, ColorSpec, BufferWriter, Ansi};
2020
use termcolor::{WriteColor, Color, Buffer};
2121

2222
const ANONYMIZED_LINE_NUM: &str = "LL";
@@ -152,13 +152,15 @@ impl EmitterWriter {
152152
}
153153
}
154154

155-
pub fn new(dst: Box<dyn Write + Send>,
156-
source_map: Option<Lrc<SourceMapperDyn>>,
157-
short_message: bool,
158-
teach: bool)
159-
-> EmitterWriter {
155+
pub fn new(
156+
dst: Box<dyn Write + Send>,
157+
source_map: Option<Lrc<SourceMapperDyn>>,
158+
short_message: bool,
159+
teach: bool,
160+
colored: bool,
161+
) -> EmitterWriter {
160162
EmitterWriter {
161-
dst: Raw(dst),
163+
dst: Raw(dst, colored),
162164
sm: source_map,
163165
short_message,
164166
teach,
@@ -1538,13 +1540,14 @@ fn emit_to_destination(rendered_buffer: &[Vec<StyledString>],
15381540
pub enum Destination {
15391541
Terminal(StandardStream),
15401542
Buffered(BufferWriter),
1541-
Raw(Box<dyn Write + Send>),
1543+
Raw(Box<(dyn Write + Send)>, bool),
15421544
}
15431545

15441546
pub enum WritableDst<'a> {
15451547
Terminal(&'a mut StandardStream),
15461548
Buffered(&'a mut BufferWriter, Buffer),
1547-
Raw(&'a mut Box<dyn Write + Send>),
1549+
Raw(&'a mut (dyn Write + Send)),
1550+
ColoredRaw(Ansi<&'a mut (dyn Write + Send)>),
15481551
}
15491552

15501553
impl Destination {
@@ -1570,7 +1573,8 @@ impl Destination {
15701573
let buf = t.buffer();
15711574
WritableDst::Buffered(t, buf)
15721575
}
1573-
Destination::Raw(ref mut t) => WritableDst::Raw(t),
1576+
Destination::Raw(ref mut t, false) => WritableDst::Raw(t),
1577+
Destination::Raw(ref mut t, true) => WritableDst::ColoredRaw(Ansi::new(t)),
15741578
}
15751579
}
15761580
}
@@ -1628,6 +1632,7 @@ impl<'a> WritableDst<'a> {
16281632
match *self {
16291633
WritableDst::Terminal(ref mut t) => t.set_color(color),
16301634
WritableDst::Buffered(_, ref mut t) => t.set_color(color),
1635+
WritableDst::ColoredRaw(ref mut t) => t.set_color(color),
16311636
WritableDst::Raw(_) => Ok(())
16321637
}
16331638
}
@@ -1636,6 +1641,7 @@ impl<'a> WritableDst<'a> {
16361641
match *self {
16371642
WritableDst::Terminal(ref mut t) => t.reset(),
16381643
WritableDst::Buffered(_, ref mut t) => t.reset(),
1644+
WritableDst::ColoredRaw(ref mut t) => t.reset(),
16391645
WritableDst::Raw(_) => Ok(()),
16401646
}
16411647
}
@@ -1647,6 +1653,7 @@ impl<'a> Write for WritableDst<'a> {
16471653
WritableDst::Terminal(ref mut t) => t.write(bytes),
16481654
WritableDst::Buffered(_, ref mut buf) => buf.write(bytes),
16491655
WritableDst::Raw(ref mut w) => w.write(bytes),
1656+
WritableDst::ColoredRaw(ref mut t) => t.write(bytes),
16501657
}
16511658
}
16521659

@@ -1655,6 +1662,7 @@ impl<'a> Write for WritableDst<'a> {
16551662
WritableDst::Terminal(ref mut t) => t.flush(),
16561663
WritableDst::Buffered(_, ref mut buf) => buf.flush(),
16571664
WritableDst::Raw(ref mut w) => w.flush(),
1665+
WritableDst::ColoredRaw(ref mut w) => w.flush(),
16581666
}
16591667
}
16601668
}

src/libsyntax/json.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,37 +30,46 @@ pub struct JsonEmitter {
3030
sm: Lrc<dyn SourceMapper + sync::Send + sync::Sync>,
3131
pretty: bool,
3232
ui_testing: bool,
33+
colorful_rendered: bool,
3334
}
3435

3536
impl JsonEmitter {
36-
pub fn stderr(registry: Option<Registry>,
37-
source_map: Lrc<SourceMap>,
38-
pretty: bool) -> JsonEmitter {
37+
pub fn stderr(
38+
registry: Option<Registry>,
39+
source_map: Lrc<SourceMap>,
40+
pretty: bool,
41+
colorful_rendered: bool,
42+
) -> JsonEmitter {
3943
JsonEmitter {
4044
dst: Box::new(io::stderr()),
4145
registry,
4246
sm: source_map,
4347
pretty,
4448
ui_testing: false,
49+
colorful_rendered,
4550
}
4651
}
4752

48-
pub fn basic(pretty: bool) -> JsonEmitter {
53+
pub fn basic(pretty: bool, colorful_rendered: bool) -> JsonEmitter {
4954
let file_path_mapping = FilePathMapping::empty();
5055
JsonEmitter::stderr(None, Lrc::new(SourceMap::new(file_path_mapping)),
51-
pretty)
56+
pretty, colorful_rendered)
5257
}
5358

54-
pub fn new(dst: Box<dyn Write + Send>,
55-
registry: Option<Registry>,
56-
source_map: Lrc<SourceMap>,
57-
pretty: bool) -> JsonEmitter {
59+
pub fn new(
60+
dst: Box<dyn Write + Send>,
61+
registry: Option<Registry>,
62+
source_map: Lrc<SourceMap>,
63+
pretty: bool,
64+
colorful_rendered: bool,
65+
) -> JsonEmitter {
5866
JsonEmitter {
5967
dst,
6068
registry,
6169
sm: source_map,
6270
pretty,
6371
ui_testing: false,
72+
colorful_rendered,
6473
}
6574
}
6675

@@ -190,7 +199,7 @@ impl Diagnostic {
190199
}
191200
let buf = BufWriter::default();
192201
let output = buf.clone();
193-
EmitterWriter::new(Box::new(buf), Some(je.sm.clone()), false, false)
202+
EmitterWriter::new(Box::new(buf), Some(je.sm.clone()), false, false, je.colorful_rendered)
194203
.ui_testing(je.ui_testing).emit(db);
195204
let output = Arc::try_unwrap(output.0).unwrap().into_inner().unwrap();
196205
let output = String::from_utf8(output).unwrap();

src/test/ui/lint/use_suggestion_json.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// ignore-cloudabi
2-
// compile-flags: --error-format pretty-json -Zunstable-options
2+
// compile-flags: --error-format pretty-json -Zunstable-options --colorful-json=true
33

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

0 commit comments

Comments
 (0)