diff options
| author | Nick Cameron <ncameron@mozilla.com> | 2015-06-16 22:20:30 +1200 |
|---|---|---|
| committer | Nick Cameron <ncameron@mozilla.com> | 2015-06-30 17:21:26 +1200 |
| commit | b23ddc60e9fcb188421060a83f1af2b815fc60e2 (patch) | |
| tree | cc87feb3dc28243acb5c26f229a158d1ae556937 | |
| parent | bbf0daa19276354d5759d0b0bd7d31bcd3cc301c (diff) | |
| download | rust-b23ddc60e9fcb188421060a83f1af2b815fc60e2.tar.gz rust-b23ddc60e9fcb188421060a83f1af2b815fc60e2.zip | |
Implement get_enclosing_scope and use it in save-analysis
| -rw-r--r-- | src/librustc/ast_map/mod.rs | 28 | ||||
| -rw-r--r-- | src/librustc_trans/save/mod.rs | 16 |
2 files changed, 36 insertions, 8 deletions
diff --git a/src/librustc/ast_map/mod.rs b/src/librustc/ast_map/mod.rs index 39ad2022183..7c80ba376c3 100644 --- a/src/librustc/ast_map/mod.rs +++ b/src/librustc/ast_map/mod.rs @@ -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) { diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index 27805b9d833..e9c91f4f4c1 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -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, })) } |
