-
Notifications
You must be signed in to change notification settings - Fork 91
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #64 from konstin/parse_messages
Add message-format=json support, second take
- Loading branch information
Showing
6 changed files
with
345 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
//! This module contains `Diagnostic` and the types/functions it uses for deserialization. | ||
|
||
use std::fmt; | ||
|
||
/// The error code associated to this diagnostic. | ||
#[derive(Debug, Clone, Serialize, Deserialize)] | ||
pub struct DiagnosticCode { | ||
/// The code itself. | ||
pub code: String, | ||
/// An explanation for the code | ||
pub explanation: Option<String>, | ||
#[doc(hidden)] | ||
#[serde(skip)] | ||
__do_not_match_exhaustively: (), | ||
} | ||
|
||
/// A line of code associated with the Diagnostic | ||
#[derive(Debug, Clone, Serialize, Deserialize)] | ||
pub struct DiagnosticSpanLine { | ||
/// The line of code associated with the error | ||
pub text: String, | ||
/// Start of the section of the line to highlight. 1-based, character offset in self.text | ||
pub highlight_start: usize, | ||
/// End of the section of the line to highlight. 1-based, character offset in self.text | ||
pub highlight_end: usize, | ||
#[doc(hidden)] | ||
#[serde(skip)] | ||
__do_not_match_exhaustively: (), | ||
} | ||
|
||
/// Macro expansion information associated with a diagnostic. | ||
#[derive(Debug, Clone, Serialize, Deserialize)] | ||
pub struct DiagnosticSpanMacroExpansion { | ||
/// span where macro was applied to generate this code; note that | ||
/// this may itself derive from a macro (if | ||
/// `span.expansion.is_some()`) | ||
pub span: DiagnosticSpan, | ||
|
||
/// name of macro that was applied (e.g., "foo!" or "#[derive(Eq)]") | ||
pub macro_decl_name: String, | ||
|
||
/// span where macro was defined (if known) | ||
pub def_site_span: Option<DiagnosticSpan>, | ||
#[doc(hidden)] | ||
#[serde(skip)] | ||
__do_not_match_exhaustively: (), | ||
} | ||
|
||
/// A section of the source code associated with a Diagnostic | ||
#[derive(Debug, Clone, Serialize, Deserialize)] | ||
pub struct DiagnosticSpan { | ||
/// The file name or the macro name this diagnostic comes from. | ||
pub file_name: String, | ||
/// The byte offset in the file where this diagnostic starts from. | ||
pub byte_start: u32, | ||
/// The byte offset in the file where this diagnostic ends. | ||
pub byte_end: u32, | ||
/// 1-based. The line in the file. | ||
pub line_start: usize, | ||
/// 1-based. The line in the file. | ||
pub line_end: usize, | ||
/// 1-based, character offset. | ||
pub column_start: usize, | ||
/// 1-based, character offset. | ||
pub column_end: usize, | ||
/// Is this a "primary" span -- meaning the point, or one of the points, | ||
/// where the error occurred? | ||
/// | ||
/// There are rare cases where multiple spans are marked as primary, | ||
/// e.g. "immutable borrow occurs here" and "mutable borrow ends here" can | ||
/// be two separate spans both "primary". Top (parent) messages should | ||
/// always have at least one primary span, unless it has 0 spans. Child | ||
/// messages may have 0 or more primary spans. | ||
pub is_primary: bool, | ||
/// Source text from the start of line_start to the end of line_end. | ||
pub text: Vec<DiagnosticSpanLine>, | ||
/// Label that should be placed at this location (if any) | ||
pub label: Option<String>, | ||
/// If we are suggesting a replacement, this will contain text | ||
/// that should be sliced in atop this span. | ||
pub suggested_replacement: Option<String>, | ||
/// If the suggestion is approximate | ||
pub suggestion_applicability: Option<Applicability>, | ||
/// Macro invocations that created the code at this span, if any. | ||
pub expansion: Option<Box<DiagnosticSpanMacroExpansion>>, | ||
#[doc(hidden)] | ||
#[serde(skip)] | ||
__do_not_match_exhaustively: (), | ||
} | ||
|
||
/// Whether a suggestion can be safely applied. | ||
#[derive(Debug, Clone, Serialize, Deserialize)] | ||
pub enum Applicability { | ||
/// The suggested replacement can be applied automatically safely | ||
MachineApplicable, | ||
/// The suggested replacement has placeholders that will need to be manually | ||
/// replaced. | ||
HasPlaceholders, | ||
/// The suggested replacement may be incorrect in some circumstances. Needs | ||
/// human review. | ||
MaybeIncorrect, | ||
/// The suggested replacement will probably not work. | ||
Unspecified, | ||
#[doc(hidden)] | ||
#[serde(other)] | ||
Unknown, | ||
} | ||
|
||
/// The diagnostic level | ||
#[derive(Debug, Clone, Copy, Serialize, Deserialize)] | ||
#[serde(rename_all = "lowercase")] | ||
pub enum DiagnosticLevel { | ||
/// Internal compiler error | ||
#[serde(rename = "error: internal compiler error")] | ||
Ice, | ||
/// Error | ||
Error, | ||
/// Warning | ||
Warning, | ||
/// Note | ||
Note, | ||
/// Help | ||
Help, | ||
#[doc(hidden)] | ||
#[serde(other)] | ||
Unknown, | ||
} | ||
|
||
/// A diagnostic message generated by rustc | ||
#[derive(Debug, Clone, Serialize, Deserialize)] | ||
pub struct Diagnostic { | ||
/// The error message of this diagnostic. | ||
pub message: String, | ||
/// The associated error code for this diagnostic | ||
pub code: Option<DiagnosticCode>, | ||
/// "error: internal compiler error", "error", "warning", "note", "help" | ||
pub level: DiagnosticLevel, | ||
/// A list of source code spans this diagnostic is associated with. | ||
pub spans: Vec<DiagnosticSpan>, | ||
/// Associated diagnostic messages. | ||
pub children: Vec<Diagnostic>, | ||
/// The message as rustc would render it | ||
pub rendered: Option<String>, | ||
#[doc(hidden)] | ||
#[serde(skip)] | ||
__do_not_match_exhaustively: (), | ||
} | ||
|
||
impl fmt::Display for Diagnostic { | ||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
if let Some(ref rendered) = self.rendered { | ||
f.write_str(rendered)?; | ||
} else { | ||
f.write_str("cargo didn't render this message")?; | ||
} | ||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
use super::{Diagnostic, PackageId, Target}; | ||
use serde_json; | ||
use std::fmt; | ||
use std::io::Read; | ||
use std::path::PathBuf; | ||
|
||
/// Profile settings used to determine which compiler flags to use for a | ||
/// target. | ||
#[derive(Debug, Clone, Serialize, Deserialize)] | ||
pub struct ArtifactProfile { | ||
/// Optimization level. Possible values are 0-3, s or z. | ||
pub opt_level: String, | ||
/// The amount of debug info. 0 for none, 1 for limited, 2 for full | ||
pub debuginfo: Option<u32>, | ||
/// State of the `cfg(debug_assertions)` directive, enabling macros like | ||
/// `debug_assert!` | ||
pub debug_assertions: bool, | ||
/// State of the overflow checks. | ||
pub overflow_checks: bool, | ||
/// Whether this profile is a test | ||
pub test: bool, | ||
#[doc(hidden)] | ||
#[serde(skip)] | ||
__do_not_match_exhaustively: (), | ||
} | ||
|
||
/// A compiler-generated file. | ||
#[derive(Debug, Clone, Serialize, Deserialize)] | ||
pub struct Artifact { | ||
/// The package this artifact belongs to | ||
pub package_id: PackageId, | ||
/// The target this artifact was compiled for | ||
pub target: Target, | ||
/// The profile this artifact was compiled with | ||
pub profile: ArtifactProfile, | ||
/// The enabled features for this artifact | ||
pub features: Vec<String>, | ||
/// The full paths to the generated artifacts | ||
pub filenames: Vec<PathBuf>, | ||
/// If true, then the files were already generated | ||
pub fresh: bool, | ||
#[doc(hidden)] | ||
#[serde(skip)] | ||
__do_not_match_exhaustively: (), | ||
} | ||
|
||
/// Message left by the compiler | ||
// TODO: Better name. This one comes from machine_message.rs | ||
#[derive(Debug, Clone, Serialize, Deserialize)] | ||
pub struct CompilerMessage { | ||
/// The package this message belongs to | ||
pub package_id: PackageId, | ||
/// The target this message is aimed at | ||
pub target: Target, | ||
/// The message the compiler sent. | ||
pub message: Diagnostic, | ||
#[doc(hidden)] | ||
#[serde(skip)] | ||
__do_not_match_exhaustively: (), | ||
} | ||
|
||
/// Output of a build script execution. | ||
#[derive(Debug, Clone, Serialize, Deserialize)] | ||
pub struct BuildScript { | ||
/// The package this build script execution belongs to | ||
pub package_id: PackageId, | ||
/// The libs to link | ||
pub linked_libs: Vec<PathBuf>, | ||
/// The paths to search when resolving libs | ||
pub linked_paths: Vec<PathBuf>, | ||
/// Various `--cfg` flags to pass to the compiler | ||
pub cfgs: Vec<PathBuf>, | ||
/// The environment variables to add to the compilation | ||
pub env: Vec<(String, String)>, | ||
#[doc(hidden)] | ||
#[serde(skip)] | ||
__do_not_match_exhaustively: (), | ||
} | ||
|
||
/// A cargo message | ||
#[derive(Debug, Clone, Serialize, Deserialize)] | ||
#[serde(tag = "reason", rename_all = "kebab-case")] | ||
pub enum Message { | ||
/// The compiler generated an artifact | ||
CompilerArtifact(Artifact), | ||
/// The compiler wants to display a message | ||
CompilerMessage(CompilerMessage), | ||
/// A build script successfully executed. | ||
BuildScriptExecuted(BuildScript), | ||
#[doc(hidden)] | ||
#[serde(other)] | ||
Unknown, | ||
} | ||
|
||
impl fmt::Display for CompilerMessage { | ||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
write!(f, "{}", self.message) | ||
} | ||
} | ||
|
||
/// An iterator of Message. | ||
type MessageIterator<R> = | ||
serde_json::StreamDeserializer<'static, serde_json::de::IoRead<R>, Message>; | ||
|
||
/// Creates an iterator of Message from a Read outputting a stream of JSON | ||
/// messages. For usage information, look at the top-level documentation. | ||
pub fn parse_messages<R: Read>(input: R) -> MessageIterator<R> { | ||
serde_json::Deserializer::from_reader(input).into_iter::<Message>() | ||
} |
Oops, something went wrong.