Skip to content

Commit bbf0daa

Browse files
committed
Add parent_node to ast_map
1 parent 27975c4 commit bbf0daa

File tree

1 file changed

+133
-67
lines changed

1 file changed

+133
-67
lines changed

src/librustc/ast_map/mod.rs

Lines changed: 133 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -121,27 +121,28 @@ pub enum Node<'ast> {
121121
NodeLifetime(&'ast Lifetime),
122122
}
123123

124-
/// Represents an entry and its parent Node ID
124+
/// Represents an entry and its parent NodeID and parent_node NodeID, see
125+
/// get_parent_node for the distinction.
125126
/// The odd layout is to bring down the total size.
126127
#[derive(Copy, Debug)]
127128
enum MapEntry<'ast> {
128129
/// Placeholder for holes in the map.
129130
NotPresent,
130131

131-
/// All the node types, with a parent ID.
132-
EntryItem(NodeId, &'ast Item),
133-
EntryForeignItem(NodeId, &'ast ForeignItem),
134-
EntryTraitItem(NodeId, &'ast TraitItem),
135-
EntryImplItem(NodeId, &'ast ImplItem),
136-
EntryVariant(NodeId, &'ast Variant),
137-
EntryExpr(NodeId, &'ast Expr),
138-
EntryStmt(NodeId, &'ast Stmt),
139-
EntryArg(NodeId, &'ast Pat),
140-
EntryLocal(NodeId, &'ast Pat),
141-
EntryPat(NodeId, &'ast Pat),
142-
EntryBlock(NodeId, &'ast Block),
143-
EntryStructCtor(NodeId, &'ast StructDef),
144-
EntryLifetime(NodeId, &'ast Lifetime),
132+
/// All the node types, with a parent and scope ID.
133+
EntryItem(NodeId, NodeId, &'ast Item),
134+
EntryForeignItem(NodeId, NodeId, &'ast ForeignItem),
135+
EntryTraitItem(NodeId, NodeId, &'ast TraitItem),
136+
EntryImplItem(NodeId, NodeId, &'ast ImplItem),
137+
EntryVariant(NodeId, NodeId, &'ast Variant),
138+
EntryExpr(NodeId, NodeId, &'ast Expr),
139+
EntryStmt(NodeId, NodeId, &'ast Stmt),
140+
EntryArg(NodeId, NodeId, &'ast Pat),
141+
EntryLocal(NodeId, NodeId, &'ast Pat),
142+
EntryPat(NodeId, NodeId, &'ast Pat),
143+
EntryBlock(NodeId, NodeId, &'ast Block),
144+
EntryStructCtor(NodeId, NodeId, &'ast StructDef),
145+
EntryLifetime(NodeId, NodeId, &'ast Lifetime),
145146

146147
/// Roots for node trees.
147148
RootCrate,
@@ -161,58 +162,77 @@ struct InlinedParent {
161162
}
162163

163164
impl<'ast> MapEntry<'ast> {
164-
fn from_node(p: NodeId, node: Node<'ast>) -> MapEntry<'ast> {
165+
fn from_node(p: NodeId, s: NodeId, node: Node<'ast>) -> MapEntry<'ast> {
165166
match node {
166-
NodeItem(n) => EntryItem(p, n),
167-
NodeForeignItem(n) => EntryForeignItem(p, n),
168-
NodeTraitItem(n) => EntryTraitItem(p, n),
169-
NodeImplItem(n) => EntryImplItem(p, n),
170-
NodeVariant(n) => EntryVariant(p, n),
171-
NodeExpr(n) => EntryExpr(p, n),
172-
NodeStmt(n) => EntryStmt(p, n),
173-
NodeArg(n) => EntryArg(p, n),
174-
NodeLocal(n) => EntryLocal(p, n),
175-
NodePat(n) => EntryPat(p, n),
176-
NodeBlock(n) => EntryBlock(p, n),
177-
NodeStructCtor(n) => EntryStructCtor(p, n),
178-
NodeLifetime(n) => EntryLifetime(p, n)
167+
NodeItem(n) => EntryItem(p, s, n),
168+
NodeForeignItem(n) => EntryForeignItem(p, s, n),
169+
NodeTraitItem(n) => EntryTraitItem(p, s, n),
170+
NodeImplItem(n) => EntryImplItem(p, s, n),
171+
NodeVariant(n) => EntryVariant(p, s, n),
172+
NodeExpr(n) => EntryExpr(p, s, n),
173+
NodeStmt(n) => EntryStmt(p, s, n),
174+
NodeArg(n) => EntryArg(p, s, n),
175+
NodeLocal(n) => EntryLocal(p, s, n),
176+
NodePat(n) => EntryPat(p, s, n),
177+
NodeBlock(n) => EntryBlock(p, s, n),
178+
NodeStructCtor(n) => EntryStructCtor(p, s, n),
179+
NodeLifetime(n) => EntryLifetime(p, s, n)
179180
}
180181
}
181182

182183
fn parent(self) -> Option<NodeId> {
183184
Some(match self {
184-
EntryItem(id, _) => id,
185-
EntryForeignItem(id, _) => id,
186-
EntryTraitItem(id, _) => id,
187-
EntryImplItem(id, _) => id,
188-
EntryVariant(id, _) => id,
189-
EntryExpr(id, _) => id,
190-
EntryStmt(id, _) => id,
191-
EntryArg(id, _) => id,
192-
EntryLocal(id, _) => id,
193-
EntryPat(id, _) => id,
194-
EntryBlock(id, _) => id,
195-
EntryStructCtor(id, _) => id,
196-
EntryLifetime(id, _) => id,
185+
EntryItem(id, _, _) => id,
186+
EntryForeignItem(id, _, _) => id,
187+
EntryTraitItem(id, _, _) => id,
188+
EntryImplItem(id, _, _) => id,
189+
EntryVariant(id, _, _) => id,
190+
EntryExpr(id, _, _) => id,
191+
EntryStmt(id, _, _) => id,
192+
EntryArg(id, _, _) => id,
193+
EntryLocal(id, _, _) => id,
194+
EntryPat(id, _, _) => id,
195+
EntryBlock(id, _, _) => id,
196+
EntryStructCtor(id, _, _) => id,
197+
EntryLifetime(id, _, _) => id,
198+
_ => return None
199+
})
200+
}
201+
202+
fn parent_node(self) -> Option<NodeId> {
203+
Some(match self {
204+
EntryItem(_, id, _) => id,
205+
EntryForeignItem(_, id, _) => id,
206+
EntryTraitItem(_, id, _) => id,
207+
EntryImplItem(_, id, _) => id,
208+
EntryVariant(_, id, _) => id,
209+
EntryExpr(_, id, _) => id,
210+
EntryStmt(_, id, _) => id,
211+
EntryArg(_, id, _) => id,
212+
EntryLocal(_, id, _) => id,
213+
EntryPat(_, id, _) => id,
214+
EntryBlock(_, id, _) => id,
215+
EntryStructCtor(_, id, _) => id,
216+
EntryLifetime(_, id, _) => id,
197217
_ => return None
198218
})
199219
}
200220

201221
fn to_node(self) -> Option<Node<'ast>> {
202222
Some(match self {
203-
EntryItem(_, n) => NodeItem(n),
204-
EntryForeignItem(_, n) => NodeForeignItem(n),
205-
EntryTraitItem(_, n) => NodeTraitItem(n),
206-
EntryImplItem(_, n) => NodeImplItem(n),
207-
EntryVariant(_, n) => NodeVariant(n),
208-
EntryExpr(_, n) => NodeExpr(n),
209-
EntryStmt(_, n) => NodeStmt(n),
210-
EntryArg(_, n) => NodeArg(n),
211-
EntryLocal(_, n) => NodeLocal(n),
212-
EntryPat(_, n) => NodePat(n),
213-
EntryBlock(_, n) => NodeBlock(n),
214-
EntryStructCtor(_, n) => NodeStructCtor(n),
215-
EntryLifetime(_, n) => NodeLifetime(n),
223+
EntryItem(_, _, n) => NodeItem(n),
224+
EntryForeignItem(_, _, n) => NodeForeignItem(n),
225+
EntryTraitItem(_, _, n) => NodeTraitItem(n),
226+
EntryImplItem(_, _, n) => NodeImplItem(n),
227+
EntryVariant(_, _, n) => NodeVariant(n),
228+
EntryExpr(_, _, n) => NodeExpr(n),
229+
EntryStmt(_, _, n) => NodeStmt(n),
230+
EntryArg(_, _, n) => NodeArg(n),
231+
EntryLocal(_, _, n) => NodeLocal(n),
232+
EntryPat(_, _, n) => NodePat(n),
233+
EntryBlock(_, _, n) => NodeBlock(n),
234+
EntryStructCtor(_, _, n) => NodeStructCtor(n),
235+
EntryLifetime(_, _, n) => NodeLifetime(n),
216236
_ => return None
217237
})
218238
}
@@ -289,6 +309,18 @@ impl<'ast> Map<'ast> {
289309
self.find_entry(id).and_then(|x| x.parent()).unwrap_or(id)
290310
}
291311

312+
/// Similar to get_parent, returns the parent node id or id if there is no
313+
/// parent.
314+
/// This function returns the most direct parent in the AST, whereas get_parent
315+
/// returns the enclosing item. Note that this might not be the actual parent
316+
/// node in the AST - some kinds of nodes are not in the map and these will
317+
/// never appear as the parent_node. So you can always walk the parent_nodes
318+
/// from a node to the root of the ast (unless you get the same id back here
319+
/// that can happen if the id is not in the map itself or is just weird).
320+
pub fn get_parent_node(&self, id: NodeId) -> NodeId {
321+
self.find_entry(id).and_then(|x| x.parent_node()).unwrap_or(id)
322+
}
323+
292324
pub fn get_parent_did(&self, id: NodeId) -> DefId {
293325
let parent = self.get_parent(id);
294326
match self.find_entry(parent) {
@@ -301,7 +333,7 @@ impl<'ast> Map<'ast> {
301333
pub fn get_foreign_abi(&self, id: NodeId) -> abi::Abi {
302334
let parent = self.get_parent(id);
303335
let abi = match self.find_entry(parent) {
304-
Some(EntryItem(_, i)) => {
336+
Some(EntryItem(_, _, i)) => {
305337
match i.node {
306338
ItemForeignMod(ref nm) => Some(nm.abi),
307339
_ => None
@@ -591,11 +623,11 @@ impl<'a, 'ast> Iterator for NodesMatchingSuffix<'a, 'ast> {
591623
}
592624
self.idx += 1;
593625
let (p, name) = match self.map.find_entry(idx) {
594-
Some(EntryItem(p, n)) => (p, n.name()),
595-
Some(EntryForeignItem(p, n))=> (p, n.name()),
596-
Some(EntryTraitItem(p, n)) => (p, n.name()),
597-
Some(EntryImplItem(p, n)) => (p, n.name()),
598-
Some(EntryVariant(p, n)) => (p, n.name()),
626+
Some(EntryItem(p, _, n)) => (p, n.name()),
627+
Some(EntryForeignItem(p, _, n))=> (p, n.name()),
628+
Some(EntryTraitItem(p, _, n)) => (p, n.name()),
629+
Some(EntryImplItem(p, _, n)) => (p, n.name()),
630+
Some(EntryVariant(p, _, n)) => (p, n.name()),
599631
_ => continue,
600632
};
601633
if self.matches_names(p, name) {
@@ -648,7 +680,8 @@ impl<F: FoldOps> Folder for IdAndSpanUpdater<F> {
648680
struct NodeCollector<'ast> {
649681
map: Vec<MapEntry<'ast>>,
650682
/// The node in which we are currently mapping (an item or a method).
651-
parent: NodeId
683+
parent: NodeId,
684+
parent_node: NodeId,
652685
}
653686

654687
impl<'ast> NodeCollector<'ast> {
@@ -662,7 +695,7 @@ impl<'ast> NodeCollector<'ast> {
662695
}
663696

664697
fn insert(&mut self, id: NodeId, node: Node<'ast>) {
665-
let entry = MapEntry::from_node(self.parent, node);
698+
let entry = MapEntry::from_node(self.parent, self.parent_node, node);
666699
self.insert_entry(id, entry);
667700
}
668701

@@ -678,6 +711,8 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
678711
self.insert(i.id, NodeItem(i));
679712
let parent = self.parent;
680713
self.parent = i.id;
714+
let parent_node = self.parent_node;
715+
self.parent_node = i.id;
681716
match i.node {
682717
ItemImpl(_, _, _, _, _, ref impl_items) => {
683718
for ii in impl_items {
@@ -728,64 +763,93 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
728763
}
729764
visit::walk_item(self, i);
730765
self.parent = parent;
766+
self.parent_node = parent_node;
731767
}
732768

733769
fn visit_trait_item(&mut self, ti: &'ast TraitItem) {
734770
let parent = self.parent;
735771
self.parent = ti.id;
772+
let parent_node = self.parent_node;
773+
self.parent_node = ti.id;
736774
visit::walk_trait_item(self, ti);
737775
self.parent = parent;
776+
self.parent_node = parent_node;
738777
}
739778

740779
fn visit_impl_item(&mut self, ii: &'ast ImplItem) {
741780
let parent = self.parent;
742781
self.parent = ii.id;
782+
let parent_node = self.parent_node;
783+
self.parent_node = ii.id;
743784
visit::walk_impl_item(self, ii);
744785
self.parent = parent;
786+
self.parent_node = parent_node;
745787
}
746788

747789
fn visit_pat(&mut self, pat: &'ast Pat) {
790+
let parent_node = self.parent_node;
791+
self.parent_node = pat.id;
748792
self.insert(pat.id, match pat.node {
749793
// Note: this is at least *potentially* a pattern...
750794
PatIdent(..) => NodeLocal(pat),
751795
_ => NodePat(pat)
752796
});
753797
visit::walk_pat(self, pat);
798+
self.parent_node = parent_node;
754799
}
755800

756801
fn visit_expr(&mut self, expr: &'ast Expr) {
802+
let parent_node = self.parent_node;
803+
self.parent_node = expr.id;
757804
self.insert(expr.id, NodeExpr(expr));
758805
visit::walk_expr(self, expr);
806+
self.parent_node = parent_node;
759807
}
760808

761809
fn visit_stmt(&mut self, stmt: &'ast Stmt) {
762-
self.insert(ast_util::stmt_id(stmt), NodeStmt(stmt));
810+
let id = ast_util::stmt_id(stmt);
811+
let parent_node = self.parent_node;
812+
self.parent_node = id;
813+
self.insert(id, NodeStmt(stmt));
763814
visit::walk_stmt(self, stmt);
815+
self.parent_node = parent_node;
764816
}
765817

766818
fn visit_fn(&mut self, fk: visit::FnKind<'ast>, fd: &'ast FnDecl,
767-
b: &'ast Block, s: Span, _: NodeId) {
819+
b: &'ast Block, s: Span, id: NodeId) {
820+
let parent_node = self.parent_node;
821+
self.parent_node = id;
768822
self.visit_fn_decl(fd);
769823
visit::walk_fn(self, fk, fd, b, s);
824+
self.parent_node = parent_node;
770825
}
771826

772827
fn visit_ty(&mut self, ty: &'ast Ty) {
828+
let parent_node = self.parent_node;
829+
self.parent_node = ty.id;
773830
match ty.node {
774831
TyBareFn(ref fd) => {
775832
self.visit_fn_decl(&*fd.decl);
776833
}
777834
_ => {}
778835
}
779836
visit::walk_ty(self, ty);
837+
self.parent_node = parent_node;
780838
}
781839

782840
fn visit_block(&mut self, block: &'ast Block) {
841+
let parent_node = self.parent_node;
842+
self.parent_node = block.id;
783843
self.insert(block.id, NodeBlock(block));
784844
visit::walk_block(self, block);
845+
self.parent_node = parent_node;
785846
}
786847

787848
fn visit_lifetime_ref(&mut self, lifetime: &'ast Lifetime) {
849+
let parent_node = self.parent_node;
850+
self.parent_node = lifetime.id;
788851
self.insert(lifetime.id, NodeLifetime(lifetime));
852+
self.parent_node = parent_node;
789853
}
790854

791855
fn visit_lifetime_def(&mut self, def: &'ast LifetimeDef) {
@@ -809,7 +873,8 @@ pub fn map_crate<'ast, F: FoldOps>(forest: &'ast mut Forest, fold_ops: F) -> Map
809873

810874
let mut collector = NodeCollector {
811875
map: vec![],
812-
parent: CRATE_NODE_ID
876+
parent: CRATE_NODE_ID,
877+
parent_node: CRATE_NODE_ID,
813878
};
814879
collector.insert_entry(CRATE_NODE_ID, RootCrate);
815880
visit::walk_crate(&mut collector, &forest.krate);
@@ -866,7 +931,8 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
866931

867932
let mut collector = NodeCollector {
868933
map: mem::replace(&mut *map.map.borrow_mut(), vec![]),
869-
parent: fld.new_id(DUMMY_NODE_ID)
934+
parent: fld.new_id(DUMMY_NODE_ID),
935+
parent_node: fld.new_id(DUMMY_NODE_ID),
870936
};
871937
let ii_parent_id = collector.parent;
872938
collector.insert_entry(ii_parent_id, RootInlinedParent(ii_parent));

0 commit comments

Comments
 (0)