Skip to content

Commit d7b0eb0

Browse files
committed
build up a set of node-ids that we can construct def-ids from
1 parent a0dc2d9 commit d7b0eb0

File tree

7 files changed

+371
-237
lines changed

7 files changed

+371
-237
lines changed

src/librustc/front/map/collector.rs

Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use super::*;
12+
use super::MapEntry::*;
13+
14+
use rustc_front::hir::*;
15+
use rustc_front::util;
16+
use rustc_front::visit::{self, Visitor};
17+
use std::iter::repeat;
18+
use syntax::ast::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID};
19+
use syntax::codemap::Span;
20+
use util::nodemap::NodeSet;
21+
22+
/// A Visitor that walks over an AST and collects Node's into an AST
23+
/// Map.
24+
pub struct NodeCollector<'ast> {
25+
pub map: Vec<MapEntry<'ast>>,
26+
pub definitions_map: NodeSet,
27+
pub parent_node: NodeId,
28+
}
29+
30+
impl<'ast> NodeCollector<'ast> {
31+
pub fn root() -> NodeCollector<'ast> {
32+
let mut collector = NodeCollector {
33+
map: vec![],
34+
definitions_map: NodeSet(),
35+
parent_node: CRATE_NODE_ID,
36+
};
37+
collector.insert_entry(CRATE_NODE_ID, RootCrate);
38+
collector.create_def(CRATE_NODE_ID);
39+
collector.create_def(DUMMY_NODE_ID);
40+
collector
41+
}
42+
43+
pub fn extend(parent: &'ast InlinedParent,
44+
parent_node: NodeId,
45+
map: Vec<MapEntry<'ast>>,
46+
definitions_map: NodeSet)
47+
-> NodeCollector<'ast> {
48+
let mut collector = NodeCollector {
49+
map: map,
50+
definitions_map: definitions_map,
51+
parent_node: parent_node
52+
};
53+
collector.insert_entry(parent_node, RootInlinedParent(parent));
54+
55+
collector
56+
}
57+
58+
fn create_def(&mut self, node: NodeId) {
59+
let is_new = self.definitions_map.insert(node);
60+
assert!(is_new,
61+
"two entries for node id `{}` -- previous is `{:?}`",
62+
node, node);
63+
}
64+
65+
fn insert_entry(&mut self, id: NodeId, entry: MapEntry<'ast>) {
66+
debug!("ast_map: {:?} => {:?}", id, entry);
67+
let len = self.map.len();
68+
if id as usize >= len {
69+
self.map.extend(repeat(NotPresent).take(id as usize - len + 1));
70+
}
71+
self.map[id as usize] = entry;
72+
}
73+
74+
fn insert(&mut self, id: NodeId, node: Node<'ast>) {
75+
let entry = MapEntry::from_node(self.parent_node, node);
76+
self.insert_entry(id, entry);
77+
}
78+
79+
fn visit_fn_decl(&mut self, decl: &'ast FnDecl) {
80+
for a in &decl.inputs {
81+
self.insert(a.id, NodeArg(&*a.pat));
82+
}
83+
}
84+
}
85+
86+
impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
87+
fn visit_item(&mut self, i: &'ast Item) {
88+
self.insert(i.id, NodeItem(i));
89+
90+
let parent_node = self.parent_node;
91+
self.parent_node = i.id;
92+
93+
self.create_def(i.id);
94+
95+
match i.node {
96+
ItemImpl(..) => { }
97+
ItemEnum(ref enum_definition, _) => {
98+
for v in &enum_definition.variants {
99+
self.insert(v.node.id, NodeVariant(&**v));
100+
self.create_def(v.node.id);
101+
102+
match v.node.kind {
103+
TupleVariantKind(ref args) => {
104+
for arg in args {
105+
self.create_def(arg.id);
106+
}
107+
}
108+
StructVariantKind(ref def) => {
109+
for field in &def.fields {
110+
self.create_def(field.node.id);
111+
}
112+
}
113+
}
114+
}
115+
}
116+
ItemForeignMod(..) => {}
117+
ItemStruct(ref struct_def, _) => {
118+
// If this is a tuple-like struct, register the constructor.
119+
match struct_def.ctor_id {
120+
Some(ctor_id) => {
121+
self.insert(ctor_id, NodeStructCtor(&**struct_def));
122+
self.create_def(ctor_id);
123+
}
124+
None => {}
125+
}
126+
127+
for field in &struct_def.fields {
128+
self.create_def(field.node.id);
129+
}
130+
}
131+
ItemTrait(_, _, ref bounds, _) => {
132+
for b in bounds.iter() {
133+
if let TraitTyParamBound(ref t, TraitBoundModifier::None) = *b {
134+
self.insert(t.trait_ref.ref_id, NodeItem(i));
135+
}
136+
}
137+
}
138+
ItemUse(ref view_path) => {
139+
match view_path.node {
140+
ViewPathList(_, ref paths) => {
141+
for path in paths {
142+
self.insert(path.node.id(), NodeItem(i));
143+
}
144+
}
145+
_ => ()
146+
}
147+
}
148+
_ => {}
149+
}
150+
visit::walk_item(self, i);
151+
self.parent_node = parent_node;
152+
}
153+
154+
fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) {
155+
self.insert(foreign_item.id, NodeForeignItem(foreign_item));
156+
self.create_def(foreign_item.id);
157+
158+
let parent_node = self.parent_node;
159+
self.parent_node = foreign_item.id;
160+
visit::walk_foreign_item(self, foreign_item);
161+
self.parent_node = parent_node;
162+
}
163+
164+
fn visit_generics(&mut self, generics: &'ast Generics) {
165+
for ty_param in generics.ty_params.iter() {
166+
self.create_def(ty_param.id);
167+
self.insert(ty_param.id, NodeTyParam(ty_param));
168+
}
169+
170+
visit::walk_generics(self, generics);
171+
}
172+
173+
fn visit_trait_item(&mut self, ti: &'ast TraitItem) {
174+
self.insert(ti.id, NodeTraitItem(ti));
175+
self.create_def(ti.id);
176+
177+
match ti.node {
178+
ConstTraitItem(_, Some(ref expr)) => {
179+
self.create_def(expr.id);
180+
}
181+
_ => { }
182+
}
183+
184+
let parent_node = self.parent_node;
185+
self.parent_node = ti.id;
186+
visit::walk_trait_item(self, ti);
187+
self.parent_node = parent_node;
188+
}
189+
190+
fn visit_impl_item(&mut self, ii: &'ast ImplItem) {
191+
self.insert(ii.id, NodeImplItem(ii));
192+
self.create_def(ii.id);
193+
194+
match ii.node {
195+
ConstImplItem(_, ref expr) => {
196+
self.create_def(expr.id);
197+
}
198+
_ => { }
199+
}
200+
201+
let parent_node = self.parent_node;
202+
self.parent_node = ii.id;
203+
visit::walk_impl_item(self, ii);
204+
self.parent_node = parent_node;
205+
}
206+
207+
fn visit_pat(&mut self, pat: &'ast Pat) {
208+
let maybe_binding = match pat.node {
209+
PatIdent(..) => true,
210+
_ => false
211+
};
212+
213+
self.insert(pat.id,
214+
if maybe_binding {NodeLocal(pat)} else {NodePat(pat)});
215+
216+
if maybe_binding {
217+
self.create_def(pat.id);
218+
}
219+
220+
let parent_node = self.parent_node;
221+
self.parent_node = pat.id;
222+
visit::walk_pat(self, pat);
223+
self.parent_node = parent_node;
224+
}
225+
226+
fn visit_expr(&mut self, expr: &'ast Expr) {
227+
self.insert(expr.id, NodeExpr(expr));
228+
229+
match expr.node {
230+
ExprClosure(..) => self.create_def(expr.id),
231+
_ => (),
232+
}
233+
234+
let parent_node = self.parent_node;
235+
self.parent_node = expr.id;
236+
visit::walk_expr(self, expr);
237+
self.parent_node = parent_node;
238+
}
239+
240+
fn visit_stmt(&mut self, stmt: &'ast Stmt) {
241+
let id = util::stmt_id(stmt);
242+
self.insert(id, NodeStmt(stmt));
243+
let parent_node = self.parent_node;
244+
self.parent_node = id;
245+
visit::walk_stmt(self, stmt);
246+
self.parent_node = parent_node;
247+
}
248+
249+
fn visit_fn(&mut self, fk: visit::FnKind<'ast>, fd: &'ast FnDecl,
250+
b: &'ast Block, s: Span, id: NodeId) {
251+
let parent_node = self.parent_node;
252+
self.parent_node = id;
253+
self.visit_fn_decl(fd);
254+
visit::walk_fn(self, fk, fd, b, s);
255+
self.parent_node = parent_node;
256+
}
257+
258+
fn visit_ty(&mut self, ty: &'ast Ty) {
259+
let parent_node = self.parent_node;
260+
self.parent_node = ty.id;
261+
match ty.node {
262+
TyBareFn(ref fd) => {
263+
self.visit_fn_decl(&*fd.decl);
264+
}
265+
_ => {}
266+
}
267+
visit::walk_ty(self, ty);
268+
self.parent_node = parent_node;
269+
}
270+
271+
fn visit_block(&mut self, block: &'ast Block) {
272+
self.insert(block.id, NodeBlock(block));
273+
let parent_node = self.parent_node;
274+
self.parent_node = block.id;
275+
visit::walk_block(self, block);
276+
self.parent_node = parent_node;
277+
}
278+
279+
fn visit_lifetime(&mut self, lifetime: &'ast Lifetime) {
280+
self.insert(lifetime.id, NodeLifetime(lifetime));
281+
}
282+
283+
fn visit_lifetime_def(&mut self, def: &'ast LifetimeDef) {
284+
self.create_def(def.lifetime.id);
285+
self.visit_lifetime(&def.lifetime);
286+
}
287+
288+
fn visit_macro_def(&mut self, macro_def: &'ast MacroDef) {
289+
self.create_def(macro_def.id);
290+
}
291+
}
292+

0 commit comments

Comments
 (0)