about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNick Cameron <ncameron@mozilla.com>2016-08-30 16:00:48 +1200
committerNick Cameron <ncameron@mozilla.com>2016-09-01 14:55:27 +1200
commit4dc7b585a2d7784e5c8a8e390c77441df4aea29b (patch)
treefd16d562af0e8eb838a318ad0d3d74c15e834d18
parent4e4306c6dfa7a8dd43a7ee9bbc531f4b14b03aec (diff)
downloadrust-4dc7b585a2d7784e5c8a8e390c77441df4aea29b.tar.gz
rust-4dc7b585a2d7784e5c8a8e390c77441df4aea29b.zip
save-analysis: add parent info to api dumps
The parent id is used for constructing rustdoc URLs by clients
-rw-r--r--src/librustc_driver/driver.rs3
-rw-r--r--src/librustc_save_analysis/data.rs9
-rw-r--r--src/librustc_save_analysis/dump_visitor.rs131
-rw-r--r--src/librustc_save_analysis/external_data.rs14
-rw-r--r--src/librustc_save_analysis/json_api_dumper.rs19
-rw-r--r--src/librustc_save_analysis/lib.rs6
-rw-r--r--src/test/run-make/save-analysis/Makefile1
7 files changed, 113 insertions, 70 deletions
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 94092be4922..df1378f9e0d 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -248,7 +248,8 @@ fn keep_hygiene_data(sess: &Session) -> bool {
 fn keep_ast(sess: &Session) -> bool {
     sess.opts.debugging_opts.keep_ast ||
     sess.opts.debugging_opts.save_analysis ||
-    sess.opts.debugging_opts.save_analysis_csv
+    sess.opts.debugging_opts.save_analysis_csv ||
+    sess.opts.debugging_opts.save_analysis_api
 }
 
 /// The name used for source code that doesn't originate in a file
diff --git a/src/librustc_save_analysis/data.rs b/src/librustc_save_analysis/data.rs
index b8827657888..a58cce0745f 100644
--- a/src/librustc_save_analysis/data.rs
+++ b/src/librustc_save_analysis/data.rs
@@ -166,6 +166,7 @@ pub struct FunctionData {
     pub scope: NodeId,
     pub value: String,
     pub visibility: Visibility,
+    pub parent: Option<NodeId>,
 }
 
 /// Data about a function call.
@@ -292,7 +293,8 @@ pub struct StructVariantData {
     pub qualname: String,
     pub type_value: String,
     pub value: String,
-    pub scope: NodeId
+    pub scope: NodeId,
+    pub parent: Option<NodeId>,
 }
 
 #[derive(Debug, RustcEncodable)]
@@ -315,7 +317,8 @@ pub struct TupleVariantData {
     pub qualname: String,
     pub type_value: String,
     pub value: String,
-    pub scope: NodeId
+    pub scope: NodeId,
+    pub parent: Option<NodeId>,
 }
 
 /// Data for a typedef.
@@ -327,6 +330,7 @@ pub struct TypeDefData {
     pub qualname: String,
     pub value: String,
     pub visibility: Visibility,
+    pub parent: Option<NodeId>,
 }
 
 /// Data for a reference to a type or trait.
@@ -366,6 +370,7 @@ pub struct VariableData {
     pub qualname: String,
     pub span: Span,
     pub scope: NodeId,
+    pub parent: Option<NodeId>,
     pub value: String,
     pub type_value: String,
     pub visibility: Visibility,
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index e0475bfed93..c4eba4171de 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -365,6 +365,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
                         type_value: typ,
                         value: String::new(),
                         scope: 0,
+                        parent: None,
                         visibility: Visibility::Inherited,
                     }.lower(self.tcx));
                 }
@@ -488,6 +489,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
                     qualname: qualname,
                     value: String::new(),
                     visibility: Visibility::Inherited,
+                    parent: None,
                 }.lower(self.tcx));
             }
         }
@@ -531,13 +533,14 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
         self.visit_expr(expr);
     }
 
-    fn process_const(&mut self,
-                     id: ast::NodeId,
-                     name: ast::Name,
-                     span: Span,
-                     typ: &ast::Ty,
-                     expr: &ast::Expr,
-                     vis: Visibility) {
+    fn process_assoc_const(&mut self,
+                           id: ast::NodeId,
+                           name: ast::Name,
+                           span: Span,
+                           typ: &ast::Ty,
+                           expr: &ast::Expr,
+                           parent_id: NodeId,
+                           vis: Visibility) {
         let qualname = format!("::{}", self.tcx.node_path_str(id));
 
         let sub_span = self.span.sub_span_after_keyword(span, keywords::Const);
@@ -552,6 +555,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
                 value: self.span.snippet(expr.span),
                 type_value: ty_to_string(&typ),
                 scope: self.cur_scope,
+                parent: Some(parent_id),
                 visibility: vis,
             }.lower(self.tcx));
         }
@@ -646,7 +650,8 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
                             qualname: qualname,
                             type_value: enum_data.qualname.clone(),
                             value: val,
-                            scope: enum_data.scope
+                            scope: enum_data.scope,
+                            parent: Some(item.id),
                         }.lower(self.tcx));
                     }
                 }
@@ -669,7 +674,8 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
                             qualname: qualname,
                             type_value: enum_data.qualname.clone(),
                             value: val,
-                            scope: enum_data.scope
+                            scope: enum_data.scope,
+                            parent: Some(item.id),
                         }.lower(self.tcx));
                     }
                 }
@@ -722,7 +728,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
         }
         self.process_generic_params(type_parameters, item.span, "", item.id);
         for impl_item in impl_items {
-            self.visit_impl_item(impl_item);
+            self.process_impl_item(impl_item, item.id);
         }
     }
 
@@ -792,7 +798,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
         // walk generics and methods
         self.process_generic_params(generics, item.span, &qualname, item.id);
         for method in methods {
-            self.visit_trait_item(method)
+            self.process_trait_item(method, item.id)
         }
     }
 
@@ -998,6 +1004,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
                     value: value,
                     type_value: typ,
                     scope: 0,
+                    parent: None,
                     visibility: Visibility::Inherited,
                 }.lower(self.tcx));
             }
@@ -1046,6 +1053,57 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
             }
         }
     }
+
+    fn process_trait_item(&mut self, trait_item: &ast::TraitItem, trait_id: NodeId) {
+        self.process_macro_use(trait_item.span, trait_item.id);
+        match trait_item.node {
+            ast::TraitItemKind::Const(ref ty, Some(ref expr)) => {
+                self.process_assoc_const(trait_item.id,
+                                         trait_item.ident.name,
+                                         trait_item.span,
+                                         &ty,
+                                         &expr,
+                                         trait_id,
+                                         Visibility::Public);
+            }
+            ast::TraitItemKind::Method(ref sig, ref body) => {
+                self.process_method(sig,
+                                    body.as_ref().map(|x| &**x),
+                                    trait_item.id,
+                                    trait_item.ident.name,
+                                    Visibility::Public,
+                                    trait_item.span);
+            }
+            ast::TraitItemKind::Const(_, None) |
+            ast::TraitItemKind::Type(..) |
+            ast::TraitItemKind::Macro(_) => {}
+        }
+    }
+
+    fn process_impl_item(&mut self, impl_item: &ast::ImplItem, impl_id: NodeId) {
+        self.process_macro_use(impl_item.span, impl_item.id);
+        match impl_item.node {
+            ast::ImplItemKind::Const(ref ty, ref expr) => {
+                self.process_assoc_const(impl_item.id,
+                                         impl_item.ident.name,
+                                         impl_item.span,
+                                         &ty,
+                                         &expr,
+                                         impl_id,
+                                         From::from(&impl_item.vis));
+            }
+            ast::ImplItemKind::Method(ref sig, ref body) => {
+                self.process_method(sig,
+                                    Some(body),
+                                    impl_item.id,
+                                    impl_item.ident.name,
+                                    From::from(&impl_item.vis),
+                                    impl_item.span);
+            }
+            ast::ImplItemKind::Type(_) |
+            ast::ImplItemKind::Macro(_) => {}
+        }
+    }
 }
 
 impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D> {
@@ -1180,6 +1238,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D>
                         qualname: qualname.clone(),
                         value: value,
                         visibility: From::from(&item.vis),
+                        parent: None,
                     }.lower(self.tcx));
                 }
 
@@ -1204,55 +1263,6 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D>
         }
     }
 
-    fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
-        self.process_macro_use(trait_item.span, trait_item.id);
-        match trait_item.node {
-            ast::TraitItemKind::Const(ref ty, Some(ref expr)) => {
-                self.process_const(trait_item.id,
-                                   trait_item.ident.name,
-                                   trait_item.span,
-                                   &ty,
-                                   &expr,
-                                   Visibility::Public);
-            }
-            ast::TraitItemKind::Method(ref sig, ref body) => {
-                self.process_method(sig,
-                                    body.as_ref().map(|x| &**x),
-                                    trait_item.id,
-                                    trait_item.ident.name,
-                                    Visibility::Public,
-                                    trait_item.span);
-            }
-            ast::TraitItemKind::Const(_, None) |
-            ast::TraitItemKind::Type(..) |
-            ast::TraitItemKind::Macro(_) => {}
-        }
-    }
-
-    fn visit_impl_item(&mut self, impl_item: &ast::ImplItem) {
-        self.process_macro_use(impl_item.span, impl_item.id);
-        match impl_item.node {
-            ast::ImplItemKind::Const(ref ty, ref expr) => {
-                self.process_const(impl_item.id,
-                                   impl_item.ident.name,
-                                   impl_item.span,
-                                   &ty,
-                                   &expr,
-                                   From::from(&impl_item.vis));
-            }
-            ast::ImplItemKind::Method(ref sig, ref body) => {
-                self.process_method(sig,
-                                    Some(body),
-                                    impl_item.id,
-                                    impl_item.ident.name,
-                                    From::from(&impl_item.vis),
-                                    impl_item.span);
-            }
-            ast::ImplItemKind::Type(_) |
-            ast::ImplItemKind::Macro(_) => {}
-        }
-    }
-
     fn visit_ty(&mut self, t: &ast::Ty) {
         self.process_macro_use(t.span, t.id);
         match t.node {
@@ -1416,6 +1426,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D>
                             value: value,
                             type_value: String::new(),
                             scope: 0,
+                            parent: None,
                             visibility: Visibility::Inherited,
                         }.lower(self.tcx));
                     }
diff --git a/src/librustc_save_analysis/external_data.rs b/src/librustc_save_analysis/external_data.rs
index b7dded7b624..4333c6dd18e 100644
--- a/src/librustc_save_analysis/external_data.rs
+++ b/src/librustc_save_analysis/external_data.rs
@@ -169,6 +169,7 @@ pub struct FunctionData {
     pub scope: DefId,
     pub value: String,
     pub visibility: Visibility,
+    pub parent: Option<DefId>,
 }
 
 impl Lower for data::FunctionData {
@@ -184,6 +185,7 @@ impl Lower for data::FunctionData {
             scope: make_def_id(self.scope, &tcx.map),
             value: self.value,
             visibility: self.visibility,
+            parent: self.parent.map(|id| make_def_id(id, &tcx.map)),
         }
     }
 }
@@ -328,6 +330,7 @@ pub struct MethodData {
     pub value: String,
     pub decl_id: Option<DefId>,
     pub visibility: Visibility,
+    pub parent: Option<DefId>
 }
 
 impl Lower for data::MethodData {
@@ -343,6 +346,7 @@ impl Lower for data::MethodData {
             value: self.value,
             decl_id: self.decl_id,
             visibility: self.visibility,
+            parent: Some(make_def_id(self.scope, &tcx.map)),
         }
     }
 }
@@ -438,7 +442,8 @@ pub struct StructVariantData {
     pub qualname: String,
     pub type_value: String,
     pub value: String,
-    pub scope: DefId
+    pub scope: DefId,
+    pub parent: Option<DefId>,
 }
 
 impl Lower for data::StructVariantData {
@@ -453,6 +458,7 @@ impl Lower for data::StructVariantData {
             type_value: self.type_value,
             value: self.value,
             scope: make_def_id(self.scope, &tcx.map),
+            parent: self.parent.map(|id| make_def_id(id, &tcx.map)),
         }
     }
 }
@@ -495,6 +501,7 @@ pub struct TupleVariantData {
     pub type_value: String,
     pub value: String,
     pub scope: DefId,
+    pub parent: Option<DefId>,
 }
 
 impl Lower for data::TupleVariantData {
@@ -509,6 +516,7 @@ impl Lower for data::TupleVariantData {
             type_value: self.type_value,
             value: self.value,
             scope: make_def_id(self.scope, &tcx.map),
+            parent: self.parent.map(|id| make_def_id(id, &tcx.map)),
         }
     }
 }
@@ -522,6 +530,7 @@ pub struct TypeDefData {
     pub qualname: String,
     pub value: String,
     pub visibility: Visibility,
+    pub parent: Option<DefId>,
 }
 
 impl Lower for data::TypeDefData {
@@ -535,6 +544,7 @@ impl Lower for data::TypeDefData {
             qualname: self.qualname,
             value: self.value,
             visibility: self.visibility,
+            parent: self.parent.map(|id| make_def_id(id, &tcx.map)),
         }
     }
 }
@@ -620,6 +630,7 @@ pub struct VariableData {
     pub scope: DefId,
     pub value: String,
     pub type_value: String,
+    pub parent: Option<DefId>,
     pub visibility: Visibility,
 }
 
@@ -636,6 +647,7 @@ impl Lower for data::VariableData {
             scope: make_def_id(self.scope, &tcx.map),
             value: self.value,
             type_value: self.type_value,
+            parent: self.parent.map(|id| make_def_id(id, &tcx.map)),
             visibility: self.visibility,
         }
     }
diff --git a/src/librustc_save_analysis/json_api_dumper.rs b/src/librustc_save_analysis/json_api_dumper.rs
index 9cc1badf7cd..874babb907e 100644
--- a/src/librustc_save_analysis/json_api_dumper.rs
+++ b/src/librustc_save_analysis/json_api_dumper.rs
@@ -17,6 +17,13 @@ use external_data::*;
 use data::{VariableKind, Visibility};
 use dump::Dump;
 
+// 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
+// information here, and (for example) generate Rustdoc URLs, but don't need
+// information for navigating the source of the crate.
+// Relative to the regular JSON save-analysis info, this form is filtered to
+// remove non-visible items, but includes some extra info for items (e.g., the
+// parent field for finding the struct to which a field belongs).
 pub struct JsonApiDumper<'b, W: Write + 'b> {
     output: &'b mut W,
     result: Analysis,
@@ -217,7 +224,7 @@ impl From<TupleVariantData> for Option<Def> {
             name: data.name,
             qualname: data.qualname,
             value: data.value,
-            parent: None,
+            parent: data.parent.map(|id| From::from(id)),
             children: vec![],
             decl_id: None,
         })
@@ -232,7 +239,7 @@ impl From<StructVariantData> for Option<Def> {
             name: data.name,
             qualname: data.qualname,
             value: data.value,
-            parent: None,
+            parent: data.parent.map(|id| From::from(id)),
             children: vec![],
             decl_id: None,
         })
@@ -285,7 +292,7 @@ impl From<FunctionData> for Option<Def> {
                 qualname: data.qualname,
                 value: data.value,
                 children: vec![],
-                parent: None,
+                parent: data.parent.map(|id| From::from(id)),
                 decl_id: None,
             }),
             _ => None,
@@ -303,7 +310,7 @@ impl From<MethodData> for Option<Def> {
                 qualname: data.qualname,
                 value: data.value,
                 children: vec![],
-                parent: None,
+                parent: data.parent.map(|id| From::from(id)),
                 decl_id: data.decl_id.map(|id| From::from(id)),
             }),
             _ => None,
@@ -354,7 +361,7 @@ impl From<TypeDefData> for Option<Def> {
                 qualname: data.qualname,
                 value: data.value,
                 children: vec![],
-                parent: None,
+                parent: data.parent.map(|id| From::from(id)),
                 decl_id: None,
             }),
             _ => None,
@@ -377,7 +384,7 @@ impl From<VariableData> for Option<Def> {
                 qualname: data.qualname,
                 value: data.value,
                 children: vec![],
-                parent: None,
+                parent: data.parent.map(|id| From::from(id)),
                 decl_id: None,
             }),
             _ => None,
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 3645eb68394..9478e25cff7 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -141,6 +141,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     scope: self.enclosing_scope(item.id),
                     value: make_signature(decl, generics),
                     visibility: From::from(&item.vis),
+                    parent: None,
                 }))
             }
             ast::ItemKind::Static(ref typ, mt, ref expr) => {
@@ -163,6 +164,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     qualname: qualname,
                     span: sub_span.unwrap(),
                     scope: self.enclosing_scope(item.id),
+                    parent: None,
                     value: value,
                     type_value: ty_to_string(&typ),
                     visibility: From::from(&item.vis),
@@ -179,6 +181,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     qualname: qualname,
                     span: sub_span.unwrap(),
                     scope: self.enclosing_scope(item.id),
+                    parent: None,
                     value: self.span_utils.snippet(expr.span),
                     type_value: ty_to_string(&typ),
                     visibility: From::from(&item.vis),
@@ -284,6 +287,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                 qualname: qualname,
                 span: sub_span.unwrap(),
                 scope: scope,
+                parent: Some(scope),
                 value: "".to_owned(),
                 type_value: typ,
                 visibility: From::from(&field.vis),
@@ -366,6 +370,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
 
         let sub_span = self.span_utils.sub_span_after_keyword(span, keywords::Fn);
         filter!(self.span_utils, sub_span, span, None);
+        let parent_scope = self.enclosing_scope(id);
         Some(FunctionData {
             id: id,
             name: name.to_string(),
@@ -376,6 +381,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
             // FIXME you get better data here by using the visitor.
             value: String::new(),
             visibility: vis,
+            parent: Some(parent_scope),
         })
     }
 
diff --git a/src/test/run-make/save-analysis/Makefile b/src/test/run-make/save-analysis/Makefile
index 3c636baaedc..3711b6ea895 100644
--- a/src/test/run-make/save-analysis/Makefile
+++ b/src/test/run-make/save-analysis/Makefile
@@ -5,3 +5,4 @@ krate2: krate2.rs
 code: foo.rs krate2
 	$(RUSTC) foo.rs -Zsave-analysis-csv
 	$(RUSTC) foo.rs -Zsave-analysis
+	$(RUSTC) foo.rs -Zsave-analysis-api