/src/librustc_save_analysis/json_dumper.rs
https://gitlab.com/alx741/rust · Rust · 651 lines · 542 code · 82 blank · 27 comment · 32 complexity · 03c09b38cdf0b57e1b2b0e053f12989f MD5 · raw file
- // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
- // file at the top-level directory of this distribution and at
- // http://rust-lang.org/COPYRIGHT.
- //
- // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
- // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
- // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
- // option. This file may not be copied, modified, or distributed
- // except according to those terms.
- use std::io::Write;
- use rustc_serialize::json::as_json;
- use syntax::codemap::CodeMap;
- use syntax::ast::CrateNum;
- use super::data::{self, SpanData};
- use super::dump::Dump;
- pub struct JsonDumper<'a, 'b, W: Write + 'b> {
- output: &'b mut W,
- codemap: &'a CodeMap,
- first: bool,
- }
- impl<'a, 'b, W: Write> JsonDumper<'a, 'b, W> {
- pub fn new(writer: &'b mut W, codemap: &'a CodeMap) -> JsonDumper<'a, 'b, W> {
- if let Err(_) = write!(writer, "[") {
- error!("Error writing output");
- }
- JsonDumper { output: writer, codemap:codemap, first: true }
- }
- }
- impl<'a, 'b, W: Write> Drop for JsonDumper<'a, 'b, W> {
- fn drop(&mut self) {
- if let Err(_) = write!(self.output, "]") {
- error!("Error writing output");
- }
- }
- }
- macro_rules! impl_fn {
- ($fn_name: ident, $data_type: ident) => {
- fn $fn_name(&mut self, data: data::$data_type) {
- if self.first {
- self.first = false;
- } else {
- if let Err(_) = write!(self.output, ",") {
- error!("Error writing output");
- }
- }
- let data = data.lower(self.codemap);
- if let Err(_) = write!(self.output, "{}", as_json(&data)) {
- error!("Error writing output '{}'", as_json(&data));
- }
- }
- }
- }
- impl<'a, 'b, W: Write + 'b> Dump for JsonDumper<'a, 'b, W> {
- impl_fn!(crate_prelude, CratePreludeData);
- impl_fn!(enum_data, EnumData);
- impl_fn!(extern_crate, ExternCrateData);
- impl_fn!(impl_data, ImplData);
- impl_fn!(inheritance, InheritanceData);
- impl_fn!(function, FunctionData);
- impl_fn!(function_ref, FunctionRefData);
- impl_fn!(function_call, FunctionCallData);
- impl_fn!(method, MethodData);
- impl_fn!(method_call, MethodCallData);
- impl_fn!(macro_data, MacroData);
- impl_fn!(macro_use, MacroUseData);
- impl_fn!(mod_data, ModData);
- impl_fn!(mod_ref, ModRefData);
- impl_fn!(struct_data, StructData);
- impl_fn!(struct_variant, StructVariantData);
- impl_fn!(trait_data, TraitData);
- impl_fn!(tuple_variant, TupleVariantData);
- impl_fn!(type_ref, TypeRefData);
- impl_fn!(typedef, TypedefData);
- impl_fn!(use_data, UseData);
- impl_fn!(use_glob, UseGlobData);
- impl_fn!(variable, VariableData);
- impl_fn!(variable_ref, VariableRefData);
- }
- trait Lower {
- type Target;
- fn lower(self, cm: &CodeMap) -> Self::Target;
- }
- pub type Id = u32;
- #[derive(Debug, RustcEncodable)]
- pub struct CratePreludeData {
- pub crate_name: String,
- pub crate_root: String,
- pub external_crates: Vec<data::ExternalCrateData>,
- pub span: SpanData,
- }
- impl Lower for data::CratePreludeData {
- type Target = CratePreludeData;
- fn lower(self, cm: &CodeMap) -> CratePreludeData {
- CratePreludeData {
- crate_name: self.crate_name,
- crate_root: self.crate_root,
- external_crates: self.external_crates,
- span: SpanData::from_span(self.span, cm),
- }
- }
- }
- /// Data for enum declarations.
- #[derive(Clone, Debug, RustcEncodable)]
- pub struct EnumData {
- pub id: Id,
- pub value: String,
- pub qualname: String,
- pub span: SpanData,
- pub scope: Id,
- }
- impl Lower for data::EnumData {
- type Target = EnumData;
- fn lower(self, cm: &CodeMap) -> EnumData {
- EnumData {
- id: self.id,
- value: self.value,
- qualname: self.qualname,
- span: SpanData::from_span(self.span, cm),
- scope: self.scope,
- }
- }
- }
- /// Data for extern crates.
- #[derive(Debug, RustcEncodable)]
- pub struct ExternCrateData {
- pub id: Id,
- pub name: String,
- pub crate_num: CrateNum,
- pub location: String,
- pub span: SpanData,
- pub scope: Id,
- }
- impl Lower for data::ExternCrateData {
- type Target = ExternCrateData;
- fn lower(self, cm: &CodeMap) -> ExternCrateData {
- ExternCrateData {
- id: self.id,
- name: self.name,
- crate_num: self.crate_num,
- location: self.location,
- span: SpanData::from_span(self.span, cm),
- scope: self.scope,
- }
- }
- }
- /// Data about a function call.
- #[derive(Debug, RustcEncodable)]
- pub struct FunctionCallData {
- pub span: SpanData,
- pub scope: Id,
- pub ref_id: Id,
- }
- impl Lower for data::FunctionCallData {
- type Target = FunctionCallData;
- fn lower(self, cm: &CodeMap) -> FunctionCallData {
- FunctionCallData {
- span: SpanData::from_span(self.span, cm),
- scope: self.scope,
- ref_id: self.ref_id.index.as_u32(),
- }
- }
- }
- /// Data for all kinds of functions and methods.
- #[derive(Clone, Debug, RustcEncodable)]
- pub struct FunctionData {
- pub id: Id,
- pub name: String,
- pub qualname: String,
- pub declaration: Option<Id>,
- pub span: SpanData,
- pub scope: Id,
- }
- impl Lower for data::FunctionData {
- type Target = FunctionData;
- fn lower(self, cm: &CodeMap) -> FunctionData {
- FunctionData {
- id: self.id,
- name: self.name,
- qualname: self.qualname,
- declaration: self.declaration.map(|id| id.index.as_u32()),
- span: SpanData::from_span(self.span, cm),
- scope: self.scope,
- }
- }
- }
- /// Data about a function call.
- #[derive(Debug, RustcEncodable)]
- pub struct FunctionRefData {
- pub span: SpanData,
- pub scope: Id,
- pub ref_id: Id,
- }
- impl Lower for data::FunctionRefData {
- type Target = FunctionRefData;
- fn lower(self, cm: &CodeMap) -> FunctionRefData {
- FunctionRefData {
- span: SpanData::from_span(self.span, cm),
- scope: self.scope,
- ref_id: self.ref_id.index.as_u32(),
- }
- }
- }
- #[derive(Debug, RustcEncodable)]
- pub struct ImplData {
- pub id: Id,
- pub span: SpanData,
- pub scope: Id,
- pub trait_ref: Option<Id>,
- pub self_ref: Option<Id>,
- }
- impl Lower for data::ImplData {
- type Target = ImplData;
- fn lower(self, cm: &CodeMap) -> ImplData {
- ImplData {
- id: self.id,
- span: SpanData::from_span(self.span, cm),
- scope: self.scope,
- trait_ref: self.trait_ref.map(|id| id.index.as_u32()),
- self_ref: self.self_ref.map(|id| id.index.as_u32()),
- }
- }
- }
- #[derive(Debug, RustcEncodable)]
- pub struct InheritanceData {
- pub span: SpanData,
- pub base_id: Id,
- pub deriv_id: Id
- }
- impl Lower for data::InheritanceData {
- type Target = InheritanceData;
- fn lower(self, cm: &CodeMap) -> InheritanceData {
- InheritanceData {
- span: SpanData::from_span(self.span, cm),
- base_id: self.base_id.index.as_u32(),
- deriv_id: self.deriv_id
- }
- }
- }
- /// Data about a macro declaration.
- #[derive(Debug, RustcEncodable)]
- pub struct MacroData {
- pub span: SpanData,
- pub name: String,
- pub qualname: String,
- }
- impl Lower for data::MacroData {
- type Target = MacroData;
- fn lower(self, cm: &CodeMap) -> MacroData {
- MacroData {
- span: SpanData::from_span(self.span, cm),
- name: self.name,
- qualname: self.qualname,
- }
- }
- }
- /// Data about a macro use.
- #[derive(Debug, RustcEncodable)]
- pub struct MacroUseData {
- pub span: SpanData,
- pub name: String,
- pub qualname: String,
- // Because macro expansion happens before ref-ids are determined,
- // we use the callee span to reference the associated macro definition.
- pub callee_span: SpanData,
- pub scope: Id,
- pub imported: bool,
- }
- impl Lower for data::MacroUseData {
- type Target = MacroUseData;
- fn lower(self, cm: &CodeMap) -> MacroUseData {
- MacroUseData {
- span: SpanData::from_span(self.span, cm),
- name: self.name,
- qualname: self.qualname,
- callee_span: SpanData::from_span(self.callee_span, cm),
- scope: self.scope,
- imported: self.imported,
- }
- }
- }
- /// Data about a method call.
- #[derive(Debug, RustcEncodable)]
- pub struct MethodCallData {
- pub span: SpanData,
- pub scope: Id,
- pub ref_id: Option<Id>,
- pub decl_id: Option<Id>,
- }
- impl Lower for data::MethodCallData {
- type Target = MethodCallData;
- fn lower(self, cm: &CodeMap) -> MethodCallData {
- MethodCallData {
- span: SpanData::from_span(self.span, cm),
- scope: self.scope,
- ref_id: self.ref_id.map(|id| id.index.as_u32()),
- decl_id: self.decl_id.map(|id| id.index.as_u32()),
- }
- }
- }
- /// Data for method declarations (methods with a body are treated as functions).
- #[derive(Clone, Debug, RustcEncodable)]
- pub struct MethodData {
- pub id: Id,
- pub qualname: String,
- pub span: SpanData,
- pub scope: Id,
- }
- impl Lower for data::MethodData {
- type Target = MethodData;
- fn lower(self, cm: &CodeMap) -> MethodData {
- MethodData {
- span: SpanData::from_span(self.span, cm),
- scope: self.scope,
- id: self.id,
- qualname: self.qualname,
- }
- }
- }
- /// Data for modules.
- #[derive(Debug, RustcEncodable)]
- pub struct ModData {
- pub id: Id,
- pub name: String,
- pub qualname: String,
- pub span: SpanData,
- pub scope: Id,
- pub filename: String,
- }
- impl Lower for data::ModData {
- type Target = ModData;
- fn lower(self, cm: &CodeMap) -> ModData {
- ModData {
- id: self.id,
- name: self.name,
- qualname: self.qualname,
- span: SpanData::from_span(self.span, cm),
- scope: self.scope,
- filename: self.filename,
- }
- }
- }
- /// Data for a reference to a module.
- #[derive(Debug, RustcEncodable)]
- pub struct ModRefData {
- pub span: SpanData,
- pub scope: Id,
- pub ref_id: Option<Id>,
- pub qualname: String
- }
- impl Lower for data::ModRefData {
- type Target = ModRefData;
- fn lower(self, cm: &CodeMap) -> ModRefData {
- ModRefData {
- span: SpanData::from_span(self.span, cm),
- scope: self.scope,
- ref_id: self.ref_id.map(|id| id.index.as_u32()),
- qualname: self.qualname,
- }
- }
- }
- #[derive(Debug, RustcEncodable)]
- pub struct StructData {
- pub span: SpanData,
- pub id: Id,
- pub ctor_id: Id,
- pub qualname: String,
- pub scope: Id,
- pub value: String
- }
- impl Lower for data::StructData {
- type Target = StructData;
- fn lower(self, cm: &CodeMap) -> StructData {
- StructData {
- span: SpanData::from_span(self.span, cm),
- id: self.id,
- ctor_id: self.ctor_id,
- qualname: self.qualname,
- scope: self.scope,
- value: self.value
- }
- }
- }
- #[derive(Debug, RustcEncodable)]
- pub struct StructVariantData {
- pub span: SpanData,
- pub id: Id,
- pub qualname: String,
- pub type_value: String,
- pub value: String,
- pub scope: Id
- }
- impl Lower for data::StructVariantData {
- type Target = StructVariantData;
- fn lower(self, cm: &CodeMap) -> StructVariantData {
- StructVariantData {
- span: SpanData::from_span(self.span, cm),
- id: self.id,
- qualname: self.qualname,
- type_value: self.type_value,
- value: self.value,
- scope: self.scope,
- }
- }
- }
- #[derive(Debug, RustcEncodable)]
- pub struct TraitData {
- pub span: SpanData,
- pub id: Id,
- pub qualname: String,
- pub scope: Id,
- pub value: String
- }
- impl Lower for data::TraitData {
- type Target = TraitData;
- fn lower(self, cm: &CodeMap) -> TraitData {
- TraitData {
- span: SpanData::from_span(self.span, cm),
- id: self.id,
- qualname: self.qualname,
- scope: self.scope,
- value: self.value,
- }
- }
- }
- #[derive(Debug, RustcEncodable)]
- pub struct TupleVariantData {
- pub span: SpanData,
- pub id: Id,
- pub name: String,
- pub qualname: String,
- pub type_value: String,
- pub value: String,
- pub scope: Id,
- }
- impl Lower for data::TupleVariantData {
- type Target = TupleVariantData;
- fn lower(self, cm: &CodeMap) -> TupleVariantData {
- TupleVariantData {
- span: SpanData::from_span(self.span, cm),
- id: self.id,
- name: self.name,
- qualname: self.qualname,
- type_value: self.type_value,
- value: self.value,
- scope: self.scope,
- }
- }
- }
- /// Data for a typedef.
- #[derive(Debug, RustcEncodable)]
- pub struct TypedefData {
- pub id: Id,
- pub span: SpanData,
- pub qualname: String,
- pub value: String,
- }
- impl Lower for data::TypedefData {
- type Target = TypedefData;
- fn lower(self, cm: &CodeMap) -> TypedefData {
- TypedefData {
- id: self.id,
- span: SpanData::from_span(self.span, cm),
- qualname: self.qualname,
- value: self.value,
- }
- }
- }
- /// Data for a reference to a type or trait.
- #[derive(Clone, Debug, RustcEncodable)]
- pub struct TypeRefData {
- pub span: SpanData,
- pub scope: Id,
- pub ref_id: Option<Id>,
- pub qualname: String,
- }
- impl Lower for data::TypeRefData {
- type Target = TypeRefData;
- fn lower(self, cm: &CodeMap) -> TypeRefData {
- TypeRefData {
- span: SpanData::from_span(self.span, cm),
- scope: self.scope,
- ref_id: self.ref_id.map(|id| id.index.as_u32()),
- qualname: self.qualname,
- }
- }
- }
- #[derive(Debug, RustcEncodable)]
- pub struct UseData {
- pub id: Id,
- pub span: SpanData,
- pub name: String,
- pub mod_id: Option<Id>,
- pub scope: Id
- }
- impl Lower for data::UseData {
- type Target = UseData;
- fn lower(self, cm: &CodeMap) -> UseData {
- UseData {
- id: self.id,
- span: SpanData::from_span(self.span, cm),
- name: self.name,
- mod_id: self.mod_id.map(|id| id.index.as_u32()),
- scope: self.scope,
- }
- }
- }
- #[derive(Debug, RustcEncodable)]
- pub struct UseGlobData {
- pub id: Id,
- pub span: SpanData,
- pub names: Vec<String>,
- pub scope: Id
- }
- impl Lower for data::UseGlobData {
- type Target = UseGlobData;
- fn lower(self, cm: &CodeMap) -> UseGlobData {
- UseGlobData {
- id: self.id,
- span: SpanData::from_span(self.span, cm),
- names: self.names,
- scope: self.scope,
- }
- }
- }
- /// Data for local and global variables (consts and statics).
- #[derive(Debug, RustcEncodable)]
- pub struct VariableData {
- pub id: Id,
- pub name: String,
- pub qualname: String,
- pub span: SpanData,
- pub scope: Id,
- pub value: String,
- pub type_value: String,
- }
- impl Lower for data::VariableData {
- type Target = VariableData;
- fn lower(self, cm: &CodeMap) -> VariableData {
- VariableData {
- id: self.id,
- name: self.name,
- qualname: self.qualname,
- span: SpanData::from_span(self.span, cm),
- scope: self.scope,
- value: self.value,
- type_value: self.type_value,
- }
- }
- }
- /// Data for the use of some item (e.g., the use of a local variable, which
- /// will refer to that variables declaration (by ref_id)).
- #[derive(Debug, RustcEncodable)]
- pub struct VariableRefData {
- pub name: String,
- pub span: SpanData,
- pub scope: Id,
- pub ref_id: Id,
- }
- impl Lower for data::VariableRefData {
- type Target = VariableRefData;
- fn lower(self, cm: &CodeMap) -> VariableRefData {
- VariableRefData {
- name: self.name,
- span: SpanData::from_span(self.span, cm),
- scope: self.scope,
- ref_id: self.ref_id.index.as_u32(),
- }
- }
- }