about summary refs log tree commit diff
path: root/compiler/rustc_errors/src/json.rs
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2024-02-29 17:08:38 +0100
committerGitHub <noreply@github.com>2024-02-29 17:08:38 +0100
commit0e9f02d6fa769f1e96fc5e54af7b77b101bcc603 (patch)
tree3bd55c979127cf371e5059d7debb7e9e8677c160 /compiler/rustc_errors/src/json.rs
parenta5945b5d8d0b5b19aa01926ce3cd8c33de6fde8e (diff)
parent607bf653c2bed1ec3f7979d9511f3c9cef604bc3 (diff)
downloadrust-0e9f02d6fa769f1e96fc5e54af7b77b101bcc603.tar.gz
rust-0e9f02d6fa769f1e96fc5e54af7b77b101bcc603.zip
Rollup merge of #121783 - nnethercote:emitter-cleanups, r=oli-obk
Emitter cleanups

Some cleanups I made when reading emitter code. In particular, `HumanEmitter` and `JsonEmitter` have gone from three constructors to one.

r? `@oli-obk`
Diffstat (limited to 'compiler/rustc_errors/src/json.rs')
-rw-r--r--compiler/rustc_errors/src/json.rs131
1 files changed, 38 insertions, 93 deletions
diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs
index 88a83c8bf78..bc1822f83fc 100644
--- a/compiler/rustc_errors/src/json.rs
+++ b/compiler/rustc_errors/src/json.rs
@@ -9,42 +9,49 @@
 
 // FIXME: spec the JSON output properly.
 
-use rustc_span::source_map::{FilePathMapping, SourceMap};
-use termcolor::{ColorSpec, WriteColor};
-
-use crate::emitter::{should_show_source_code, Emitter, HumanReadableErrorType};
+use crate::emitter::{
+    should_show_source_code, ColorConfig, Destination, Emitter, HumanEmitter,
+    HumanReadableErrorType,
+};
 use crate::registry::Registry;
 use crate::translation::{to_fluent_args, Translate};
 use crate::{
     diagnostic::IsLint, CodeSuggestion, FluentBundle, LazyFallbackBundle, MultiSpan, SpanLabel,
     Subdiag, TerminalUrl,
 };
-use rustc_lint_defs::Applicability;
-
+use derive_setters::Setters;
 use rustc_data_structures::sync::{IntoDynSyncSend, Lrc};
 use rustc_error_messages::FluentArgs;
+use rustc_lint_defs::Applicability;
 use rustc_span::hygiene::ExpnData;
+use rustc_span::source_map::SourceMap;
 use rustc_span::Span;
+use serde::Serialize;
 use std::error::Report;
 use std::io::{self, Write};
 use std::path::Path;
 use std::sync::{Arc, Mutex};
 use std::vec;
-
-use serde::Serialize;
+use termcolor::{ColorSpec, WriteColor};
 
 #[cfg(test)]
 mod tests;
 
+#[derive(Setters)]
 pub struct JsonEmitter {
+    #[setters(skip)]
     dst: IntoDynSyncSend<Box<dyn Write + Send>>,
     registry: Option<Registry>,
+    #[setters(skip)]
     sm: Lrc<SourceMap>,
     fluent_bundle: Option<Lrc<FluentBundle>>,
+    #[setters(skip)]
     fallback_bundle: LazyFallbackBundle,
+    #[setters(skip)]
     pretty: bool,
     ui_testing: bool,
     ignored_directories_in_source_blocks: Vec<String>,
+    #[setters(skip)]
     json_rendered: HumanReadableErrorType,
     diagnostic_width: Option<usize>,
     macro_backtrace: bool,
@@ -53,98 +60,30 @@ pub struct JsonEmitter {
 }
 
 impl JsonEmitter {
-    pub fn stderr(
-        registry: Option<Registry>,
-        source_map: Lrc<SourceMap>,
-        fluent_bundle: Option<Lrc<FluentBundle>>,
-        fallback_bundle: LazyFallbackBundle,
-        pretty: bool,
-        json_rendered: HumanReadableErrorType,
-        diagnostic_width: Option<usize>,
-        macro_backtrace: bool,
-        track_diagnostics: bool,
-        terminal_url: TerminalUrl,
-    ) -> JsonEmitter {
-        JsonEmitter {
-            dst: IntoDynSyncSend(Box::new(io::BufWriter::new(io::stderr()))),
-            registry,
-            sm: source_map,
-            fluent_bundle,
-            fallback_bundle,
-            pretty,
-            ui_testing: false,
-            ignored_directories_in_source_blocks: Vec::new(),
-            json_rendered,
-            diagnostic_width,
-            macro_backtrace,
-            track_diagnostics,
-            terminal_url,
-        }
-    }
-
-    pub fn basic(
-        pretty: bool,
-        json_rendered: HumanReadableErrorType,
-        fluent_bundle: Option<Lrc<FluentBundle>>,
-        fallback_bundle: LazyFallbackBundle,
-        diagnostic_width: Option<usize>,
-        macro_backtrace: bool,
-        track_diagnostics: bool,
-        terminal_url: TerminalUrl,
-    ) -> JsonEmitter {
-        let file_path_mapping = FilePathMapping::empty();
-        JsonEmitter::stderr(
-            None,
-            Lrc::new(SourceMap::new(file_path_mapping)),
-            fluent_bundle,
-            fallback_bundle,
-            pretty,
-            json_rendered,
-            diagnostic_width,
-            macro_backtrace,
-            track_diagnostics,
-            terminal_url,
-        )
-    }
-
     pub fn new(
         dst: Box<dyn Write + Send>,
-        registry: Option<Registry>,
-        source_map: Lrc<SourceMap>,
-        fluent_bundle: Option<Lrc<FluentBundle>>,
+        sm: Lrc<SourceMap>,
         fallback_bundle: LazyFallbackBundle,
         pretty: bool,
         json_rendered: HumanReadableErrorType,
-        diagnostic_width: Option<usize>,
-        macro_backtrace: bool,
-        track_diagnostics: bool,
-        terminal_url: TerminalUrl,
     ) -> JsonEmitter {
         JsonEmitter {
             dst: IntoDynSyncSend(dst),
-            registry,
-            sm: source_map,
-            fluent_bundle,
+            registry: None,
+            sm,
+            fluent_bundle: None,
             fallback_bundle,
             pretty,
             ui_testing: false,
             ignored_directories_in_source_blocks: Vec::new(),
             json_rendered,
-            diagnostic_width,
-            macro_backtrace,
-            track_diagnostics,
-            terminal_url,
+            diagnostic_width: None,
+            macro_backtrace: false,
+            track_diagnostics: false,
+            terminal_url: TerminalUrl::No,
         }
     }
 
-    pub fn ui_testing(self, ui_testing: bool) -> Self {
-        Self { ui_testing, ..self }
-    }
-
-    pub fn ignored_directories_in_source_blocks(self, value: Vec<String>) -> Self {
-        Self { ignored_directories_in_source_blocks: value, ..self }
-    }
-
     fn emit(&mut self, val: EmitTyped<'_>) -> io::Result<()> {
         if self.pretty {
             serde_json::to_writer_pretty(&mut *self.dst, &val)?
@@ -162,7 +101,7 @@ enum EmitTyped<'a> {
     Diagnostic(Diagnostic),
     Artifact(ArtifactNotification<'a>),
     FutureIncompat(FutureIncompatReport<'a>),
-    UnusedExtern(UnusedExterns<'a, 'a, 'a>),
+    UnusedExtern(UnusedExterns<'a>),
 }
 
 impl Translate for JsonEmitter {
@@ -332,14 +271,15 @@ struct FutureIncompatReport<'a> {
 // We could unify this struct the one in rustdoc but they have different
 // ownership semantics, so doing so would create wasteful allocations.
 #[derive(Serialize)]
-struct UnusedExterns<'a, 'b, 'c> {
+struct UnusedExterns<'a> {
     /// The severity level of the unused dependencies lint
     lint_level: &'a str,
     /// List of unused externs by their names.
-    unused_extern_names: &'b [&'c str],
+    unused_extern_names: &'a [&'a str],
 }
 
 impl Diagnostic {
+    /// Converts from `rustc_errors::DiagInner` to `Diagnostic`.
     fn from_errors_diagnostic(diag: crate::DiagInner, je: &JsonEmitter) -> Diagnostic {
         let args = to_fluent_args(diag.args.iter());
         let sugg = diag.suggestions.iter().flatten().map(|sugg| {
@@ -405,9 +345,14 @@ impl Diagnostic {
             .collect();
 
         let buf = BufWriter::default();
-        let output = buf.clone();
-        je.json_rendered
-            .new_emitter(Box::new(buf), je.fallback_bundle.clone())
+        let mut dst: Destination = Box::new(buf.clone());
+        let (short, color_config) = je.json_rendered.unzip();
+        match color_config {
+            ColorConfig::Always | ColorConfig::Auto => dst = Box::new(termcolor::Ansi::new(dst)),
+            ColorConfig::Never => {}
+        }
+        HumanEmitter::new(dst, je.fallback_bundle.clone())
+            .short_message(short)
             .sm(Some(je.sm.clone()))
             .fluent_bundle(je.fluent_bundle.clone())
             .diagnostic_width(je.diagnostic_width)
@@ -417,8 +362,8 @@ impl Diagnostic {
             .ui_testing(je.ui_testing)
             .ignored_directories_in_source_blocks(je.ignored_directories_in_source_blocks.clone())
             .emit_diagnostic(diag);
-        let output = Arc::try_unwrap(output.0).unwrap().into_inner().unwrap();
-        let output = String::from_utf8(output).unwrap();
+        let buf = Arc::try_unwrap(buf.0).unwrap().into_inner().unwrap();
+        let buf = String::from_utf8(buf).unwrap();
 
         Diagnostic {
             message: translated_message.to_string(),
@@ -426,7 +371,7 @@ impl Diagnostic {
             level,
             spans,
             children,
-            rendered: Some(output),
+            rendered: Some(buf),
         }
     }