about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNick Cameron <ncameron@mozilla.com>2015-05-26 10:35:53 +1200
committerNick Cameron <ncameron@mozilla.com>2015-05-28 17:25:50 +1200
commitb2c8719341edaade2d8ccccf8e3db7ef4c208ca5 (patch)
treeb1a61a4ce92695b53e09995d9e05306fb286c7cc
parent6770253c67979012295a2e6ec8be18567ac674f7 (diff)
downloadrust-b2c8719341edaade2d8ccccf8e3db7ef4c208ca5.tar.gz
rust-b2c8719341edaade2d8ccccf8e3db7ef4c208ca5.zip
save-analysis: move another couple of things to the API
-rw-r--r--src/librustc_trans/save/dump_csv.rs69
-rw-r--r--src/librustc_trans/save/mod.rs80
2 files changed, 109 insertions, 40 deletions
diff --git a/src/librustc_trans/save/dump_csv.rs b/src/librustc_trans/save/dump_csv.rs
index 00a1f728b9b..5c630533ec3 100644
--- a/src/librustc_trans/save/dump_csv.rs
+++ b/src/librustc_trans/save/dump_csv.rs
@@ -508,7 +508,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
             self.process_formals(&decl.inputs, &fn_data.qualname);
             self.process_generic_params(ty_params, item.span, &fn_data.qualname, item.id);
         } else {
-            unreachable!();
+            self.sess.span_bug(item.span, "expected FunctionData");
         }
 
         for arg in &decl.inputs {
@@ -538,7 +538,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
                                 &var_data.type_value,
                                 var_data.scope);
         } else {
-            unreachable!();
+            self.sess.span_bug(item.span, "expected VariableData");
         }
 
         self.visit_ty(&typ);
@@ -768,22 +768,18 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
     }
 
     fn process_mod(&mut self,
-                   item: &ast::Item,  // The module in question, represented as an item.
-                   m: &ast::Mod) {
-        let qualname = format!("::{}", self.analysis.ty_cx.map.path_to_string(item.id));
-
-        let cm = self.sess.codemap();
-        let filename = cm.span_to_filename(m.inner);
-
-        let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Mod);
-        self.fmt.mod_str(item.span,
-                         sub_span,
-                         item.id,
-                         &qualname[..],
-                         self.cur_scope,
-                         &filename[..]);
-
-        self.nest(item.id, |v| visit::walk_mod(v, m));
+                   item: &ast::Item) {  // The module in question, represented as an item.
+        let mod_data = self.save_ctxt.get_item_data(item);
+        if let super::Data::ModData(mod_data) = mod_data {
+            self.fmt.mod_str(item.span,
+                             Some(mod_data.span),
+                             mod_data.id,
+                             &mod_data.qualname,
+                             mod_data.scope,
+                             &mod_data.filename);
+        } else {
+            self.sess.span_bug(item.span, "expected ModData");
+        }
     }
 
     fn process_path(&mut self,
@@ -1188,7 +1184,10 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
             }
             ast::ItemTrait(_, ref generics, ref trait_refs, ref methods) =>
                 self.process_trait(item, generics, trait_refs, methods),
-            ast::ItemMod(ref m) => self.process_mod(item, m),
+            ast::ItemMod(ref m) => {
+                self.process_mod(item);
+                self.nest(item.id, |v| visit::walk_mod(v, m));
+            }
             ast::ItemTy(ref ty, ref ty_params) => {
                 let qualname = format!("::{}", self.analysis.ty_cx.map.path_to_string(item.id));
                 let value = ty_to_string(&**ty);
@@ -1295,30 +1294,22 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
             ast::ExprStruct(ref path, ref fields, ref base) =>
                 self.process_struct_lit(ex, path, fields, base),
             ast::ExprMethodCall(_, _, ref args) => self.process_method_call(ex, args),
-            ast::ExprField(ref sub_ex, ident) => {
+            ast::ExprField(ref sub_ex, _) => {
                 if generated_code(sub_ex.span) {
                     return
                 }
 
-                self.visit_expr(&**sub_ex);
-                let ty = &ty::expr_ty_adjusted(&self.analysis.ty_cx, &**sub_ex).sty;
-                match *ty {
-                    ty::ty_struct(def_id, _) => {
-                        let fields = ty::lookup_struct_fields(&self.analysis.ty_cx, def_id);
-                        for f in &fields {
-                            if f.name == ident.node.name {
-                                let sub_span = self.span.span_for_last_ident(ex.span);
-                                self.fmt.ref_str(recorder::VarRef,
-                                                 ex.span,
-                                                 sub_span,
-                                                 f.id,
-                                                 self.cur_scope);
-                                break;
-                            }
-                        }
-                    }
-                    _ => self.sess.span_bug(ex.span,
-                                            &format!("Expected struct type, found {:?}", ty)),
+                self.visit_expr(&sub_ex);
+
+                let field_data = self.save_ctxt.get_expr_data(ex);
+                if let super::Data::VariableRefData(field_data) = field_data {
+                    self.fmt.ref_str(recorder::VarRef,
+                                     ex.span,
+                                     Some(field_data.span),
+                                     field_data.ref_id,
+                                     field_data.scope);
+                } else {
+                    self.sess.span_bug(ex.span, "expected VariableRefData");
                 }
             },
             ast::ExprTupField(ref sub_ex, idx) => {
diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs
index c5c4a75ef82..27297d8aa8d 100644
--- a/src/librustc_trans/save/mod.rs
+++ b/src/librustc_trans/save/mod.rs
@@ -49,6 +49,12 @@ pub enum Data {
     FunctionData(FunctionData),
     /// Data for local and global variables (consts and statics).
     VariableData(VariableData),
+    /// Data for modules.
+    ModData(ModData),
+
+    /// Data for the use of some variable (e.g., the use of a local variable, which
+    /// will refere to that variables declaration).
+    VariableRefData(VariableRefData),
 }
 
 /// Data for all kinds of functions and methods.
@@ -72,6 +78,26 @@ pub struct VariableData {
     pub type_value: String,
 }
 
+/// Data for modules.
+pub struct ModData {
+    pub id: NodeId,
+    pub name: String,
+    pub qualname: String,
+    pub span: Span,
+    pub scope: NodeId,
+    pub filename: String,
+}
+
+/// Data for the use of some item (e.g., the use of a local variable, which
+/// will refere to that variables declaration (by ref_id)).
+pub struct VariableRefData {
+    pub name: String,
+    pub span: Span,
+    pub scope: NodeId,
+    pub ref_id: DefId,
+}
+
+
 impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
     pub fn new(sess: &'l Session,
                analysis: &'l ty::CrateAnalysis<'tcx>,
@@ -97,7 +123,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
 
     pub fn get_item_data(&self, item: &ast::Item) -> Data {
         match item.node {
-            ast::Item_::ItemFn(..) => {
+            ast::ItemFn(..) => {
                 let name = self.analysis.ty_cx.map.path_to_string(item.id);
                 let qualname = format!("::{}", name);
                 let sub_span = self.span_utils.sub_span_after_keyword(item.span, keywords::Fn);
@@ -146,6 +172,58 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     type_value: ty_to_string(&typ),
                 })
             }
+            ast::ItemMod(ref m) => {
+                let qualname = format!("::{}", self.analysis.ty_cx.map.path_to_string(item.id));
+
+                let cm = self.sess.codemap();
+                let filename = cm.span_to_filename(m.inner);
+
+                let sub_span = self.span_utils.sub_span_after_keyword(item.span, keywords::Mod);
+
+                Data::ModData(ModData {
+                    id: item.id,
+                    name: get_ident(item.ident).to_string(),
+                    qualname: qualname,
+                    span: sub_span.unwrap(),
+                    scope: self.analysis.ty_cx.map.get_parent(item.id),
+                    filename: filename,
+                })
+            }
+            _ => {
+                // FIXME
+                unimplemented!();
+            }
+        }
+    }
+
+    pub fn get_expr_data(&self, expr: &ast::Expr) -> Data {
+        match expr.node {
+            ast::ExprField(ref sub_ex, ident) => {
+                let ty = &ty::expr_ty_adjusted(&self.analysis.ty_cx, &sub_ex).sty;
+                match *ty {
+                    ty::ty_struct(def_id, _) => {
+                        let fields = ty::lookup_struct_fields(&self.analysis.ty_cx, def_id);
+                        for f in &fields {
+                            if f.name == ident.node.name {
+                                let sub_span = self.span_utils.span_for_last_ident(expr.span);
+                                return Data::VariableRefData(VariableRefData {
+                                    name: get_ident(ident.node).to_string(),
+                                    span: sub_span.unwrap(),
+                                    scope: self.analysis.ty_cx.map.get_parent(expr.id),
+                                    ref_id: f.id,
+                                });
+                            }
+                        }
+
+                        self.sess.span_bug(expr.span,
+                                           &format!("Couldn't find field {} on {:?}",
+                                                    &get_ident(ident.node),
+                                                    ty))
+                    }
+                    _ => self.sess.span_bug(expr.span,
+                                            &format!("Expected struct type, found {:?}", ty)),
+                }
+            }
             _ => {
                 // FIXME
                 unimplemented!();