X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibrustc_trans%2Fsave%2Fdump_csv.rs;h=34d806ab0a8a30f9c621ac92246aef75e9f1cc10;hb=2b816b0d6a9bc8210ca314a020a247f8632b4f38;hp=2951cf2ee1ba4d28a66579b58ea6ab07ed00b5cb;hpb=cb3680c08028e4cfe241cf7e68a5d8d6e5dbd2d7;p=rust.git diff --git a/src/librustc_trans/save/dump_csv.rs b/src/librustc_trans/save/dump_csv.rs index 2951cf2ee1b..34d806ab0a8 100644 --- a/src/librustc_trans/save/dump_csv.rs +++ b/src/librustc_trans/save/dump_csv.rs @@ -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, + mac_uses: HashSet, + } 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,13 +807,13 @@ 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 { "".to_string() }; let types = self.tcx.node_types(); - let typ = types.get(&id).unwrap().to_string(); + let typ = types.get(&id).map(|t| t.to_string()).unwrap_or(String::new()); // Get the span only for the name of the variable (I hope the path // is only ever a variable name, but who knows?). let sub_span = self.span.span_for_last_ident(p.span); @@ -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 { "".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);