]> git.lizzy.rs Git - rust.git/commitdiff
Change json dumper (and a few other bits and pieces) to use rls-data rather than...
authorNick Cameron <ncameron@mozilla.com>
Tue, 14 Mar 2017 04:08:47 +0000 (17:08 +1300)
committerNick Cameron <ncameron@mozilla.com>
Wed, 15 Mar 2017 08:21:20 +0000 (21:21 +1300)
src/librustc_save_analysis/csv_dumper.rs
src/librustc_save_analysis/data.rs
src/librustc_save_analysis/dump.rs
src/librustc_save_analysis/dump_visitor.rs
src/librustc_save_analysis/external_data.rs
src/librustc_save_analysis/json_api_dumper.rs
src/librustc_save_analysis/json_dumper.rs

index 0fd95500422ff193af8a29aa1f8ea615657eb775..59340ae87ee5da6e607b7e48ce976efd988b9228 100644 (file)
@@ -13,6 +13,8 @@
 use super::external_data::*;
 use super::dump::Dump;
 
+use rls_data::{SpanData, CratePreludeData};
+
 pub struct CsvDumper<'b, W: 'b> {
     output: &'b mut W
 }
@@ -429,6 +431,6 @@ fn make_values_str(pairs: &[(&'static str, &str)]) -> String {
 fn span_extent_str(span: SpanData) -> String {
     format!("file_name,\"{}\",file_line,{},file_col,{},byte_start,{},\
              file_line_end,{},file_col_end,{},byte_end,{}",
-             span.file_name, span.line_start, span.column_start, span.byte_start,
-             span.line_end, span.column_end, span.byte_end)
+             span.file_name.to_str().unwrap(), span.line_start.0, span.column_start.0,
+             span.byte_start, span.line_end.0, span.column_end.0, span.byte_end)
 }
index 6caf81380e40dad51f8c33c1d90a51c7dd5f7065..6a80b703d9da379b7d385dfcd67e5fea25ff4547 100644 (file)
@@ -18,6 +18,8 @@
 use syntax::ast::{self, Attribute, NodeId};
 use syntax_pos::Span;
 
+use rls_data::ExternalCrateData;
+
 pub struct CrateData {
     pub name: String,
     pub number: u32,
@@ -115,14 +117,6 @@ pub struct CratePreludeData {
     pub span: Span,
 }
 
-/// Data for external crates in the prelude of a crate.
-#[derive(Debug, RustcEncodable)]
-pub struct ExternalCrateData {
-    pub name: String,
-    pub num: CrateNum,
-    pub file_name: String,
-}
-
 /// Data for enum declarations.
 #[derive(Clone, Debug, RustcEncodable)]
 pub struct EnumData {
index 18241b394cc17474986d0b9df95d53daa4d7b5dd..84e1fb03f624e821068f2111b3fcefc67ee51eeb 100644 (file)
@@ -10,6 +10,8 @@
 
 use super::external_data::*;
 
+use rls_data::CratePreludeData;
+
 pub trait Dump {
     fn crate_prelude(&mut self, CratePreludeData) {}
     fn enum_data(&mut self, EnumData) {}
index 61956e5cd9d66e4abfd1e411e7b30d1a7ccfedf8..85bef9f3170ac78b6d5b3bd828b100fd47ad8fa8 100644 (file)
@@ -54,6 +54,8 @@
 use super::span_utils::SpanUtils;
 use super::recorder;
 
+use rls_data::ExternalCrateData;
+
 macro_rules! down_cast_data {
     ($id:ident, $kind:ident, $sp:expr) => {
         let $id = if let super::Data::$kind(data) = $id {
index 41658dc5b1b48b043b9faf344768803a1db2b52b..3555887007499ae702d2f2cc125525ea8a3f06fe 100644 (file)
 use syntax::symbol::Symbol;
 use syntax_pos::Span;
 
+use std::path::PathBuf;
+
 use data::{self, Visibility, SigElement};
 
+use rls_data::{SpanData, CratePreludeData};
+
 // FIXME: this should be pub(crate), but the current snapshot doesn't allow it yet
 pub trait Lower {
     type Target;
@@ -36,41 +40,26 @@ pub fn null_def_id() -> DefId {
     }
 }
 
-#[derive(Clone, Debug, RustcEncodable)]
-pub struct SpanData {
-    pub file_name: String,
-    pub byte_start: u32,
-    pub byte_end: u32,
-    /// 1-based.
-    pub line_start: usize,
-    pub line_end: usize,
-    /// 1-based, character offset.
-    pub column_start: usize,
-    pub column_end: usize,
-}
-
-impl SpanData {
-    pub fn from_span(span: Span, cm: &CodeMap) -> SpanData {
-        let start = cm.lookup_char_pos(span.lo);
-        let end = cm.lookup_char_pos(span.hi);
-
-        SpanData {
-            file_name: start.file.name.clone(),
-            byte_start: span.lo.0,
-            byte_end: span.hi.0,
-            line_start: start.line,
-            line_end: end.line,
-            column_start: start.col.0 + 1,
-            column_end: end.col.0 + 1,
-        }
+pub fn span_from_span(span: Span, cm: &CodeMap) -> SpanData {
+    let start = cm.lookup_char_pos(span.lo);
+    let end = cm.lookup_char_pos(span.hi);
+
+    SpanData {
+        file_name: start.file.name.clone().into(),
+        byte_start: span.lo.0,
+        byte_end: span.hi.0,
+        line_start: start.line,
+        line_end: end.line,
+        column_start: start.col.0 + 1,
+        column_end: end.col.0 + 1,
     }
 }
 
 /// Represent an arbitrary attribute on a code element
 #[derive(Clone, Debug, RustcEncodable)]
 pub struct Attribute {
-    value: String,
-    span: SpanData,
+    pub value: String,
+    pub span: SpanData,
 }
 
 impl Lower for Vec<ast::Attribute> {
@@ -93,20 +82,12 @@ fn lower(self, tcx: TyCtxt) -> Vec<Attribute> {
 
             Attribute {
                 value: value,
-                span: SpanData::from_span(attr.span, tcx.sess.codemap()),
+                span: span_from_span(attr.span, tcx.sess.codemap()),
             }
         }).collect()
     }
 }
 
-#[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;
 
@@ -115,7 +96,7 @@ fn lower(self, tcx: TyCtxt) -> CratePreludeData {
             crate_name: self.crate_name,
             crate_root: self.crate_root,
             external_crates: self.external_crates,
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
         }
     }
 }
@@ -145,7 +126,7 @@ fn lower(self, tcx: TyCtxt) -> EnumData {
             name: self.name,
             value: self.value,
             qualname: self.qualname,
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.hir),
             variants: self.variants.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(),
             visibility: self.visibility,
@@ -176,7 +157,7 @@ fn lower(self, tcx: TyCtxt) -> ExternCrateData {
             name: self.name,
             crate_num: self.crate_num,
             location: self.location,
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.hir),
         }
     }
@@ -195,7 +176,7 @@ impl Lower for data::FunctionCallData {
 
     fn lower(self, tcx: TyCtxt) -> FunctionCallData {
         FunctionCallData {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.hir),
             ref_id: self.ref_id,
         }
@@ -228,7 +209,7 @@ fn lower(self, tcx: TyCtxt) -> FunctionData {
             name: self.name,
             qualname: self.qualname,
             declaration: self.declaration,
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.hir),
             value: self.value,
             visibility: self.visibility,
@@ -253,7 +234,7 @@ impl Lower for data::FunctionRefData {
 
     fn lower(self, tcx: TyCtxt) -> FunctionRefData {
         FunctionRefData {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.hir),
             ref_id: self.ref_id,
         }
@@ -274,7 +255,7 @@ impl Lower for data::ImplData {
     fn lower(self, tcx: TyCtxt) -> ImplData {
         ImplData {
             id: make_def_id(self.id, &tcx.hir),
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.hir),
             trait_ref: self.trait_ref,
             self_ref: self.self_ref,
@@ -294,7 +275,7 @@ impl Lower for data::InheritanceData {
 
     fn lower(self, tcx: TyCtxt) -> InheritanceData {
         InheritanceData {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             base_id: self.base_id,
             deriv_id: make_def_id(self.deriv_id, &tcx.hir)
         }
@@ -315,7 +296,7 @@ impl Lower for data::MacroData {
 
     fn lower(self, tcx: TyCtxt) -> MacroData {
         MacroData {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             name: self.name,
             qualname: self.qualname,
             docs: self.docs,
@@ -340,10 +321,10 @@ impl Lower for data::MacroUseData {
 
     fn lower(self, tcx: TyCtxt) -> MacroUseData {
         MacroUseData {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             name: self.name,
             qualname: self.qualname,
-            callee_span: SpanData::from_span(self.callee_span, tcx.sess.codemap()),
+            callee_span: span_from_span(self.callee_span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.hir),
         }
     }
@@ -363,7 +344,7 @@ impl Lower for data::MethodCallData {
 
     fn lower(self, tcx: TyCtxt) -> MethodCallData {
         MethodCallData {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.hir),
             ref_id: self.ref_id,
             decl_id: self.decl_id,
@@ -393,7 +374,7 @@ impl Lower for data::MethodData {
 
     fn lower(self, tcx: TyCtxt) -> MethodData {
         MethodData {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             name: self.name,
             scope: make_def_id(self.scope, &tcx.hir),
             id: make_def_id(self.id, &tcx.hir),
@@ -433,7 +414,7 @@ fn lower(self, tcx: TyCtxt) -> ModData {
             id: make_def_id(self.id, &tcx.hir),
             name: self.name,
             qualname: self.qualname,
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.hir),
             filename: self.filename,
             items: self.items.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(),
@@ -459,7 +440,7 @@ impl Lower for data::ModRefData {
 
     fn lower(self, tcx: TyCtxt) -> ModRefData {
         ModRefData {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.hir),
             ref_id: self.ref_id,
             qualname: self.qualname,
@@ -488,7 +469,7 @@ impl Lower for data::StructData {
 
     fn lower(self, tcx: TyCtxt) -> StructData {
         StructData {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             name: self.name,
             id: make_def_id(self.id, &tcx.hir),
             ctor_id: make_def_id(self.ctor_id, &tcx.hir),
@@ -524,7 +505,7 @@ impl Lower for data::StructVariantData {
 
     fn lower(self, tcx: TyCtxt) -> StructVariantData {
         StructVariantData {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             name: self.name,
             id: make_def_id(self.id, &tcx.hir),
             qualname: self.qualname,
@@ -559,7 +540,7 @@ impl Lower for data::TraitData {
 
     fn lower(self, tcx: TyCtxt) -> TraitData {
         TraitData {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             name: self.name,
             id: make_def_id(self.id, &tcx.hir),
             qualname: self.qualname,
@@ -594,7 +575,7 @@ impl Lower for data::TupleVariantData {
 
     fn lower(self, tcx: TyCtxt) -> TupleVariantData {
         TupleVariantData {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             id: make_def_id(self.id, &tcx.hir),
             name: self.name,
             qualname: self.qualname,
@@ -631,7 +612,7 @@ fn lower(self, tcx: TyCtxt) -> TypeDefData {
         TypeDefData {
             id: make_def_id(self.id, &tcx.hir),
             name: self.name,
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             qualname: self.qualname,
             value: self.value,
             visibility: self.visibility,
@@ -657,7 +638,7 @@ impl Lower for data::TypeRefData {
 
     fn lower(self, tcx: TyCtxt) -> TypeRefData {
         TypeRefData {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.hir),
             ref_id: self.ref_id,
             qualname: self.qualname,
@@ -681,7 +662,7 @@ impl Lower for data::UseData {
     fn lower(self, tcx: TyCtxt) -> UseData {
         UseData {
             id: make_def_id(self.id, &tcx.hir),
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             name: self.name,
             mod_id: self.mod_id,
             scope: make_def_id(self.scope, &tcx.hir),
@@ -705,7 +686,7 @@ impl Lower for data::UseGlobData {
     fn lower(self, tcx: TyCtxt) -> UseGlobData {
         UseGlobData {
             id: make_def_id(self.id, &tcx.hir),
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             names: self.names,
             scope: make_def_id(self.scope, &tcx.hir),
             visibility: self.visibility,
@@ -740,7 +721,7 @@ fn lower(self, tcx: TyCtxt) -> VariableData {
             kind: self.kind,
             name: self.name,
             qualname: self.qualname,
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.hir),
             value: self.value,
             type_value: self.type_value,
@@ -769,7 +750,7 @@ impl Lower for data::VariableRefData {
     fn lower(self, tcx: TyCtxt) -> VariableRefData {
         VariableRefData {
             name: self.name,
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.hir),
             ref_id: self.ref_id,
         }
@@ -793,7 +774,7 @@ impl Lower for data::Signature {
 
     fn lower(self, tcx: TyCtxt) -> Signature {
         Signature {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             text: self.text,
             ident_start: self.ident_start,
             ident_end: self.ident_end,
index 277535f9e651373318c162830e7c3889a2451bf7..b779e8245ed6aef526b13c461666dec18cc851b4 100644 (file)
@@ -18,6 +18,8 @@
 use dump::Dump;
 use super::Format;
 
+use rls_data::{SpanData, CratePreludeData};
+
 
 // A dumper to dump a restricted set of JSON information, designed for use with
 // libraries distributed without their source. Clients are likely to use type
index 1b72489f83c67da2d611710b757001966994c3f5..8a4146ad1050711e9025a15051544146cdd3b58c 100644 (file)
 use rustc::hir::def_id::DefId;
 use rustc_serialize::json::as_json;
 
+use rls_data::{self, Id, Analysis, Import, ImportKind, Def, DefKind, Ref, RefKind, MacroRef,
+               Relation, RelationKind, Signature, SigElement, CratePreludeData};
+
+use external_data;
 use external_data::*;
-use data::{VariableKind, SigElement};
+use data::{self, VariableKind};
 use dump::Dump;
 use super::Format;
 
@@ -40,7 +44,7 @@ fn drop(&mut self) {
 macro_rules! impl_fn {
     ($fn_name: ident, $data_type: ident, $bucket: ident) => {
         fn $fn_name(&mut self, data: $data_type) {
-            self.result.$bucket.push(From::from(data));
+            self.result.$bucket.push(data.into());
         }
     }
 }
@@ -75,21 +79,22 @@ fn crate_prelude(&mut self, data: CratePreludeData) {
     impl_fn!(macro_use, MacroUseData, macro_refs);
 
     fn mod_data(&mut self, data: ModData) {
-        let id: Id = From::from(data.id);
+        let id: Id = id_from_def_id(data.id);
         let mut def = Def {
             kind: DefKind::Mod,
             id: id,
-            span: data.span,
+            span: data.span.into(),
             name: data.name,
             qualname: data.qualname,
             value: data.filename,
-            children: data.items.into_iter().map(|id| From::from(id)).collect(),
+            parent: None,
+            children: data.items.into_iter().map(|id| id_from_def_id(id)).collect(),
             decl_id: None,
             docs: data.docs,
-            sig: Some(From::from(data.sig)),
-            attributes: data.attributes,
+            sig: Some(data.sig.into()),
+            attributes: data.attributes.into_iter().map(|a| a.into()).collect(),
         };
-        if def.span.file_name != def.value {
+        if data.span.file_name.to_str().unwrap() != def.value {
             // If the module is an out-of-line defintion, then we'll make the
             // defintion the first character in the module's file and turn the
             // the declaration into a reference to it.
@@ -99,8 +104,8 @@ fn mod_data(&mut self, data: ModData) {
                 ref_id: id,
             };
             self.result.refs.push(rf);
-            def.span = SpanData {
-                file_name: def.value.clone(),
+            def.span = rls_data::SpanData {
+                file_name: def.value.clone().into(),
                 byte_start: 0,
                 byte_end: 0,
                 line_start: 1,
@@ -115,11 +120,11 @@ fn mod_data(&mut self, data: ModData) {
 
     fn impl_data(&mut self, data: ImplData) {
         if data.self_ref.is_some() {
-            self.result.relations.push(From::from(data));
+            self.result.relations.push(data.into());
         }
     }
     fn inheritance(&mut self, data: InheritanceData) {
-        self.result.relations.push(From::from(data));
+        self.result.relations.push(data.into());
     }
 }
 
@@ -129,476 +134,351 @@ fn inheritance(&mut self, data: InheritanceData) {
 // method, but not the supplied method). In both cases, we are currently
 // ignoring it.
 
-#[derive(Debug, RustcEncodable)]
-struct Analysis {
-    kind: Format,
-    prelude: Option<CratePreludeData>,
-    imports: Vec<Import>,
-    defs: Vec<Def>,
-    refs: Vec<Ref>,
-    macro_refs: Vec<MacroRef>,
-    relations: Vec<Relation>,
-}
-
-impl Analysis {
-    fn new() -> Analysis {
-        Analysis {
-            kind: Format::Json,
-            prelude: None,
-            imports: vec![],
-            defs: vec![],
-            refs: vec![],
-            macro_refs: vec![],
-            relations: vec![],
-        }
-    }
-}
-
 // DefId::index is a newtype and so the JSON serialisation is ugly. Therefore
 // we use our own Id which is the same, but without the newtype.
-#[derive(Clone, Copy, Debug, RustcEncodable)]
-struct Id {
-    krate: u32,
-    index: u32,
+fn id_from_def_id(id: DefId) -> Id {
+    Id {
+        krate: id.krate.as_u32(),
+        index: id.index.as_u32(),
+    }
 }
 
-impl From<DefId> for Id {
-    fn from(id: DefId) -> Id {
-        Id {
-            krate: id.krate.as_u32(),
-            index: id.index.as_u32(),
+impl Into<rls_data::Attribute> for Attribute {
+    fn into(self) -> rls_data::Attribute {
+        rls_data::Attribute {
+            value: self.value,
+            span: self.span,
         }
     }
 }
 
-#[derive(Debug, RustcEncodable)]
-struct Import {
-    kind: ImportKind,
-    ref_id: Option<Id>,
-    span: SpanData,
-    name: String,
-    value: String,
-}
-
-#[derive(Debug, RustcEncodable)]
-enum ImportKind {
-    ExternCrate,
-    Use,
-    GlobUse,
-}
-
-impl From<ExternCrateData> for Import {
-    fn from(data: ExternCrateData) -> Import {
+impl Into<Import> for ExternCrateData {
+    fn into(self) -> Import {
         Import {
             kind: ImportKind::ExternCrate,
             ref_id: None,
-            span: data.span,
-            name: data.name,
+            span: self.span,
+            name: self.name,
             value: String::new(),
         }
     }
 }
-impl From<UseData> for Import {
-    fn from(data: UseData) -> Import {
+impl Into<Import> for UseData {
+    fn into(self) -> Import {
         Import {
             kind: ImportKind::Use,
-            ref_id: data.mod_id.map(|id| From::from(id)),
-            span: data.span,
-            name: data.name,
+            ref_id: self.mod_id.map(|id| id_from_def_id(id)),
+            span: self.span,
+            name: self.name,
             value: String::new(),
         }
     }
 }
-impl From<UseGlobData> for Import {
-    fn from(data: UseGlobData) -> Import {
+impl Into<Import> for UseGlobData {
+    fn into(self) -> Import {
         Import {
             kind: ImportKind::GlobUse,
             ref_id: None,
-            span: data.span,
+            span: self.span,
             name: "*".to_owned(),
-            value: data.names.join(", "),
+            value: self.names.join(", "),
         }
     }
 }
 
-#[derive(Debug, RustcEncodable)]
-struct Def {
-    kind: DefKind,
-    id: Id,
-    span: SpanData,
-    name: String,
-    qualname: String,
-    value: String,
-    children: Vec<Id>,
-    decl_id: Option<Id>,
-    docs: String,
-    sig: Option<JsonSignature>,
-    attributes: Vec<Attribute>,
-}
-
-#[derive(Debug, RustcEncodable)]
-enum DefKind {
-    // value = variant names
-    Enum,
-    // value = enum name + variant name + types
-    Tuple,
-    // value = [enum name +] name + fields
-    Struct,
-    // value = signature
-    Trait,
-    // value = type + generics
-    Function,
-    // value = type + generics
-    Method,
-    // No id, no value.
-    Macro,
-    // value = file_name
-    Mod,
-    // value = aliased type
-    Type,
-    // value = type and init expression (for all variable kinds).
-    Local,
-    Static,
-    Const,
-    Field,
-}
-
-impl From<EnumData> for Def {
-    fn from(data: EnumData) -> Def {
+impl Into<Def> for EnumData {
+    fn into(self) -> Def {
         Def {
             kind: DefKind::Enum,
-            id: From::from(data.id),
-            span: data.span,
-            name: data.name,
-            qualname: data.qualname,
-            value: data.value,
-            children: data.variants.into_iter().map(|id| From::from(id)).collect(),
+            id: id_from_def_id(self.id),
+            span: self.span,
+            name: self.name,
+            qualname: self.qualname,
+            value: self.value,
+            parent: None,
+            children: self.variants.into_iter().map(|id| id_from_def_id(id)).collect(),
             decl_id: None,
-            docs: data.docs,
-            sig: Some(From::from(data.sig)),
-            attributes: data.attributes,
+            docs: self.docs,
+            sig: Some(self.sig.into()),
+            attributes: self.attributes.into_iter().map(|a| a.into()).collect(),
         }
     }
 }
 
-impl From<TupleVariantData> for Def {
-    fn from(data: TupleVariantData) -> Def {
+impl Into<Def> for TupleVariantData {
+    fn into(self) -> Def {
         Def {
             kind: DefKind::Tuple,
-            id: From::from(data.id),
-            span: data.span,
-            name: data.name,
-            qualname: data.qualname,
-            value: data.value,
+            id: id_from_def_id(self.id),
+            span: self.span,
+            name: self.name,
+            qualname: self.qualname,
+            value: self.value,
+            parent: None,
             children: vec![],
             decl_id: None,
-            docs: data.docs,
-            sig: Some(From::from(data.sig)),
-            attributes: data.attributes,
+            docs: self.docs,
+            sig: Some(self.sig.into()),
+            attributes: self.attributes.into_iter().map(|a| a.into()).collect(),
         }
     }
 }
-impl From<StructVariantData> for Def {
-    fn from(data: StructVariantData) -> Def {
+impl Into<Def> for StructVariantData {
+    fn into(self) -> Def {
         Def {
             kind: DefKind::Struct,
-            id: From::from(data.id),
-            span: data.span,
-            name: data.name,
-            qualname: data.qualname,
-            value: data.value,
+            id: id_from_def_id(self.id),
+            span: self.span,
+            name: self.name,
+            qualname: self.qualname,
+            value: self.value,
+            parent: None,
             children: vec![],
             decl_id: None,
-            docs: data.docs,
-            sig: Some(From::from(data.sig)),
-            attributes: data.attributes,
+            docs: self.docs,
+            sig: Some(self.sig.into()),
+            attributes: self.attributes.into_iter().map(|a| a.into()).collect(),
         }
     }
 }
-impl From<StructData> for Def {
-    fn from(data: StructData) -> Def {
+impl Into<Def> for StructData {
+    fn into(self) -> Def {
         Def {
             kind: DefKind::Struct,
-            id: From::from(data.id),
-            span: data.span,
-            name: data.name,
-            qualname: data.qualname,
-            value: data.value,
-            children: data.fields.into_iter().map(|id| From::from(id)).collect(),
+            id: id_from_def_id(self.id),
+            span: self.span,
+            name: self.name,
+            qualname: self.qualname,
+            value: self.value,
+            parent: None,
+            children: self.fields.into_iter().map(|id| id_from_def_id(id)).collect(),
             decl_id: None,
-            docs: data.docs,
-            sig: Some(From::from(data.sig)),
-            attributes: data.attributes,
+            docs: self.docs,
+            sig: Some(self.sig.into()),
+            attributes: self.attributes.into_iter().map(|a| a.into()).collect(),
         }
     }
 }
-impl From<TraitData> for Def {
-    fn from(data: TraitData) -> Def {
+impl Into<Def> for TraitData {
+    fn into(self) -> Def {
         Def {
             kind: DefKind::Trait,
-            id: From::from(data.id),
-            span: data.span,
-            name: data.name,
-            qualname: data.qualname,
-            value: data.value,
-            children: data.items.into_iter().map(|id| From::from(id)).collect(),
+            id: id_from_def_id(self.id),
+            span: self.span,
+            name: self.name,
+            qualname: self.qualname,
+            value: self.value,
+            parent: None,
+            children: self.items.into_iter().map(|id| id_from_def_id(id)).collect(),
             decl_id: None,
-            docs: data.docs,
-            sig: Some(From::from(data.sig)),
-            attributes: data.attributes,
+            docs: self.docs,
+            sig: Some(self.sig.into()),
+            attributes: self.attributes.into_iter().map(|a| a.into()).collect(),
         }
     }
 }
-impl From<FunctionData> for Def {
-    fn from(data: FunctionData) -> Def {
+impl Into<Def> for FunctionData {
+    fn into(self) -> Def {
         Def {
             kind: DefKind::Function,
-            id: From::from(data.id),
-            span: data.span,
-            name: data.name,
-            qualname: data.qualname,
-            value: data.value,
+            id: id_from_def_id(self.id),
+            span: self.span,
+            name: self.name,
+            qualname: self.qualname,
+            value: self.value,
+            parent: None,
             children: vec![],
             decl_id: None,
-            docs: data.docs,
-            sig: Some(From::from(data.sig)),
-            attributes: data.attributes,
+            docs: self.docs,
+            sig: Some(self.sig.into()),
+            attributes: self.attributes.into_iter().map(|a| a.into()).collect(),
         }
     }
 }
-impl From<MethodData> for Def {
-    fn from(data: MethodData) -> Def {
+impl Into<Def> for MethodData {
+    fn into(self) -> Def {
         Def {
             kind: DefKind::Method,
-            id: From::from(data.id),
-            span: data.span,
-            name: data.name,
-            qualname: data.qualname,
-            value: data.value,
+            id: id_from_def_id(self.id),
+            span: self.span,
+            name: self.name,
+            qualname: self.qualname,
+            value: self.value,
+            parent: None,
             children: vec![],
-            decl_id: data.decl_id.map(|id| From::from(id)),
-            docs: data.docs,
-            sig: Some(From::from(data.sig)),
-            attributes: data.attributes,
+            decl_id: self.decl_id.map(|id| id_from_def_id(id)),
+            docs: self.docs,
+            sig: Some(self.sig.into()),
+            attributes: self.attributes.into_iter().map(|a| a.into()).collect(),
         }
     }
 }
-impl From<MacroData> for Def {
-    fn from(data: MacroData) -> Def {
+impl Into<Def> for MacroData {
+    fn into(self) -> Def {
         Def {
             kind: DefKind::Macro,
-            id: From::from(null_def_id()),
-            span: data.span,
-            name: data.name,
-            qualname: data.qualname,
+            id: id_from_def_id(null_def_id()),
+            span: self.span,
+            name: self.name,
+            qualname: self.qualname,
             value: String::new(),
+            parent: None,
             children: vec![],
             decl_id: None,
-            docs: data.docs,
+            docs: self.docs,
             sig: None,
             attributes: vec![],
         }
     }
 }
-impl From<TypeDefData> for Def {
-    fn from(data: TypeDefData) -> Def {
+impl Into<Def> for TypeDefData {
+    fn into(self) -> Def {
         Def {
             kind: DefKind::Type,
-            id: From::from(data.id),
-            span: data.span,
-            name: data.name,
-            qualname: data.qualname,
-            value: data.value,
+            id: id_from_def_id(self.id),
+            span: self.span,
+            name: self.name,
+            qualname: self.qualname,
+            value: self.value,
+            parent: None,
             children: vec![],
             decl_id: None,
             docs: String::new(),
-            sig: data.sig.map(|s| From::from(s)),
-            attributes: data.attributes,
+            sig: self.sig.map(|s| s.into()),
+            attributes: self.attributes.into_iter().map(|a| a.into()).collect(),
         }
     }
 }
-impl From<VariableData> for Def {
-    fn from(data: VariableData) -> Def {
+impl Into<Def> for VariableData {
+    fn into(self) -> Def {
         Def {
-            kind: match data.kind {
+            kind: match self.kind {
                 VariableKind::Static => DefKind::Static,
                 VariableKind::Const => DefKind::Const,
                 VariableKind::Local => DefKind::Local,
                 VariableKind::Field => DefKind::Field,
             },
-            id: From::from(data.id),
-            span: data.span,
-            name: data.name,
-            qualname: data.qualname,
-            value: data.type_value,
+            id: id_from_def_id(self.id),
+            span: self.span,
+            name: self.name,
+            qualname: self.qualname,
+            value: self.type_value,
+            parent: None,
             children: vec![],
             decl_id: None,
-            docs: data.docs,
+            docs: self.docs,
             sig: None,
-            attributes: data.attributes,
+            attributes: self.attributes.into_iter().map(|a| a.into()).collect(),
         }
     }
 }
 
-#[derive(Debug, RustcEncodable)]
-enum RefKind {
-    Function,
-    Mod,
-    Type,
-    Variable,
-}
-
-#[derive(Debug, RustcEncodable)]
-struct Ref {
-    kind: RefKind,
-    span: SpanData,
-    ref_id: Id,
-}
-
-impl From<FunctionRefData> for Ref {
-    fn from(data: FunctionRefData) -> Ref {
+impl Into<Ref> for FunctionRefData {
+    fn into(self) -> Ref {
         Ref {
             kind: RefKind::Function,
-            span: data.span,
-            ref_id: From::from(data.ref_id),
+            span: self.span,
+            ref_id: id_from_def_id(self.ref_id),
         }
     }
 }
-impl From<FunctionCallData> for Ref {
-    fn from(data: FunctionCallData) -> Ref {
+impl Into<Ref> for FunctionCallData {
+    fn into(self) -> Ref {
         Ref {
             kind: RefKind::Function,
-            span: data.span,
-            ref_id: From::from(data.ref_id),
+            span: self.span,
+            ref_id: id_from_def_id(self.ref_id),
         }
     }
 }
-impl From<MethodCallData> for Ref {
-    fn from(data: MethodCallData) -> Ref {
+impl Into<Ref> for MethodCallData {
+    fn into(self) -> Ref {
         Ref {
             kind: RefKind::Function,
-            span: data.span,
-            ref_id: From::from(data.ref_id.or(data.decl_id).unwrap_or(null_def_id())),
+            span: self.span,
+            ref_id: id_from_def_id(self.ref_id.or(self.decl_id).unwrap_or(null_def_id())),
         }
     }
 }
-impl From<ModRefData> for Ref {
-    fn from(data: ModRefData) -> Ref {
+impl Into<Ref> for ModRefData {
+    fn into(self) -> Ref {
         Ref {
             kind: RefKind::Mod,
-            span: data.span,
-            ref_id: From::from(data.ref_id.unwrap_or(null_def_id())),
+            span: self.span,
+            ref_id: id_from_def_id(self.ref_id.unwrap_or(null_def_id())),
         }
     }
 }
-impl From<TypeRefData> for Ref {
-    fn from(data: TypeRefData) -> Ref {
+impl Into<Ref> for TypeRefData {
+    fn into(self) -> Ref {
         Ref {
             kind: RefKind::Type,
-            span: data.span,
-            ref_id: From::from(data.ref_id.unwrap_or(null_def_id())),
+            span: self.span,
+            ref_id: id_from_def_id(self.ref_id.unwrap_or(null_def_id())),
         }
     }
 }
-impl From<VariableRefData> for Ref {
-    fn from(data: VariableRefData) -> Ref {
+impl Into<Ref> for VariableRefData {
+    fn into(self) -> Ref {
         Ref {
             kind: RefKind::Variable,
-            span: data.span,
-            ref_id: From::from(data.ref_id),
+            span: self.span,
+            ref_id: id_from_def_id(self.ref_id),
         }
     }
 }
 
-#[derive(Debug, RustcEncodable)]
-struct MacroRef {
-    span: SpanData,
-    qualname: String,
-    callee_span: SpanData,
-}
-
-impl From<MacroUseData> for MacroRef {
-    fn from(data: MacroUseData) -> MacroRef {
+impl Into<MacroRef> for MacroUseData {
+    fn into(self) -> MacroRef {
         MacroRef {
-            span: data.span,
-            qualname: data.qualname,
-            callee_span: data.callee_span,
+            span: self.span,
+            qualname: self.qualname,
+            callee_span: self.callee_span.into(),
         }
     }
 }
 
-#[derive(Debug, RustcEncodable)]
-struct Relation {
-    span: SpanData,
-    kind: RelationKind,
-    from: Id,
-    to: Id,
-}
-
-#[derive(Debug, RustcEncodable)]
-enum RelationKind {
-    Impl,
-    SuperTrait,
-}
-
-impl From<ImplData> for Relation {
-    fn from(data: ImplData) -> Relation {
+impl Into<Relation> for ImplData {
+    fn into(self) -> Relation {
         Relation {
-            span: data.span,
+            span: self.span,
             kind: RelationKind::Impl,
-            from: From::from(data.self_ref.unwrap_or(null_def_id())),
-            to: From::from(data.trait_ref.unwrap_or(null_def_id())),
+            from: id_from_def_id(self.self_ref.unwrap_or(null_def_id())),
+            to: id_from_def_id(self.trait_ref.unwrap_or(null_def_id())),
         }
     }
 }
 
-impl From<InheritanceData> for Relation {
-    fn from(data: InheritanceData) -> Relation {
+impl Into<Relation> for InheritanceData {
+    fn into(self) -> Relation {
         Relation {
-            span: data.span,
+            span: self.span,
             kind: RelationKind::SuperTrait,
-            from: From::from(data.base_id),
-            to: From::from(data.deriv_id),
+            from: id_from_def_id(self.base_id),
+            to: id_from_def_id(self.deriv_id),
         }
     }
 }
 
-#[derive(Debug, RustcEncodable)]
-pub struct JsonSignature {
-    span: SpanData,
-    text: String,
-    ident_start: usize,
-    ident_end: usize,
-    defs: Vec<JsonSigElement>,
-    refs: Vec<JsonSigElement>,
-}
-
-impl From<Signature> for JsonSignature {
-    fn from(data: Signature) -> JsonSignature {
-        JsonSignature {
-            span: data.span,
-            text: data.text,
-            ident_start: data.ident_start,
-            ident_end: data.ident_end,
-            defs: data.defs.into_iter().map(|s| From::from(s)).collect(),
-            refs: data.refs.into_iter().map(|s| From::from(s)).collect(),
+impl Into<Signature> for external_data::Signature {
+    fn into(self) -> Signature {
+        Signature {
+            span: self.span,
+            text: self.text,
+            ident_start: self.ident_start,
+            ident_end: self.ident_end,
+            defs: self.defs.into_iter().map(|s| s.into()).collect(),
+            refs: self.refs.into_iter().map(|s| s.into()).collect(),
         }
     }
 }
 
-#[derive(Debug, RustcEncodable)]
-pub struct JsonSigElement {
-    id: Id,
-    start: usize,
-    end: usize,
-}
-
-impl From<SigElement> for JsonSigElement {
-    fn from(data: SigElement) -> JsonSigElement {
-        JsonSigElement {
-            id: From::from(data.id),
-            start: data.start,
-            end: data.end,
+impl Into<SigElement> for data::SigElement {
+    fn into(self) -> SigElement {
+        SigElement {
+            id: id_from_def_id(self.id),
+            start: self.start,
+            end: self.end,
         }
     }
 }