1
Fork 0

Implement get_enclosing_scope and use it in save-analysis

This commit is contained in:
Nick Cameron 2015-06-16 22:20:30 +12:00
parent bbf0daa192
commit b23ddc60e9
2 changed files with 36 additions and 8 deletions

View file

@ -321,6 +321,34 @@ impl<'ast> Map<'ast> {
self.find_entry(id).and_then(|x| x.parent_node()).unwrap_or(id)
}
/// Returns the nearest enclosing scope. A scope is an item or block.
/// FIXME it is not clear to me that all items qualify as scopes - statics
/// and associated types probably shouldn't, for example. Behaviour in this
/// regard should be expected to be highly unstable.
pub fn get_enclosing_scope(&self, id: NodeId) -> Option<NodeId> {
let mut last_id = id;
// Walk up the chain of parents until we find a 'scope'.
loop {
let cur_id = self.get_parent_node(last_id);
if cur_id == last_id {
return None;
}
match self.get(cur_id) {
NodeItem(_) |
NodeForeignItem(_) |
NodeTraitItem(_) |
NodeImplItem(_) |
NodeBlock(_) => {
return Some(cur_id);
}
_ => {}
}
last_id = cur_id;
}
}
pub fn get_parent_did(&self, id: NodeId) -> DefId {
let parent = self.get_parent(id);
match self.find_entry(parent) {

View file

@ -172,7 +172,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
qualname: qualname,
declaration: None,
span: sub_span.unwrap(),
scope: self.tcx.map.get_parent(item.id),
scope: self.tcx.map.get_enclosing_scope(item.id).unwrap(),
})
}
ast::ItemStatic(ref typ, mt, ref expr) => {
@ -191,7 +191,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
name: get_ident(item.ident).to_string(),
qualname: qualname,
span: sub_span.unwrap(),
scope: self.tcx.map.get_parent(item.id),
scope: self.tcx.map.get_enclosing_scope(item.id).unwrap(),
value: value,
type_value: ty_to_string(&typ),
})
@ -205,7 +205,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
name: get_ident(item.ident).to_string(),
qualname: qualname,
span: sub_span.unwrap(),
scope: self.tcx.map.get_parent(item.id),
scope: self.tcx.map.get_enclosing_scope(item.id).unwrap(),
value: self.span_utils.snippet(expr.span),
type_value: ty_to_string(&typ),
})
@ -223,7 +223,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
name: get_ident(item.ident).to_string(),
qualname: qualname,
span: sub_span.unwrap(),
scope: self.tcx.map.get_parent(item.id),
scope: self.tcx.map.get_enclosing_scope(item.id).unwrap(),
filename: filename,
})
},
@ -237,14 +237,14 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
value: val,
span: sub_span.unwrap(),
qualname: enum_name,
scope: self.tcx.map.get_parent(item.id),
scope: self.tcx.map.get_enclosing_scope(item.id).unwrap(),
})
},
ast::ItemImpl(_, _, _, ref trait_ref, ref typ, _) => {
let mut type_data = None;
let sub_span;
let parent = self.tcx.map.get_parent(item.id);
let parent = self.tcx.map.get_enclosing_scope(item.id).unwrap();
match typ.node {
// Common case impl for a struct or something basic.
@ -337,7 +337,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
return Some(Data::VariableRefData(VariableRefData {
name: get_ident(ident.node).to_string(),
span: sub_span.unwrap(),
scope: self.tcx.map.get_parent(expr.id),
scope: self.tcx.map.get_enclosing_scope(expr.id).unwrap(),
ref_id: f.id,
}));
}
@ -360,7 +360,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
let sub_span = self.span_utils.span_for_last_ident(path.span);
Some(Data::TypeRefData(TypeRefData {
span: sub_span.unwrap(),
scope: self.tcx.map.get_parent(expr.id),
scope: self.tcx.map.get_enclosing_scope(expr.id).unwrap(),
ref_id: def_id,
}))
}