]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_trans/save/dump_csv.rs
[breaking-change] don't glob export ast::PathListItem_ variants
[rust.git] / src / librustc_trans / save / dump_csv.rs
index 21d536667e5a0425f10283e925ededf4eca3fecc..34d806ab0a8a30f9c621ac92246aef75e9f1cc10 100644 (file)
@@ -37,6 +37,8 @@
 use middle::ty;
 
 use std::fs::File;
+use std::hash::*;
+use std::collections::HashSet;
 
 use syntax::ast::{self, NodeId};
 use syntax::codemap::*;
@@ -70,6 +72,14 @@ pub struct DumpCsvVisitor<'l, 'tcx: 'l> {
     fmt: FmtStrs<'l, 'tcx>,
 
     cur_scope: NodeId,
+
+    // Set of macro definition (callee) spans, and the set
+    // of macro use (callsite) spans. We store these to ensure
+    // we only write one macro def per unique macro definition, and
+    // one macro use per unique callsite span.
+    mac_defs: HashSet<Span>,
+    mac_uses: HashSet<Span>,
+
 }
 
 impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
@@ -92,6 +102,8 @@ pub fn new(tcx: &'l ty::ctxt<'tcx>,
                               span_utils,
                               tcx),
             cur_scope: 0,
+            mac_defs: HashSet::new(),
+            mac_uses: HashSet::new(),
         }
     }
 
@@ -338,7 +350,7 @@ fn process_method(&mut self,
             self.visit_ty(&arg.ty);
         }
 
-        if let ast::Return(ref ret_ty) = sig.decl.output {
+        if let ast::FunctionRetTy::Ty(ref ret_ty) = sig.decl.output {
             self.visit_ty(ret_ty);
         }
 
@@ -417,7 +429,7 @@ fn process_fn(&mut self,
             self.visit_ty(&arg.ty);
         }
 
-        if let ast::Return(ref ret_ty) = decl.output {
+        if let ast::FunctionRetTy::Ty(ref ret_ty) = decl.output {
             self.visit_ty(&ret_ty);
         }
 
@@ -795,7 +807,7 @@ fn process_var_decl(&mut self, p: &ast::Pat, value: String) {
         self.visit_pat(&p);
 
         for &(id, ref p, immut, _) in &collector.collected_paths {
-            let value = if immut == ast::MutImmutable {
+            let value = if immut == ast::Mutability::Immutable {
                 value.to_string()
             } else {
                 "<mutable>".to_string()
@@ -814,12 +826,48 @@ fn process_var_decl(&mut self, p: &ast::Pat, value: String) {
                                   &typ);
         }
     }
+
+    /// Extract macro use and definition information from the AST node defined
+    /// by the given NodeId, using the expansion information from the node's
+    /// span.
+    ///
+    /// If the span is not macro-generated, do nothing, else use callee and
+    /// callsite spans to record macro definition and use data, using the
+    /// mac_uses and mac_defs sets to prevent multiples.
+    fn process_macro_use(&mut self, span: Span, id: NodeId) {
+        let data = match self.save_ctxt.get_macro_use_data(span, id) {
+            None => return,
+            Some(data) => data,
+        };
+        let mut hasher = SipHasher::new();
+        data.callee_span.hash(&mut hasher);
+        let hash = hasher.finish();
+        let qualname = format!("{}::{}", data.name, hash);
+        // Don't write macro definition for imported macros
+        if !self.mac_defs.contains(&data.callee_span)
+            && !data.imported {
+            self.mac_defs.insert(data.callee_span);
+            if let Some(sub_span) = self.span.span_for_macro_def_name(data.callee_span) {
+                self.fmt.macro_str(data.callee_span, sub_span,
+                                   data.name.clone(), qualname.clone());
+            }
+        }
+        if !self.mac_uses.contains(&data.span) {
+            self.mac_uses.insert(data.span);
+            if let Some(sub_span) = self.span.span_for_macro_use_name(data.span) {
+                self.fmt.macro_use_str(data.span, sub_span, data.name,
+                                       qualname, data.scope);
+            }
+        }
+    }
 }
 
 impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
     fn visit_item(&mut self, item: &ast::Item) {
+        use syntax::ast::ItemKind::*;
+        self.process_macro_use(item.span, item.id);
         match item.node {
-            ast::ItemUse(ref use_item) => {
+            Use(ref use_item) => {
                 match use_item.node {
                     ast::ViewPathSimple(ident, ref path) => {
                         let sub_span = self.span.span_for_last_ident(path.span);
@@ -880,7 +928,7 @@ fn visit_item(&mut self, item: &ast::Item) {
                     ast::ViewPathList(ref path, ref list) => {
                         for plid in list {
                             match plid.node {
-                                ast::PathListIdent { id, .. } => {
+                                ast::PathListItemKind::Ident { id, .. } => {
                                     match self.lookup_type_ref(id) {
                                         Some(def_id) => match self.lookup_def_kind(id, plid.span) {
                                             Some(kind) => {
@@ -895,7 +943,7 @@ fn visit_item(&mut self, item: &ast::Item) {
                                         None => (),
                                     }
                                 }
-                                ast::PathListMod { .. } => (),
+                                ast::PathListItemKind::Mod { .. } => (),
                             }
                         }
 
@@ -903,7 +951,7 @@ fn visit_item(&mut self, item: &ast::Item) {
                     }
                 }
             }
-            ast::ItemExternCrate(ref s) => {
+            ExternCrate(ref s) => {
                 let location = match *s {
                     Some(s) => s.to_string(),
                     None => item.ident.to_string(),
@@ -921,28 +969,28 @@ fn visit_item(&mut self, item: &ast::Item) {
                                           &location,
                                           self.cur_scope);
             }
-            ast::ItemFn(ref decl, _, _, _, ref ty_params, ref body) =>
+            Fn(ref decl, _, _, _, ref ty_params, ref body) =>
                 self.process_fn(item, &**decl, ty_params, &**body),
-            ast::ItemStatic(ref typ, _, ref expr) =>
+            Static(ref typ, _, ref expr) =>
                 self.process_static_or_const_item(item, typ, expr),
-            ast::ItemConst(ref typ, ref expr) =>
+            Const(ref typ, ref expr) =>
                 self.process_static_or_const_item(item, &typ, &expr),
-            ast::ItemStruct(ref def, ref ty_params) => self.process_struct(item, def, ty_params),
-            ast::ItemEnum(ref def, ref ty_params) => self.process_enum(item, def, ty_params),
-            ast::ItemImpl(_, _,
+            Struct(ref def, ref ty_params) => self.process_struct(item, def, ty_params),
+            Enum(ref def, ref ty_params) => self.process_enum(item, def, ty_params),
+            Impl(_, _,
                           ref ty_params,
                           ref trait_ref,
                           ref typ,
                           ref impl_items) => {
                 self.process_impl(item, ty_params, trait_ref, &typ, impl_items)
             }
-            ast::ItemTrait(_, ref generics, ref trait_refs, ref methods) =>
+            Trait(_, ref generics, ref trait_refs, ref methods) =>
                 self.process_trait(item, generics, trait_refs, methods),
-            ast::ItemMod(ref m) => {
+            Mod(ref m) => {
                 self.process_mod(item);
                 self.nest(item.id, |v| visit::walk_mod(v, m));
             }
-            ast::ItemTy(ref ty, ref ty_params) => {
+            Ty(ref ty, ref ty_params) => {
                 let qualname = format!("::{}", self.tcx.map.path_to_string(item.id));
                 let value = ty_to_string(&**ty);
                 let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Type);
@@ -951,7 +999,7 @@ fn visit_item(&mut self, item: &ast::Item) {
                 self.visit_ty(&**ty);
                 self.process_generic_params(ty_params, item.span, &qualname, item.id);
             }
-            ast::ItemMac(_) => (),
+            Mac(_) => (),
             _ => visit::walk_item(self, item),
         }
     }
@@ -970,27 +1018,29 @@ fn visit_generics(&mut self, generics: &ast::Generics) {
     }
 
     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::ConstTraitItem(ref ty, Some(ref expr)) => {
+            ast::TraitItemKind::Const(ref ty, Some(ref expr)) => {
                 self.process_const(trait_item.id,
                                    trait_item.ident.name,
                                    trait_item.span,
                                    &*ty,
                                    &*expr);
             }
-            ast::MethodTraitItem(ref sig, ref body) => {
+            ast::TraitItemKind::Method(ref sig, ref body) => {
                 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(..) => {}
+            ast::TraitItemKind::Const(_, None) |
+            ast::TraitItemKind::Type(..) => {}
         }
     }
 
     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,
@@ -1012,8 +1062,9 @@ fn visit_impl_item(&mut self, impl_item: &ast::ImplItem) {
     }
 
     fn visit_ty(&mut self, t: &ast::Ty) {
+        self.process_macro_use(t.span, t.id);
         match t.node {
-            ast::TyPath(_, ref path) => {
+            ast::TyKind::Path(_, ref path) => {
                 match self.lookup_type_ref(t.id) {
                     Some(id) => {
                         let sub_span = self.span.sub_span_for_type_name(t.span);
@@ -1031,24 +1082,25 @@ fn visit_ty(&mut self, t: &ast::Ty) {
     }
 
     fn visit_expr(&mut self, ex: &ast::Expr) {
+        self.process_macro_use(ex.span, ex.id);
         match ex.node {
-            ast::ExprCall(ref _f, ref _args) => {
+            ast::ExprKind::Call(ref _f, ref _args) => {
                 // Don't need to do anything for function calls,
                 // because just walking the callee path does what we want.
                 visit::walk_expr(self, ex);
             }
-            ast::ExprPath(_, ref path) => {
+            ast::ExprKind::Path(_, ref path) => {
                 self.process_path(ex.id, path, None);
                 visit::walk_expr(self, ex);
             }
-            ast::ExprStruct(ref path, ref fields, ref base) => {
+            ast::ExprKind::Struct(ref path, ref fields, ref base) => {
                 let hir_expr = lower_expr(self.save_ctxt.lcx, ex);
                 let adt = self.tcx.expr_ty(&hir_expr).ty_adt_def().unwrap();
                 let def = self.tcx.resolve_expr(&hir_expr);
                 self.process_struct_lit(ex, path, fields, adt.variant_of_def(def), base)
             }
-            ast::ExprMethodCall(_, _, ref args) => self.process_method_call(ex, args),
-            ast::ExprField(ref sub_ex, _) => {
+            ast::ExprKind::MethodCall(_, _, ref args) => self.process_method_call(ex, args),
+            ast::ExprKind::Field(ref sub_ex, _) => {
                 self.visit_expr(&sub_ex);
 
                 if let Some(field_data) = self.save_ctxt.get_expr_data(ex) {
@@ -1060,7 +1112,7 @@ fn visit_expr(&mut self, ex: &ast::Expr) {
                                      field_data.scope);
                 }
             }
-            ast::ExprTupField(ref sub_ex, idx) => {
+            ast::ExprKind::TupField(ref sub_ex, idx) => {
                 self.visit_expr(&**sub_ex);
 
                 let hir_node = lower_expr(self.save_ctxt.lcx, sub_ex);
@@ -1080,7 +1132,7 @@ fn visit_expr(&mut self, ex: &ast::Expr) {
                                                      ty)),
                 }
             }
-            ast::ExprClosure(_, ref decl, ref body) => {
+            ast::ExprKind::Closure(_, ref decl, ref body) => {
                 let mut id = String::from("$");
                 id.push_str(&ex.id.to_string());
                 self.process_formals(&decl.inputs, &id);
@@ -1090,21 +1142,21 @@ fn visit_expr(&mut self, ex: &ast::Expr) {
                     self.visit_ty(&*arg.ty);
                 }
 
-                if let ast::Return(ref ret_ty) = decl.output {
+                if let ast::FunctionRetTy::Ty(ref ret_ty) = decl.output {
                     self.visit_ty(&**ret_ty);
                 }
 
                 // walk the body
                 self.nest(ex.id, |v| v.visit_block(&**body));
             }
-            ast::ExprForLoop(ref pattern, ref subexpression, ref block, _) |
-            ast::ExprWhileLet(ref pattern, ref subexpression, ref block, _) => {
+            ast::ExprKind::ForLoop(ref pattern, ref subexpression, ref block, _) |
+            ast::ExprKind::WhileLet(ref pattern, ref subexpression, ref block, _) => {
                 let value = self.span.snippet(mk_sp(ex.span.lo, subexpression.span.hi));
                 self.process_var_decl(pattern, value);
                 visit::walk_expr(self, subexpression);
                 visit::walk_block(self, block);
             }
-            ast::ExprIfLet(ref pattern, ref subexpression, ref block, ref opt_else) => {
+            ast::ExprKind::IfLet(ref pattern, ref subexpression, ref block, ref opt_else) => {
                 let value = self.span.snippet(mk_sp(ex.span.lo, subexpression.span.hi));
                 self.process_var_decl(pattern, value);
                 visit::walk_expr(self, subexpression);
@@ -1117,11 +1169,13 @@ fn visit_expr(&mut self, ex: &ast::Expr) {
         }
     }
 
-    fn visit_mac(&mut self, _: &ast::Mac) {
-        // Just stop, macros are poison to us.
+    fn visit_mac(&mut self, mac: &ast::Mac) {
+        // These shouldn't exist in the AST at this point, log a span bug.
+        self.sess.span_bug(mac.span, "macro invocation should have been expanded out of AST");
     }
 
     fn visit_pat(&mut self, p: &ast::Pat) {
+        self.process_macro_use(p.span, p.id);
         self.process_pat(p);
     }
 
@@ -1146,7 +1200,7 @@ fn visit_arm(&mut self, arm: &ast::Arm) {
             let def = def_map.get(&id).unwrap().full_def();
             match def {
                 Def::Local(_, id) => {
-                    let value = if immut == ast::MutImmutable {
+                    let value = if immut == ast::Mutability::Immutable {
                         self.span.snippet(p.span).to_string()
                     } else {
                         "<mutable>".to_string()
@@ -1177,10 +1231,13 @@ fn visit_arm(&mut self, arm: &ast::Arm) {
     }
 
     fn visit_stmt(&mut self, s: &ast::Stmt) {
+        let id = s.node.id();
+        self.process_macro_use(s.span, id.unwrap());
         visit::walk_stmt(self, s)
     }
 
     fn visit_local(&mut self, l: &ast::Local) {
+        self.process_macro_use(l.span, l.id);
         let value = self.span.snippet(l.span);
         self.process_var_decl(&l.pat, value);