From: Nick Cameron Date: Tue, 16 Jun 2015 10:20:30 +0000 (+1200) Subject: Implement get_enclosing_scope and use it in save-analysis X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=b23ddc60e9fcb188421060a83f1af2b815fc60e2;p=rust.git Implement get_enclosing_scope and use it in save-analysis --- 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 @@ pub fn get_parent_node(&self, id: NodeId) -> NodeId { 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 { + 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 @@ pub fn get_item_data(&self, item: &ast::Item) -> Data { 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 @@ pub fn get_item_data(&self, item: &ast::Item) -> Data { 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 @@ pub fn get_item_data(&self, item: &ast::Item) -> Data { 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 @@ pub fn get_item_data(&self, item: &ast::Item) -> Data { 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 @@ pub fn get_item_data(&self, item: &ast::Item) -> Data { 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 @@ pub fn get_expr_data(&self, expr: &ast::Expr) -> Option { 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 @@ pub fn get_expr_data(&self, expr: &ast::Expr) -> Option { 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, })) }