diff --git a/src/librustc_save_analysis/csv_dumper.rs b/src/librustc_save_analysis/csv_dumper.rs index ac658af4006..e7cc534c5b5 100644 --- a/src/librustc_save_analysis/csv_dumper.rs +++ b/src/librustc_save_analysis/csv_dumper.rs @@ -331,7 +331,7 @@ impl<'b, W: Write + 'b> Dump for CsvDumper<'b, W> { self.record("type_ref", data.span, values); } - fn typedef(&mut self, data: TypedefData) { + fn typedef(&mut self, data: TypeDefData) { let id = data.id.index.as_u32().to_string(); let values = make_values_str(&[ ("id", &id), diff --git a/src/librustc_save_analysis/data.rs b/src/librustc_save_analysis/data.rs index 19f9ba95b35..2275a1c5c65 100644 --- a/src/librustc_save_analysis/data.rs +++ b/src/librustc_save_analysis/data.rs @@ -62,7 +62,7 @@ pub enum Data { /// Data for a tuple variant. TupleVariantData(TupleVariantData), /// Data for a typedef. - TypeDefData(TypedefData), + TypeDefData(TypeDefData), /// Data for a reference to a type or trait. TypeRefData(TypeRefData), /// Data for a use statement. @@ -97,6 +97,7 @@ pub struct ExternalCrateData { #[derive(Clone, Debug, RustcEncodable)] pub struct EnumData { pub id: NodeId, + pub name: String, pub value: String, pub qualname: String, pub span: Span, @@ -131,6 +132,7 @@ pub struct FunctionData { pub declaration: Option, pub span: Span, pub scope: NodeId, + pub value: String, } /// Data about a function call. @@ -205,9 +207,11 @@ pub struct MethodCallData { #[derive(Clone, Debug, RustcEncodable)] pub struct MethodData { pub id: NodeId, + pub name: String, pub qualname: String, pub span: Span, pub scope: NodeId, + pub value: String, } /// Data for modules. @@ -233,6 +237,7 @@ pub struct ModRefData { #[derive(Debug, RustcEncodable)] pub struct StructData { pub span: Span, + pub name: String, pub id: NodeId, pub ctor_id: NodeId, pub qualname: String, @@ -243,6 +248,7 @@ pub struct StructData { #[derive(Debug, RustcEncodable)] pub struct StructVariantData { pub span: Span, + pub name: String, pub id: NodeId, pub qualname: String, pub type_value: String, @@ -254,6 +260,7 @@ pub struct StructVariantData { pub struct TraitData { pub span: Span, pub id: NodeId, + pub name: String, pub qualname: String, pub scope: NodeId, pub value: String @@ -272,8 +279,9 @@ pub struct TupleVariantData { /// Data for a typedef. #[derive(Debug, RustcEncodable)] -pub struct TypedefData { +pub struct TypeDefData { pub id: NodeId, + pub name: String, pub span: Span, pub qualname: String, pub value: String, diff --git a/src/librustc_save_analysis/dump.rs b/src/librustc_save_analysis/dump.rs index adbf1e0a35e..18241b394cc 100644 --- a/src/librustc_save_analysis/dump.rs +++ b/src/librustc_save_analysis/dump.rs @@ -30,7 +30,7 @@ pub trait Dump { fn trait_data(&mut self, TraitData) {} fn tuple_variant(&mut self, TupleVariantData) {} fn type_ref(&mut self, TypeRefData) {} - fn typedef(&mut self, TypedefData) {} + fn typedef(&mut self, TypeDefData) {} fn use_data(&mut self, UseData) {} fn use_glob(&mut self, UseGlobData) {} fn variable(&mut self, VariableData) {} diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index f0dd7b8b9bb..6f84ccc9e36 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -397,9 +397,11 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { if !self.span.filter_generated(Some(method_data.span), span) { self.dumper.method(MethodData { id: method_data.id, + name: method_data.name, span: method_data.span, scope: method_data.scope, qualname: method_data.qualname.clone(), + value: String::new(), // TODO }.lower(self.tcx)); } } @@ -455,16 +457,18 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { let param_sub_spans = self.span.spans_for_ty_params(full_span, (generics.ty_params.len() as isize)); for (param, param_ss) in generics.ty_params.iter().zip(param_sub_spans) { + let name = escape(self.span.snippet(param_ss)); // Append $id to name to make sure each one is unique - let name = format!("{}::{}${}", - prefix, - escape(self.span.snippet(param_ss)), - id); + let qualname = format!("{}::{}${}", + prefix, + name, + id); if !self.span.filter_generated(Some(param_ss), full_span) { - self.dumper.typedef(TypedefData { + self.dumper.typedef(TypeDefData { span: param_ss, + name: name, id: param.id, - qualname: name, + qualname: qualname, value: String::new() }.lower(self.tcx)); } @@ -548,6 +552,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { self.dumper.struct_data(StructData { span: sub_span.expect("No span found for struct"), id: item.id, + name: item.ident.to_string(), ctor_id: def.id(), qualname: qualname.clone(), scope: self.cur_scope, @@ -580,10 +585,10 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { } for variant in &enum_definition.variants { - let name = &variant.node.name.name.as_str(); + let name = variant.node.name.name.to_string(); let mut qualname = enum_data.qualname.clone(); qualname.push_str("::"); - qualname.push_str(name); + qualname.push_str(&name); let val = self.span.snippet(variant.span); match variant.node.data { @@ -593,6 +598,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { self.dumper.struct_variant(StructVariantData { span: sub_span.expect("No span found for struct variant"), id: variant.node.data.id(), + name: name, qualname: qualname, type_value: enum_data.qualname.clone(), value: val, @@ -679,6 +685,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { self.dumper.trait_data(TraitData { span: sub_span.expect("No span found for trait"), id: item.id, + name: item.ident.to_string(), qualname: qualname.clone(), scope: self.cur_scope, value: val @@ -1107,8 +1114,9 @@ impl<'v, 'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'v> for DumpVisitor<'l, 'tcx, let value = ty_to_string(&ty); let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Type); if !self.span.filter_generated(sub_span, item.span) { - self.dumper.typedef(TypedefData { + self.dumper.typedef(TypeDefData { span: sub_span.expect("No span found for typedef"), + name: item.ident.to_string(), id: item.id, qualname: qualname.clone(), value: value diff --git a/src/librustc_save_analysis/external_data.rs b/src/librustc_save_analysis/external_data.rs index 51134f8383b..dc51c41f296 100644 --- a/src/librustc_save_analysis/external_data.rs +++ b/src/librustc_save_analysis/external_data.rs @@ -86,6 +86,7 @@ impl Lower for data::CratePreludeData { pub struct EnumData { pub id: DefId, pub value: String, + pub name: String, pub qualname: String, pub span: SpanData, pub scope: DefId, @@ -97,6 +98,7 @@ impl Lower for data::EnumData { fn lower(self, tcx: TyCtxt) -> EnumData { EnumData { id: make_def_id(self.id, &tcx.map), + name: self.name, value: self.value, qualname: self.qualname, span: SpanData::from_span(self.span, tcx.sess.codemap()), @@ -160,6 +162,7 @@ pub struct FunctionData { pub declaration: Option, pub span: SpanData, pub scope: DefId, + pub value: String, } impl Lower for data::FunctionData { @@ -173,6 +176,7 @@ impl Lower for data::FunctionData { declaration: self.declaration, span: SpanData::from_span(self.span, tcx.sess.codemap()), scope: make_def_id(self.scope, &tcx.map), + value: self.value, } } } @@ -268,7 +272,6 @@ pub struct MacroUseData { // we use the callee span to reference the associated macro definition. pub callee_span: SpanData, pub scope: DefId, - pub imported: bool, } impl Lower for data::MacroUseData { @@ -281,7 +284,6 @@ impl Lower for data::MacroUseData { qualname: self.qualname, callee_span: SpanData::from_span(self.callee_span, tcx.sess.codemap()), scope: make_def_id(self.scope, &tcx.map), - imported: self.imported, } } } @@ -312,9 +314,11 @@ impl Lower for data::MethodCallData { #[derive(Clone, Debug, RustcEncodable)] pub struct MethodData { pub id: DefId, + pub name: String, pub qualname: String, pub span: SpanData, pub scope: DefId, + pub value: String, } impl Lower for data::MethodData { @@ -323,9 +327,11 @@ impl Lower for data::MethodData { fn lower(self, tcx: TyCtxt) -> MethodData { MethodData { span: SpanData::from_span(self.span, tcx.sess.codemap()), + name: self.name, scope: make_def_id(self.scope, &tcx.map), id: make_def_id(self.id, &tcx.map), qualname: self.qualname, + value: self.value, } } } @@ -381,6 +387,7 @@ impl Lower for data::ModRefData { #[derive(Debug, RustcEncodable)] pub struct StructData { pub span: SpanData, + pub name: String, pub id: DefId, pub ctor_id: DefId, pub qualname: String, @@ -394,6 +401,7 @@ impl Lower for data::StructData { fn lower(self, tcx: TyCtxt) -> StructData { StructData { span: SpanData::from_span(self.span, tcx.sess.codemap()), + name: self.name, id: make_def_id(self.id, &tcx.map), ctor_id: make_def_id(self.ctor_id, &tcx.map), qualname: self.qualname, @@ -406,6 +414,7 @@ impl Lower for data::StructData { #[derive(Debug, RustcEncodable)] pub struct StructVariantData { pub span: SpanData, + pub name: String, pub id: DefId, pub qualname: String, pub type_value: String, @@ -419,6 +428,7 @@ impl Lower for data::StructVariantData { fn lower(self, tcx: TyCtxt) -> StructVariantData { StructVariantData { span: SpanData::from_span(self.span, tcx.sess.codemap()), + name: self.name, id: make_def_id(self.id, &tcx.map), qualname: self.qualname, type_value: self.type_value, @@ -431,6 +441,7 @@ impl Lower for data::StructVariantData { #[derive(Debug, RustcEncodable)] pub struct TraitData { pub span: SpanData, + pub name: String, pub id: DefId, pub qualname: String, pub scope: DefId, @@ -443,6 +454,7 @@ impl Lower for data::TraitData { fn lower(self, tcx: TyCtxt) -> TraitData { TraitData { span: SpanData::from_span(self.span, tcx.sess.codemap()), + name: self.name, id: make_def_id(self.id, &tcx.map), qualname: self.qualname, scope: make_def_id(self.scope, &tcx.map), @@ -480,19 +492,21 @@ impl Lower for data::TupleVariantData { /// Data for a typedef. #[derive(Debug, RustcEncodable)] -pub struct TypedefData { +pub struct TypeDefData { pub id: DefId, + pub name: String, pub span: SpanData, pub qualname: String, pub value: String, } -impl Lower for data::TypedefData { - type Target = TypedefData; +impl Lower for data::TypeDefData { + type Target = TypeDefData; - fn lower(self, tcx: TyCtxt) -> TypedefData { - TypedefData { + fn lower(self, tcx: TyCtxt) -> TypeDefData { + TypeDefData { id: make_def_id(self.id, &tcx.map), + name: self.name, span: SpanData::from_span(self.span, tcx.sess.codemap()), qualname: self.qualname, value: self.value, diff --git a/src/librustc_save_analysis/json_dumper.rs b/src/librustc_save_analysis/json_dumper.rs index 9ad2bcef4ed..156a6f5cc97 100644 --- a/src/librustc_save_analysis/json_dumper.rs +++ b/src/librustc_save_analysis/json_dumper.rs @@ -10,6 +10,7 @@ use std::io::Write; +use rustc::hir::def_id::DefId; use rustc_serialize::json::as_json; use super::external_data::*; @@ -17,66 +18,394 @@ use super::dump::Dump; pub struct JsonDumper<'b, W: Write + 'b> { output: &'b mut W, - first: bool, + result: Analysis, } impl<'b, W: Write> JsonDumper<'b, W> { pub fn new(writer: &'b mut W) -> JsonDumper<'b, W> { - if let Err(_) = write!(writer, "[") { - error!("Error writing output"); - } - JsonDumper { output: writer, first: true } + JsonDumper { output: writer, result: Analysis::new() } } } impl<'b, W: Write> Drop for JsonDumper<'b, W> { fn drop(&mut self) { - if let Err(_) = write!(self.output, "]") { + if let Err(_) = write!(self.output, "{}", as_json(&self.result)) { error!("Error writing output"); } } } macro_rules! impl_fn { - ($fn_name: ident, $data_type: ident) => { + ($fn_name: ident, $data_type: ident, $bin: ident) => { fn $fn_name(&mut self, data: $data_type) { - if self.first { - self.first = false; - } else { - if let Err(_) = write!(self.output, ",") { - error!("Error writing output"); - } - } - if let Err(_) = write!(self.output, "{}", as_json(&data)) { - error!("Error writing output '{}'", as_json(&data)); - } + self.result.$bin.push(From::from(data)); } } } impl<'b, W: Write + 'b> Dump for JsonDumper<'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); + fn crate_prelude(&mut self, data: CratePreludeData) { + self.result.prelude = Some(data) + } + + impl_fn!(extern_crate, ExternCrateData, imports); + impl_fn!(use_data, UseData, imports); + impl_fn!(use_glob, UseGlobData, imports); + + impl_fn!(enum_data, EnumData, defs); + impl_fn!(tuple_variant, TupleVariantData, defs); + impl_fn!(struct_variant, StructVariantData, defs); + impl_fn!(struct_data, StructData, defs); + impl_fn!(trait_data, TraitData, defs); + impl_fn!(function, FunctionData, defs); + impl_fn!(method, MethodData, defs); + impl_fn!(macro_data, MacroData, defs); + impl_fn!(mod_data, ModData, defs); + impl_fn!(typedef, TypeDefData, defs); + impl_fn!(variable, VariableData, defs); + + impl_fn!(function_ref, FunctionRefData, refs); + impl_fn!(function_call, FunctionCallData, refs); + impl_fn!(method_call, MethodCallData, refs); + impl_fn!(mod_ref, ModRefData, refs); + impl_fn!(type_ref, TypeRefData, refs); + impl_fn!(variable_ref, VariableRefData, refs); + + impl_fn!(macro_use, MacroUseData, macro_refs); + + // FIXME store this instead of throwing it away. + fn impl_data(&mut self, _data: ImplData) {} + fn inheritance(&mut self, _data: InheritanceData) {} +} + +// FIXME do we want to change ExternalData to this mode? It will break DXR. +// FIXME methods. The defs have information about possible overriding and the +// refs have decl information (e.g., a trait method where we know the required +// method, but not the supplied method). In both cases, we are currently +// ignoring it. + +#[derive(Debug, RustcEncodable)] +struct Analysis { + prelude: Option, + imports: Vec, + defs: Vec, + refs: Vec, + macro_refs: Vec, +} + +impl Analysis { + fn new() -> Analysis { + Analysis { + prelude: None, + imports: vec![], + defs: vec![], + refs: vec![], + macro_refs: vec![], + } + } +} + +#[derive(Debug, RustcEncodable)] +struct Import { + kind: ImportKind, + id: DefId, + span: SpanData, + name: String, + value: String, +} + +#[derive(Debug, RustcEncodable)] +enum ImportKind { + ExternCrate, + Use, + GlobUse, +} + +impl From for Import { + fn from(data: ExternCrateData) -> Import { + Import { + kind: ImportKind::ExternCrate, + id: data.id, + span: data.span, + name: data.name, + value: String::new(), + } + } +} +impl From for Import { + fn from(data: UseData) -> Import { + Import { + kind: ImportKind::Use, + id: data.id, + span: data.span, + name: data.name, + value: String::new(), + } + } +} +impl From for Import { + fn from(data: UseGlobData) -> Import { + Import { + kind: ImportKind::GlobUse, + id: data.id, + span: data.span, + name: "*".to_owned(), + value: data.names.join(", "), + } + } +} + +#[derive(Debug, RustcEncodable)] +struct Def { + kind: DefKind, + id: DefId, + span: SpanData, + name: String, + qualname: String, + value: String, +} + +#[derive(Debug, RustcEncodable)] +enum DefKind { + // value = type + generics + Enum, + // value = type + generics + Tuple, + // value = type + generics + types + Struct, + // value = type + generics + Trait, + // value = type + generics + Function, + // No id + Macro, + // value = file_name + Mod, + // value = aliased type + Type, + // value = type and init expression + Variable, +} +// TODO value for function and method +// TODO none of the values are right. + +impl From for Def { + fn from(data: EnumData) -> Def { + Def { + kind: DefKind::Enum, + id: data.id, + span: data.span, + name: data.name, + qualname: data.qualname, + value: data.value, + } + } +} + +impl From for Def { + fn from(data: TupleVariantData) -> Def { + Def { + kind: DefKind::Tuple, + id: data.id, + span: data.span, + name: data.name, + qualname: data.qualname, + value: data.value, + } + } +} +impl From for Def { + fn from(data: StructVariantData) -> Def { + Def { + kind: DefKind::Struct, + id: data.id, + span: data.span, + name: data.name, + qualname: data.qualname, + value: data.value, + } + } +} +impl From for Def { + fn from(data: StructData) -> Def { + Def { + kind: DefKind::Struct, + id: data.id, + span: data.span, + name: data.name, + qualname: data.qualname, + value: data.value, + } + } +} +impl From for Def { + fn from(data: TraitData) -> Def { + Def { + kind: DefKind::Trait, + id: data.id, + span: data.span, + name: data.name, + qualname: data.qualname, + value: data.value, + } + } +} +impl From for Def { + fn from(data: FunctionData) -> Def { + Def { + kind: DefKind::Function, + id: data.id, + span: data.span, + name: data.name, + qualname: data.qualname, + value: data.value, + } + } +} +impl From for Def { + fn from(data: MethodData) -> Def { + Def { + kind: DefKind::Function, + id: data.id, + span: data.span, + name: data.name, + qualname: data.qualname, + value: data.value, + } + } +} +impl From for Def { + fn from(data: MacroData) -> Def { + Def { + kind: DefKind::Macro, + id: null_def_id(), + span: data.span, + name: data.name, + qualname: data.qualname, + value: String::new(), + } + } +} +impl From for Def { + fn from(data:ModData) -> Def { + Def { + kind: DefKind::Mod, + id: data.id, + span: data.span, + name: data.name, + qualname: data.qualname, + value: data.filename, + } + } +} +impl From for Def { + fn from(data: TypeDefData) -> Def { + Def { + kind: DefKind::Type, + id: data.id, + span: data.span, + name: data.name, + qualname: data.qualname, + value: data.value, + } + } +} +impl From for Def { + fn from(data: VariableData) -> Def { + Def { + kind: DefKind::Variable, + id: data.id, + span: data.span, + name: data.name, + qualname: data.qualname, + value: data.value, + } + } +} + +#[derive(Debug, RustcEncodable)] +enum RefKind { + Function, + Mod, + Type, + Variable, +} + +#[derive(Debug, RustcEncodable)] +struct Ref { + kind: RefKind, + span: SpanData, + ref_id: DefId, +} + +impl From for Ref { + fn from(data: FunctionRefData) -> Ref { + Ref { + kind: RefKind::Function, + span: data.span, + ref_id: data.ref_id, + } + } +} +impl From for Ref { + fn from(data: FunctionCallData) -> Ref { + Ref { + kind: RefKind::Function, + span: data.span, + ref_id: data.ref_id, + } + } +} +impl From for Ref { + fn from(data: MethodCallData) -> Ref { + Ref { + kind: RefKind::Function, + span: data.span, + ref_id: data.ref_id.or(data.decl_id).unwrap_or(null_def_id()), + } + } +} +impl From for Ref { + fn from(data: ModRefData) -> Ref { + Ref { + kind: RefKind::Mod, + span: data.span, + ref_id: data.ref_id.unwrap_or(null_def_id()), + } + } +} +impl From for Ref { + fn from(data: TypeRefData) -> Ref { + Ref { + kind: RefKind::Type, + span: data.span, + ref_id: data.ref_id.unwrap_or(null_def_id()), + } + } +} +impl From for Ref { + fn from(data: VariableRefData) -> Ref { + Ref { + kind: RefKind::Variable, + span: data.span, + ref_id: data.ref_id, + } + } +} + +#[derive(Debug, RustcEncodable)] +struct MacroRef { + span: SpanData, + qualname: String, + callee_span: SpanData, +} + +impl From for MacroRef { + fn from(data: MacroUseData) -> MacroRef { + MacroRef { + span: data.span, + qualname: data.qualname, + callee_span: data.callee_span, + } + } } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index d62c14d2c57..0a5ac3af714 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -134,6 +134,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { declaration: None, span: sub_span.unwrap(), scope: self.enclosing_scope(item.id), + value: String::new(), // TODO })) } ast::ItemKind::Static(ref typ, mt, ref expr) => { @@ -197,6 +198,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { filter!(self.span_utils, sub_span, item.span, None); Some(Data::EnumData(EnumData { id: item.id, + name: item.ident.to_string(), value: val, span: sub_span.unwrap(), qualname: enum_name, @@ -353,6 +355,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { declaration: decl_id, span: sub_span.unwrap(), scope: self.enclosing_scope(id), + value: String::new(), // TODO }) }