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));
}
}
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));
}
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,
}
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 {
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,
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
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
pub struct EnumData {
pub id: DefId,
pub value: String,
+ pub name: String,
pub qualname: String,
pub span: SpanData,
pub scope: DefId,
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()),
pub declaration: Option<DefId>,
pub span: SpanData,
pub scope: DefId,
+ pub value: String,
}
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,
}
}
}
// 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 {
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,
}
}
}
#[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 {
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,
}
}
}
#[derive(Debug, RustcEncodable)]
pub struct StructData {
pub span: SpanData,
+ pub name: String,
pub id: DefId,
pub ctor_id: DefId,
pub qualname: String,
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,
#[derive(Debug, RustcEncodable)]
pub struct StructVariantData {
pub span: SpanData,
+ pub name: String,
pub id: DefId,
pub qualname: String,
pub type_value: String,
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,
#[derive(Debug, RustcEncodable)]
pub struct TraitData {
pub span: SpanData,
+ pub name: String,
pub id: DefId,
pub qualname: String,
pub scope: DefId,
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),
/// 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,
use std::io::Write;
+use rustc::hir::def_id::DefId;
use rustc_serialize::json::as_json;
use super::external_data::*;
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<CratePreludeData>,
+ imports: Vec<Import>,
+ defs: Vec<Def>,
+ refs: Vec<Ref>,
+ macro_refs: Vec<MacroRef>,
+}
+
+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<ExternCrateData> 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<UseData> 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<UseGlobData> 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<EnumData> 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<TupleVariantData> 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<StructVariantData> 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<StructData> 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<TraitData> 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<FunctionData> 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<MethodData> 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<MacroData> 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<ModData> 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<TypeDefData> 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<VariableData> 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<FunctionRefData> for Ref {
+ fn from(data: FunctionRefData) -> Ref {
+ Ref {
+ kind: RefKind::Function,
+ span: data.span,
+ ref_id: data.ref_id,
+ }
+ }
+}
+impl From<FunctionCallData> for Ref {
+ fn from(data: FunctionCallData) -> Ref {
+ Ref {
+ kind: RefKind::Function,
+ span: data.span,
+ ref_id: data.ref_id,
+ }
+ }
+}
+impl From<MethodCallData> 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<ModRefData> 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<TypeRefData> 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<VariableRefData> 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<MacroUseData> for MacroRef {
+ fn from(data: MacroUseData) -> MacroRef {
+ MacroRef {
+ span: data.span,
+ qualname: data.qualname,
+ callee_span: data.callee_span,
+ }
+ }
}