diff --git a/src/librustc_trans/save/dump_csv.rs b/src/librustc_trans/save/dump_csv.rs index cf033ff08060..23bab3fe5b76 100644 --- a/src/librustc_trans/save/dump_csv.rs +++ b/src/librustc_trans/save/dump_csv.rs @@ -28,7 +28,7 @@ //! DumpCsvVisitor walks the AST and processes it. -use super::{escape, generated_code, recorder, SaveContext, PathCollector}; +use super::{escape, generated_code, recorder, SaveContext, PathCollector, Data}; use session::Session; @@ -738,90 +738,51 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> { fn process_path(&mut self, id: NodeId, - span: Span, path: &ast::Path, ref_kind: Option) { - if generated_code(span) { - return + if generated_code(path.span) { + return; } - let def_map = self.tcx.def_map.borrow(); - if !def_map.contains_key(&id) { - self.sess.span_bug(span, - &format!("def_map has no key for {} in visit_expr", id)); - } - let def = def_map.get(&id).unwrap().full_def(); - let sub_span = self.span.span_for_last_ident(span); - match def { - def::DefUpvar(..) | - def::DefLocal(..) | - def::DefStatic(..) | - def::DefConst(..) | - def::DefAssociatedConst(..) | - def::DefVariant(..) => self.fmt.ref_str(ref_kind.unwrap_or(recorder::VarRef), - span, - sub_span, - def.def_id(), - self.cur_scope), - def::DefStruct(def_id) => self.fmt.ref_str(recorder::TypeRef, - span, - sub_span, - def_id, - self.cur_scope), - def::DefTy(def_id, _) => self.fmt.ref_str(recorder::TypeRef, - span, - sub_span, - def_id, - self.cur_scope), - def::DefMethod(declid, provenence) => { - let sub_span = self.span.sub_span_for_meth_name(span); - let defid = if declid.krate == ast::LOCAL_CRATE { - let ti = self.tcx.impl_or_trait_item(declid); - match provenence { - def::FromTrait(def_id) => { - Some(self.tcx.trait_items(def_id) - .iter() - .find(|mr| { - mr.name() == ti.name() - }) - .unwrap() - .def_id()) - } - def::FromImpl(def_id) => { - let impl_items = self.tcx.impl_items.borrow(); - Some(impl_items.get(&def_id) - .unwrap() - .iter() - .find(|mr| { - self.tcx.impl_or_trait_item(mr.def_id()).name() - == ti.name() - }) - .unwrap() - .def_id()) - } - } - } else { - None - }; - self.fmt.meth_call_str(span, - sub_span, - defid, - Some(declid), - self.cur_scope); - }, - def::DefFn(def_id, _) => { - self.fmt.fn_call_str(span, - sub_span, - def_id, - self.cur_scope) + let path_data = self.save_ctxt.get_path_data(id, path); + match path_data { + Data::VariableRefData(ref vrd) => { + self.fmt.ref_str(ref_kind.unwrap_or(recorder::VarRef), + path.span, + Some(vrd.span), + vrd.ref_id, + vrd.scope); + + } + Data::TypeRefData(ref trd) => { + self.fmt.ref_str(recorder::TypeRef, + path.span, + Some(trd.span), + trd.ref_id, + trd.scope); + } + Data::MethodCallData(ref mcd) => { + self.fmt.meth_call_str(path.span, + Some(mcd.span), + mcd.ref_id, + mcd.decl_id, + mcd.scope); + } + Data::FunctionCallData(fcd) => { + self.fmt.fn_call_str(path.span, + Some(fcd.span), + fcd.ref_id, + fcd.scope); + } + _ => { + self.sess.span_bug(path.span, + &format!("Unexpected data: {:?}", path_data)); } - _ => self.sess.span_bug(span, - &format!("Unexpected def kind while looking \ - up path in `{}`: `{:?}`", - self.span.snippet(span), - def)), } - // modules or types in the path prefix + + // Modules or types in the path prefix. + let def_map = self.tcx.def_map.borrow(); + let def = def_map.get(&id).unwrap().full_def(); match def { def::DefMethod(did, _) => { let ti = self.tcx.impl_or_trait_item(did); @@ -1187,7 +1148,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> { visit::walk_expr(self, ex); } ast::ExprPath(_, ref path) => { - self.process_path(ex.id, path.span, path, None); + self.process_path(ex.id, path, None); visit::walk_expr(self, ex); } ast::ExprStruct(ref path, ref fields, ref base) => @@ -1283,6 +1244,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> { // This is to get around borrow checking, because we need mut self to call process_path. let mut paths_to_process = vec![]; + // process collected paths for &(id, ref p, immut, ref_kind) in &collector.collected_paths { let def_map = self.tcx.def_map.borrow(); @@ -1319,11 +1281,12 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> { def) } } + for &(id, ref path, ref_kind) in &paths_to_process { - self.process_path(id, path.span, path, ref_kind); + self.process_path(id, path, ref_kind); } visit::walk_expr_opt(self, &arm.guard); - self.visit_expr(&*arm.body); + self.visit_expr(&arm.body); } fn visit_stmt(&mut self, s: &ast::Stmt) { diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index 5d080924e50d..239e5966a710 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -61,6 +61,8 @@ pub enum Data { VariableRefData(VariableRefData), /// Data for a reference to a type or trait. TypeRefData(TypeRefData), + /// Data about a function call. + FunctionCallData(FunctionCallData), /// Data about a method call. MethodCallData(MethodCallData), } @@ -122,7 +124,7 @@ pub struct ImplData { } /// 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)). +/// will refer to that variables declaration (by ref_id)). #[derive(Debug)] pub struct VariableRefData { pub name: String, @@ -139,6 +141,14 @@ pub struct TypeRefData { pub ref_id: DefId, } +/// Data about a function call. +#[derive(Debug)] +pub struct FunctionCallData { + pub span: Span, + pub scope: NodeId, + pub ref_id: DefId, +} + /// Data about a method call. #[derive(Debug)] pub struct MethodCallData { @@ -392,13 +402,17 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { ty::TraitContainer(_) => (None, Some(method_id)) }; let sub_span = self.span_utils.sub_span_for_meth_name(expr.span); + let parent = self.tcx.map.get_enclosing_scope(expr.id).unwrap_or(0); Some(Data::MethodCallData(MethodCallData { span: sub_span.unwrap(), - scope: self.tcx.map.get_enclosing_scope(expr.id).unwrap_or(0), + scope: parent, ref_id: def_id, - decl_id: decl_id, + decl_id: decl_id, })) } + ast::ExprPath(_, ref path) => { + Some(self.get_path_data(expr.id, path)) + } _ => { // FIXME unimplemented!(); @@ -406,6 +420,90 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { } } + pub fn get_path_data(&self, + id: NodeId, + path: &ast::Path) + -> Data { + let def_map = self.tcx.def_map.borrow(); + if !def_map.contains_key(&id) { + self.tcx.sess.span_bug(path.span, + &format!("def_map has no key for {} in visit_expr", id)); + } + let def = def_map.get(&id).unwrap().full_def(); + let sub_span = self.span_utils.span_for_last_ident(path.span); + match def { + def::DefUpvar(..) | + def::DefLocal(..) | + def::DefStatic(..) | + def::DefConst(..) | + def::DefAssociatedConst(..) | + def::DefVariant(..) => { + Data::VariableRefData(VariableRefData { + name: self.span_utils.snippet(sub_span.unwrap()), + span: sub_span.unwrap(), + scope: self.tcx.map.get_enclosing_scope(id).unwrap_or(0), + ref_id: def.def_id(), + }) + } + def::DefStruct(def_id) | def::DefTy(def_id, _) => { + Data::TypeRefData(TypeRefData { + span: sub_span.unwrap(), + ref_id: def_id, + scope: self.tcx.map.get_enclosing_scope(id).unwrap_or(0), + }) + } + def::DefMethod(decl_id, provenence) => { + let sub_span = self.span_utils.sub_span_for_meth_name(path.span); + let def_id = if decl_id.krate == ast::LOCAL_CRATE { + let ti = self.tcx.impl_or_trait_item(decl_id); + match provenence { + def::FromTrait(def_id) => { + Some(self.tcx.trait_items(def_id) + .iter() + .find(|mr| { + mr.name() == ti.name() + }) + .unwrap() + .def_id()) + } + def::FromImpl(def_id) => { + let impl_items = self.tcx.impl_items.borrow(); + Some(impl_items.get(&def_id) + .unwrap() + .iter() + .find(|mr| { + self.tcx.impl_or_trait_item(mr.def_id()).name() + == ti.name() + }) + .unwrap() + .def_id()) + } + } + } else { + None + }; + Data::MethodCallData(MethodCallData { + span: sub_span.unwrap(), + scope: self.tcx.map.get_enclosing_scope(id).unwrap_or(0), + ref_id: def_id, + decl_id: Some(decl_id), + }) + }, + def::DefFn(def_id, _) => { + Data::FunctionCallData(FunctionCallData { + ref_id: def_id, + span: sub_span.unwrap(), + scope: self.tcx.map.get_enclosing_scope(id).unwrap_or(0), + }) + } + _ => self.tcx.sess.span_bug(path.span, + &format!("Unexpected def kind while looking \ + up path in `{}`: `{:?}`", + self.span_utils.snippet(path.span), + def)), + } + } + pub fn get_field_ref_data(&self, field_ref: &ast::Field, struct_id: DefId, diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index a4855ddcb25d..53befc092da8 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -61,7 +61,7 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { // Keep going, outside-in. let fully_expanded = fld.fold_expr(expanded_expr); - let span = fld.new_span(span); + let span = fld.new_span(span); fld.cx.bt_pop(); fully_expanded.map(|e| ast::Expr {