save-analysis: API-ify paths
This commit is contained in:
parent
84cb4ad969
commit
374af4aea7
3 changed files with 147 additions and 86 deletions
|
|
@ -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<recorder::Row>) {
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
|
|||
|
||||
// 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 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue