about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNick Cameron <ncameron@mozilla.com>2015-07-09 12:23:29 +1200
committerNick Cameron <ncameron@mozilla.com>2015-07-09 12:24:39 +1200
commit0c766cb8bc62fcd016165db2313188e7f6de71dd (patch)
tree723f4e6e7994c273a8e9f1127c5942738433f74d
parentdf5a1ca8809d2d57e18cfe0c9d186a5699da6414 (diff)
downloadrust-0c766cb8bc62fcd016165db2313188e7f6de71dd.tar.gz
rust-0c766cb8bc62fcd016165db2313188e7f6de71dd.zip
save-analysis: API-ify methods
-rw-r--r--src/librustc_trans/save/dump_csv.rs116
-rw-r--r--src/librustc_trans/save/mod.rs94
2 files changed, 116 insertions, 94 deletions
diff --git a/src/librustc_trans/save/dump_csv.rs b/src/librustc_trans/save/dump_csv.rs
index 01990f4be6c..c5196d09e00 100644
--- a/src/librustc_trans/save/dump_csv.rs
+++ b/src/librustc_trans/save/dump_csv.rs
@@ -34,13 +34,11 @@ use session::Session;
 
 use middle::def;
 use middle::ty::{self, Ty};
-use rustc::ast_map::NodeItem;
 
 use std::cell::Cell;
 use std::fs::File;
 use std::path::Path;
 
-use syntax::ast_util;
 use syntax::ast::{self, NodeId, DefId};
 use syntax::codemap::*;
 use syntax::parse::token::{self, get_ident, keywords};
@@ -298,9 +296,11 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
         }
     }
 
-    fn process_method(&mut self, sig: &ast::MethodSig,
+    fn process_method(&mut self,
+                      sig: &ast::MethodSig,
                       body: Option<&ast::Block>,
-                      id: ast::NodeId, name: ast::Name,
+                      id: ast::NodeId,
+                      name: ast::Name,
                       span: Span) {
         if generated_code(span) {
             return;
@@ -308,91 +308,22 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
 
         debug!("process_method: {}:{}", id, token::get_name(name));
 
-        let scope_id;
-        // The qualname for a method is the trait name or name of the struct in an impl in
-        // which the method is declared in, followed by the method's name.
-        let qualname = match self.tcx.impl_of_method(ast_util::local_def(id)) {
-            Some(impl_id) => match self.tcx.map.get(impl_id.node) {
-                NodeItem(item) => {
-                    scope_id = item.id;
-                    match item.node {
-                        ast::ItemImpl(_, _, _, _, ref ty, _) => {
-                            let mut result = String::from("<");
-                            result.push_str(&ty_to_string(&**ty));
-
-                            match self.tcx.trait_of_item(ast_util::local_def(id)) {
-                                Some(def_id) => {
-                                    result.push_str(" as ");
-                                    result.push_str(
-                                        &self.tcx.item_path_str(def_id));
-                                },
-                                None => {}
-                            }
-                            result.push_str(">");
-                            result
-                        }
-                        _ => {
-                            self.sess.span_bug(span,
-                                &format!("Container {} for method {} not an impl?",
-                                         impl_id.node, id));
-                        },
-                    }
-                },
-                _ => {
-                    self.sess.span_bug(span,
-                        &format!("Container {} for method {} is not a node item {:?}",
-                                 impl_id.node, id, self.tcx.map.get(impl_id.node)));
-                },
-            },
-            None => match self.tcx.trait_of_item(ast_util::local_def(id)) {
-                Some(def_id) => {
-                    scope_id = def_id.node;
-                    match self.tcx.map.get(def_id.node) {
-                        NodeItem(_) => {
-                            format!("::{}", self.tcx.item_path_str(def_id))
-                        }
-                        _ => {
-                            self.sess.span_bug(span,
-                                &format!("Could not find container {} for method {}",
-                                         def_id.node, id));
-                        }
-                    }
-                },
-                None => {
-                    self.sess.span_bug(span,
-                        &format!("Could not find container for method {}", id));
-                },
-            },
-        };
-
-        let qualname = &format!("{}::{}", qualname, &token::get_name(name));
+        let method_data = self.save_ctxt.get_method_data(id, name, span);
 
-        // record the decl for this def (if it has one)
-        let decl_id = self.tcx.trait_item_of_item(ast_util::local_def(id))
-            .and_then(|new_id| {
-                let def_id = new_id.def_id();
-                if def_id.node != 0 && def_id != ast_util::local_def(id) {
-                    Some(def_id)
-                } else {
-                    None
-                }
-            });
-
-        let sub_span = self.span.sub_span_after_keyword(span, keywords::Fn);
         if body.is_some() {
             self.fmt.method_str(span,
-                                sub_span,
-                                id,
-                                qualname,
-                                decl_id,
-                                scope_id);
-            self.process_formals(&sig.decl.inputs, qualname);
+                                Some(method_data.span),
+                                method_data.id,
+                                &method_data.qualname,
+                                method_data.declaration,
+                                method_data.scope);
+            self.process_formals(&sig.decl.inputs, &method_data.qualname);
         } else {
             self.fmt.method_decl_str(span,
-                                     sub_span,
-                                     id,
-                                     qualname,
-                                     scope_id);
+                                     Some(method_data.span),
+                                     method_data.id,
+                                     &method_data.qualname,
+                                     method_data.scope);
         }
 
         // walk arg and return types
@@ -411,7 +342,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
 
         self.process_generic_params(&sig.generics,
                                     span,
-                                    qualname,
+                                    &method_data.qualname,
                                     id);
     }
 
@@ -432,7 +363,6 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
                                 parent_id: NodeId) {
         let field_data = self.save_ctxt.get_field_data(field, parent_id);
         if let Some(field_data) = field_data {
-            down_cast_data!(field_data, VariableData, self, field.span);
             self.fmt.field_str(field.span,
                                Some(field_data.span),
                                field_data.id,
@@ -1087,8 +1017,11 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
                                    trait_item.span, &*ty, &*expr);
             }
             ast::MethodTraitItem(ref sig, ref body) => {
-                self.process_method(sig, body.as_ref().map(|x| &**x),
-                                    trait_item.id, trait_item.ident.name, trait_item.span);
+                self.process_method(sig,
+                                    body.as_ref().map(|x| &**x),
+                                    trait_item.id,
+                                    trait_item.ident.name,
+                                    trait_item.span);
             }
             ast::ConstTraitItem(_, None) |
             ast::TypeTraitItem(..) => {}
@@ -1102,8 +1035,11 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
                                    impl_item.span, &ty, &expr);
             }
             ast::MethodImplItem(ref sig, ref body) => {
-                self.process_method(sig, Some(body), impl_item.id,
-                                    impl_item.ident.name, impl_item.span);
+                self.process_method(sig,
+                                    Some(body),
+                                    impl_item.id,
+                                    impl_item.ident.name,
+                                    impl_item.span);
             }
             ast::TypeImplItem(_) |
             ast::MacImplItem(_) => {}
diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs
index 75de46b5b7c..4e0b34b7ef8 100644
--- a/src/librustc_trans/save/mod.rs
+++ b/src/librustc_trans/save/mod.rs
@@ -15,6 +15,8 @@ use std::env;
 use std::fs::{self, File};
 use std::path::{Path, PathBuf};
 
+use rustc::ast_map::NodeItem;
+
 use syntax::{attr};
 use syntax::ast::{self, NodeId, DefId};
 use syntax::ast_util;
@@ -227,7 +229,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     name: get_ident(item.ident).to_string(),
                     qualname: qualname,
                     span: sub_span.unwrap(),
-                    scope: selfenclosing_scope(item.id),
+                    scope: self.enclosing_scope(item.id),
                     value: self.span_utils.snippet(expr.span),
                     type_value: ty_to_string(&typ),
                 })
@@ -303,7 +305,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
         }
     }
 
-    pub fn get_field_data(&self, field: &ast::StructField, scope: NodeId) -> Option<Data> {
+    pub fn get_field_data(&self, field: &ast::StructField, scope: NodeId) -> Option<VariableData> {
         match field.node.kind {
             ast::NamedField(ident, _) => {
                 let name = get_ident(ident);
@@ -313,7 +315,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                 let typ = self.tcx.node_types().get(&field.node.id).unwrap()
                                                .to_string();
                 let sub_span = self.span_utils.sub_span_before_token(field.span, token::Colon);
-                Some(Data::VariableData(VariableData {
+                Some(VariableData {
                     id: field.node.id,
                     name: get_ident(ident).to_string(),
                     qualname: qualname,
@@ -321,12 +323,96 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     scope: scope,
                     value: "".to_owned(),
                     type_value: typ,
-                }))
+                })
             },
             _ => None,
         }
     }
 
+    // FIXME would be nice to take a MethodItem here, but the ast provides both
+    // trait and impl flavours, so the caller must do the disassembly.
+    pub fn get_method_data(&self,
+                           id: ast::NodeId,
+                           name: ast::Name,
+                           span: Span) -> FunctionData {
+        // The qualname for a method is the trait name or name of the struct in an impl in
+        // which the method is declared in, followed by the method's name.
+        let qualname = match self.tcx.impl_of_method(ast_util::local_def(id)) {
+            Some(impl_id) => match self.tcx.map.get(impl_id.node) {
+                NodeItem(item) => {
+                    match item.node {
+                        ast::ItemImpl(_, _, _, _, ref ty, _) => {
+                            let mut result = String::from("<");
+                            result.push_str(&ty_to_string(&**ty));
+
+                            match self.tcx.trait_of_item(ast_util::local_def(id)) {
+                                Some(def_id) => {
+                                    result.push_str(" as ");
+                                    result.push_str(
+                                        &self.tcx.item_path_str(def_id));
+                                },
+                                None => {}
+                            }
+                            result.push_str(">");
+                            result
+                        }
+                        _ => {
+                            self.tcx.sess.span_bug(span,
+                                &format!("Container {} for method {} not an impl?",
+                                         impl_id.node, id));
+                        },
+                    }
+                },
+                _ => {
+                    self.tcx.sess.span_bug(span,
+                        &format!("Container {} for method {} is not a node item {:?}",
+                                 impl_id.node, id, self.tcx.map.get(impl_id.node)));
+                },
+            },
+            None => match self.tcx.trait_of_item(ast_util::local_def(id)) {
+                Some(def_id) => {
+                    match self.tcx.map.get(def_id.node) {
+                        NodeItem(_) => {
+                            format!("::{}", self.tcx.item_path_str(def_id))
+                        }
+                        _ => {
+                            self.tcx.sess.span_bug(span,
+                                &format!("Could not find container {} for method {}",
+                                         def_id.node, id));
+                        }
+                    }
+                },
+                None => {
+                    self.tcx.sess.span_bug(span,
+                        &format!("Could not find container for method {}", id));
+                },
+            },
+        };
+
+        let qualname = format!("{}::{}", qualname, &token::get_name(name));
+
+        let decl_id = self.tcx.trait_item_of_item(ast_util::local_def(id))
+            .and_then(|new_id| {
+                let def_id = new_id.def_id();
+                if def_id.node != 0 && def_id != ast_util::local_def(id) {
+                    Some(def_id)
+                } else {
+                    None
+                }
+            });
+
+        let sub_span = self.span_utils.sub_span_after_keyword(span, keywords::Fn);
+
+        FunctionData {
+            id: id,
+            name: token::get_name(name).to_string(),
+            qualname: qualname,
+            declaration: decl_id,
+            span: sub_span.unwrap(),
+            scope: self.enclosing_scope(id),
+        }
+    }
+
     pub fn get_trait_ref_data(&self,
                               trait_ref: &ast::TraitRef,
                               parent: NodeId)