]> git.lizzy.rs Git - rust.git/commitdiff
Implement get_enclosing_scope and use it in save-analysis
authorNick Cameron <ncameron@mozilla.com>
Tue, 16 Jun 2015 10:20:30 +0000 (22:20 +1200)
committerNick Cameron <ncameron@mozilla.com>
Tue, 30 Jun 2015 05:21:26 +0000 (17:21 +1200)
src/librustc/ast_map/mod.rs
src/librustc_trans/save/mod.rs

index 39ad2022183e479bf954807e4f9516e1b3c9bb05..7c80ba376c3680059e0df3df477f0160e094315f 100644 (file)
@@ -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<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) {
index 27805b9d8330b90066a29234a60cd9ba521bc5ef..e9c91f4f4c194ef2b508ff04ee1e296a8a384ea1 100644 (file)
@@ -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<Data> {
                                 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<Data> {
                         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,
                         }))
                     }