save-analysis: fix spans for paths to struct variants

This commit is contained in:
Nick Cameron 2014-12-28 14:37:08 +13:00
parent 25a77fbd48
commit 4c4eabfd6c
2 changed files with 54 additions and 47 deletions

View File

@ -763,37 +763,38 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
} }
fn process_path(&mut self, fn process_path(&mut self,
ex: &ast::Expr, id: NodeId,
path: &ast::Path) { span: Span,
path: &ast::Path,
ref_kind: Option<recorder::Row>) {
if generated_code(path.span) { if generated_code(path.span) {
return return
} }
let def_map = self.analysis.ty_cx.def_map.borrow(); let def_map = self.analysis.ty_cx.def_map.borrow();
if !def_map.contains_key(&ex.id) { if !def_map.contains_key(&id) {
self.sess.span_bug(ex.span, self.sess.span_bug(span,
format!("def_map has no key for {} in visit_expr", format!("def_map has no key for {} in visit_expr", id)[]);
ex.id)[]);
} }
let def = &(*def_map)[ex.id]; let def = &(*def_map)[id];
let sub_span = self.span.span_for_last_ident(ex.span); let sub_span = self.span.span_for_last_ident(span);
match *def { match *def {
def::DefUpvar(..) | def::DefUpvar(..) |
def::DefLocal(..) | def::DefLocal(..) |
def::DefStatic(..) | def::DefStatic(..) |
def::DefConst(..) | def::DefConst(..) |
def::DefVariant(..) => self.fmt.ref_str(recorder::VarRef, def::DefVariant(..) => self.fmt.ref_str(ref_kind.unwrap_or(recorder::VarRef),
ex.span, span,
sub_span, sub_span,
def.def_id(), def.def_id(),
self.cur_scope), self.cur_scope),
def::DefStruct(def_id) => self.fmt.ref_str(recorder::StructRef, def::DefStruct(def_id) => self.fmt.ref_str(recorder::StructRef,
ex.span, span,
sub_span, sub_span,
def_id, def_id,
self.cur_scope), self.cur_scope),
def::DefStaticMethod(declid, provenence) => { def::DefStaticMethod(declid, provenence) => {
let sub_span = self.span.sub_span_for_meth_name(ex.span); let sub_span = self.span.sub_span_for_meth_name(span);
let defid = if declid.krate == ast::LOCAL_CRATE { let defid = if declid.krate == ast::LOCAL_CRATE {
let ti = ty::impl_or_trait_item(&self.analysis.ty_cx, let ti = ty::impl_or_trait_item(&self.analysis.ty_cx,
declid); declid);
@ -828,34 +829,31 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
} else { } else {
None None
}; };
self.fmt.meth_call_str(ex.span, self.fmt.meth_call_str(span,
sub_span, sub_span,
defid, defid,
Some(declid), Some(declid),
self.cur_scope); self.cur_scope);
}, },
def::DefFn(def_id, _) => self.fmt.fn_call_str(ex.span, def::DefFn(def_id, _) => self.fmt.fn_call_str(span,
sub_span, sub_span,
def_id, def_id,
self.cur_scope), self.cur_scope),
_ => self.sess.span_bug(ex.span, _ => self.sess.span_bug(span,
format!("Unexpected def kind while looking up path in '{}'", format!("Unexpected def kind while looking up path in '{}'",
self.span.snippet(ex.span))[]), self.span.snippet(span))[]),
} }
// modules or types in the path prefix // modules or types in the path prefix
match *def { match *def {
def::DefStaticMethod(..) => { def::DefStaticMethod(..) => self.write_sub_path_trait_truncated(path),
self.write_sub_path_trait_truncated(path);
},
def::DefLocal(_) | def::DefLocal(_) |
def::DefStatic(_,_) | def::DefStatic(_,_) |
def::DefConst(..) | def::DefConst(..) |
def::DefStruct(_) | def::DefStruct(_) |
def::DefVariant(..) |
def::DefFn(..) => self.write_sub_paths_truncated(path), def::DefFn(..) => self.write_sub_paths_truncated(path),
_ => {}, _ => {},
} }
visit::walk_path(self, path);
} }
fn process_struct_lit(&mut self, fn process_struct_lit(&mut self,
@ -1309,7 +1307,10 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
// because just walking the callee path does what we want. // because just walking the callee path does what we want.
visit::walk_expr(self, ex); visit::walk_expr(self, ex);
}, },
ast::ExprPath(ref path) => self.process_path(ex, path), ast::ExprPath(ref path) => {
self.process_path(ex.id, ex.span, path, None);
visit::walk_path(self, path);
}
ast::ExprStruct(ref path, ref fields, ref base) => ast::ExprStruct(ref path, ref fields, ref base) =>
self.process_struct_lit(ex, path, fields, base), self.process_struct_lit(ex, path, fields, base),
ast::ExprMethodCall(_, _, ref args) => self.process_method_call(ex, args), ast::ExprMethodCall(_, _, ref args) => self.process_method_call(ex, args),
@ -1406,20 +1407,15 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
fn visit_arm(&mut self, arm: &ast::Arm) { fn visit_arm(&mut self, arm: &ast::Arm) {
assert!(self.collected_paths.len() == 0 && !self.collecting); assert!(self.collected_paths.len() == 0 && !self.collecting);
self.collecting = true; self.collecting = true;
for pattern in arm.pats.iter() { for pattern in arm.pats.iter() {
// collect paths from the arm's patterns // collect paths from the arm's patterns
self.visit_pat(&**pattern); self.visit_pat(&**pattern);
} }
self.collecting = false;
// 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 // process collected paths
for &(id, ref p, ref immut, ref_kind) in self.collected_paths.iter() { for &(id, ref p, ref immut, ref_kind) in self.collected_paths.iter() {
let value = if *immut {
self.span.snippet(p.span).to_string()
} else {
"<mutable>".to_string()
};
let sub_span = self.span.span_for_first_ident(p.span);
let def_map = self.analysis.ty_cx.def_map.borrow(); let def_map = self.analysis.ty_cx.def_map.borrow();
if !def_map.contains_key(&id) { if !def_map.contains_key(&id) {
self.sess.span_bug(p.span, self.sess.span_bug(p.span,
@ -1427,23 +1423,34 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
} }
let def = &(*def_map)[id]; let def = &(*def_map)[id];
match *def { match *def {
def::DefLocal(id) => self.fmt.variable_str(p.span, def::DefLocal(id) => {
sub_span, let value = if *immut {
self.span.snippet(p.span).to_string()
} else {
"<mutable>".to_string()
};
assert!(p.segments.len() == 1, "qualified path for local variable def in arm");
self.fmt.variable_str(p.span,
Some(p.span),
id, id,
path_to_string(p)[], path_to_string(p)[],
value[], value[],
""), "")
def::DefVariant(_, id ,_) => self.fmt.ref_str(ref_kind, }
p.span, def::DefVariant(..) => {
sub_span, paths_to_process.push((id, p.span, p.clone(), Some(ref_kind)))
id, }
self.cur_scope), // FIXME(nrc) what are these doing here?
// FIXME(nrc) what is this doing here?
def::DefStatic(_, _) => {} def::DefStatic(_, _) => {}
def::DefConst(..) => {} def::DefConst(..) => {}
_ => error!("unexpected definition kind when processing collected paths: {}", *def) _ => error!("unexpected definition kind when processing collected paths: {}", *def)
} }
} }
for &(id, span, ref path, ref_kind) in paths_to_process.iter() {
self.process_path(id, span, path, ref_kind);
}
self.collecting = false;
self.collected_paths.clear(); self.collected_paths.clear();
visit::walk_expr_opt(self, &arm.guard); visit::walk_expr_opt(self, &arm.guard);
self.visit_expr(&*arm.body); self.visit_expr(&*arm.body);

View File

@ -61,7 +61,7 @@ macro_rules! svec {
}) })
} }
#[deriving(Copy)] #[deriving(Copy,Show)]
pub enum Row { pub enum Row {
Variable, Variable,
Enum, Enum,