Use serde_json for json error messages

This commit is contained in:
bjorn3 2021-06-03 21:14:15 +02:00
parent fc1df4ff17
commit 62a4f91a5a
6 changed files with 39 additions and 33 deletions

View File

@ -3810,6 +3810,8 @@ dependencies = [
"rustc_macros",
"rustc_serialize",
"rustc_span",
"serde",
"serde_json",
"termcolor",
"termize",
"tracing",
@ -4025,6 +4027,7 @@ dependencies = [
"rustc_serialize",
"rustc_span",
"rustc_target",
"serde",
]
[[package]]

View File

@ -19,6 +19,8 @@ atty = "0.2"
termcolor = "1.0"
annotate-snippets = "0.8.0"
termize = "0.1.1"
serde = { version = "1.0.125", features = ["derive"] }
serde_json = "1.0.59"
[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["handleapi", "synchapi", "winbase"] }

View File

@ -28,7 +28,7 @@ use std::path::Path;
use std::sync::{Arc, Mutex};
use std::vec;
use rustc_serialize::json::{as_json, as_pretty_json};
use serde::Serialize;
#[cfg(test)]
mod tests;
@ -126,9 +126,9 @@ impl Emitter for JsonEmitter {
fn emit_diagnostic(&mut self, diag: &crate::Diagnostic) {
let data = Diagnostic::from_errors_diagnostic(diag, self);
let result = if self.pretty {
writeln!(&mut self.dst, "{}", as_pretty_json(&data))
writeln!(&mut self.dst, "{}", serde_json::to_string_pretty(&data).unwrap())
} else {
writeln!(&mut self.dst, "{}", as_json(&data))
writeln!(&mut self.dst, "{}", serde_json::to_string(&data).unwrap())
}
.and_then(|_| self.dst.flush());
if let Err(e) = result {
@ -139,9 +139,9 @@ impl Emitter for JsonEmitter {
fn emit_artifact_notification(&mut self, path: &Path, artifact_type: &str) {
let data = ArtifactNotification { artifact: path, emit: artifact_type };
let result = if self.pretty {
writeln!(&mut self.dst, "{}", as_pretty_json(&data))
writeln!(&mut self.dst, "{}", serde_json::to_string_pretty(&data).unwrap())
} else {
writeln!(&mut self.dst, "{}", as_json(&data))
writeln!(&mut self.dst, "{}", serde_json::to_string(&data).unwrap())
}
.and_then(|_| self.dst.flush());
if let Err(e) = result {
@ -161,9 +161,9 @@ impl Emitter for JsonEmitter {
.collect();
let report = FutureIncompatReport { future_incompat_report: data };
let result = if self.pretty {
writeln!(&mut self.dst, "{}", as_pretty_json(&report))
writeln!(&mut self.dst, "{}", serde_json::to_string_pretty(&report).unwrap())
} else {
writeln!(&mut self.dst, "{}", as_json(&report))
writeln!(&mut self.dst, "{}", serde_json::to_string(&report).unwrap())
}
.and_then(|_| self.dst.flush());
if let Err(e) = result {
@ -175,9 +175,9 @@ impl Emitter for JsonEmitter {
let lint_level = lint_level.as_str();
let data = UnusedExterns { lint_level, unused_extern_names: unused_externs };
let result = if self.pretty {
writeln!(&mut self.dst, "{}", as_pretty_json(&data))
writeln!(&mut self.dst, "{}", serde_json::to_string_pretty(&data).unwrap())
} else {
writeln!(&mut self.dst, "{}", as_json(&data))
writeln!(&mut self.dst, "{}", serde_json::to_string(&data).unwrap())
}
.and_then(|_| self.dst.flush());
if let Err(e) = result {
@ -204,7 +204,7 @@ impl Emitter for JsonEmitter {
// The following data types are provided just for serialisation.
#[derive(Encodable)]
#[derive(Serialize)]
struct Diagnostic {
/// The primary error message.
message: String,
@ -218,7 +218,7 @@ struct Diagnostic {
rendered: Option<String>,
}
#[derive(Encodable)]
#[derive(Serialize)]
struct DiagnosticSpan {
file_name: String,
byte_start: u32,
@ -245,7 +245,7 @@ struct DiagnosticSpan {
expansion: Option<Box<DiagnosticSpanMacroExpansion>>,
}
#[derive(Encodable)]
#[derive(Serialize)]
struct DiagnosticSpanLine {
text: String,
@ -255,7 +255,7 @@ struct DiagnosticSpanLine {
highlight_end: usize,
}
#[derive(Encodable)]
#[derive(Serialize)]
struct DiagnosticSpanMacroExpansion {
/// span where macro was applied to generate this code; note that
/// this may itself derive from a macro (if
@ -269,7 +269,7 @@ struct DiagnosticSpanMacroExpansion {
def_site_span: DiagnosticSpan,
}
#[derive(Encodable)]
#[derive(Serialize)]
struct DiagnosticCode {
/// The code itself.
code: String,
@ -277,7 +277,7 @@ struct DiagnosticCode {
explanation: Option<&'static str>,
}
#[derive(Encodable)]
#[derive(Serialize)]
struct ArtifactNotification<'a> {
/// The path of the artifact.
artifact: &'a Path,
@ -285,12 +285,12 @@ struct ArtifactNotification<'a> {
emit: &'a str,
}
#[derive(Encodable)]
#[derive(Serialize)]
struct FutureBreakageItem {
diagnostic: Diagnostic,
}
#[derive(Encodable)]
#[derive(Serialize)]
struct FutureIncompatReport {
future_incompat_report: Vec<FutureBreakageItem>,
}
@ -299,7 +299,7 @@ struct FutureIncompatReport {
// doctest component (as well as cargo).
// We could unify this struct the one in rustdoc but they have different
// ownership semantics, so doing so would create wasteful allocations.
#[derive(Encodable)]
#[derive(Serialize)]
struct UnusedExterns<'a, 'b, 'c> {
/// The severity level of the unused dependencies lint
lint_level: &'a str,

View File

@ -5,12 +5,18 @@ use rustc_span::source_map::{FilePathMapping, SourceMap};
use crate::emitter::{ColorConfig, HumanReadableErrorType};
use crate::Handler;
use rustc_serialize::json;
use rustc_span::{BytePos, Span};
use std::str;
#[derive(Debug, PartialEq, Eq)]
use serde::Deserialize;
#[derive(Deserialize, Debug, PartialEq, Eq)]
struct TestData {
spans: Vec<SpanTestData>,
}
#[derive(Deserialize, Debug, PartialEq, Eq)]
struct SpanTestData {
pub byte_start: u32,
pub byte_end: u32,
@ -61,19 +67,11 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) {
let bytes = output.lock().unwrap();
let actual_output = str::from_utf8(&bytes).unwrap();
let actual_output = json::from_str(&actual_output).unwrap();
let spans = actual_output["spans"].as_array().unwrap();
let actual_output: TestData = serde_json::from_str(actual_output).unwrap();
let spans = actual_output.spans;
assert_eq!(spans.len(), 1);
let obj = &spans[0];
let actual_output = SpanTestData {
byte_start: obj["byte_start"].as_u64().unwrap() as u32,
byte_end: obj["byte_end"].as_u64().unwrap() as u32,
line_start: obj["line_start"].as_u64().unwrap() as u32,
line_end: obj["line_end"].as_u64().unwrap() as u32,
column_start: obj["column_start"].as_u64().unwrap() as u32,
column_end: obj["column_end"].as_u64().unwrap() as u32,
};
assert_eq!(expected_output, actual_output);
assert_eq!(expected_output, spans[0])
})
}

View File

@ -4,6 +4,7 @@ version = "0.0.0"
edition = "2021"
[dependencies]
serde = { version = "1.0.125", features = ["derive"] }
rustc_ast = { path = "../rustc_ast" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_error_messages = { path = "../rustc_error_messages" }

View File

@ -14,6 +14,8 @@ use rustc_span::edition::Edition;
use rustc_span::{sym, symbol::Ident, Span, Symbol};
use rustc_target::spec::abi::Abi;
use serde::{Deserialize, Serialize};
pub mod builtin;
#[macro_export]
@ -34,7 +36,7 @@ macro_rules! pluralize {
/// All suggestions are marked with an `Applicability`. Tools use the applicability of a suggestion
/// to determine whether it should be automatically applied or if the user should be consulted
/// before applying the suggestion.
#[derive(Copy, Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
#[derive(Copy, Clone, Debug, PartialEq, Hash, Encodable, Decodable, Serialize, Deserialize)]
pub enum Applicability {
/// The suggestion is definitely what the user intended, or maintains the exact meaning of the code.
/// This suggestion should be automatically applied.