Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
rlib sizes: 1445222 liballoc_jemalloc-bb943c5a.rlib 10664 liballoc_system-bb943c5a.rlib 143592 libarena-bb943c5a.rlib 3639102 libcollections-bb943c5a.rlib 16316910 libcore-bb943c5a.rlib 214154 libflate-bb943c5a.rlib 231440 libfmt_macros-bb943c5a.rlib 536976 libgetopts-bb943c5a.rlib 209672 libgraphviz-bb943c5a.rlib 408008 liblibc-bb943c5a.rlib 189610 liblog-bb943c5a.rlib 662184 librand-bb943c5a.rlib 605112 librbml-bb943c5a.rlib 1397820 librustc_back-bb943c5a.rlib 38383772 librustc-bb943c5a.rlib 12842 librustc_bitflags-bb943c5a.rlib 2297822 librustc_borrowck-bb943c5a.rlib 571064 librustc_data_structures-bb943c5a.rlib 9356542 librustc_driver-bb943c5a.rlib 9477226 librustc_front-bb943c5a.rlib 1605698 librustc_lint-bb943c5a.rlib 77111720 librustc_llvm-bb943c5a.rlib 4783848 librustc_mir-bb943c5a.rlib 3534256 librustc_platform_intrinsics-bb943c5a.rlib 593038 librustc_privacy-bb943c5a.rlib 3122202 librustc_resolve-bb943c5a.rlib 14185212 librustc_trans-bb943c5a.rlib 11940328 librustc_typeck-bb943c5a.rlib 1634264 librustc_unicode-bb943c5a.rlib 15564160 librustdoc-bb943c5a.rlib 8153964 libstd-bb943c5a.rlib 30589338 libsyntax-bb943c5a.rlib 897110 libterm-bb943c5a.rlib 1360662 libtest-bb943c5a.rlib
- Loading branch information
Showing
96 changed files
with
2,489 additions
and
1,859 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,344 @@ | ||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
use super::*; | ||
use super::MapEntry::*; | ||
|
||
use rustc_front::hir::*; | ||
use rustc_front::util; | ||
use rustc_front::visit::{self, Visitor}; | ||
use middle::def_id::{CRATE_DEF_INDEX, DefIndex}; | ||
use std::iter::repeat; | ||
use syntax::ast::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID}; | ||
use syntax::codemap::Span; | ||
|
||
/// A Visitor that walks over an AST and collects Node's into an AST | ||
/// Map. | ||
pub struct NodeCollector<'ast> { | ||
pub map: Vec<MapEntry<'ast>>, | ||
pub definitions: Definitions, | ||
pub parent_node: NodeId, | ||
} | ||
|
||
impl<'ast> NodeCollector<'ast> { | ||
pub fn root() -> NodeCollector<'ast> { | ||
let mut collector = NodeCollector { | ||
map: vec![], | ||
definitions: Definitions::new(), | ||
parent_node: CRATE_NODE_ID, | ||
}; | ||
collector.insert_entry(CRATE_NODE_ID, RootCrate); | ||
|
||
let result = collector.create_def_with_parent(None, CRATE_NODE_ID, DefPathData::CrateRoot); | ||
assert_eq!(result, CRATE_DEF_INDEX); | ||
|
||
collector.create_def_with_parent(Some(CRATE_DEF_INDEX), DUMMY_NODE_ID, DefPathData::Misc); | ||
|
||
collector | ||
} | ||
|
||
pub fn extend(parent: &'ast InlinedParent, | ||
parent_node: NodeId, | ||
parent_def_path: DefPath, | ||
map: Vec<MapEntry<'ast>>, | ||
definitions: Definitions) | ||
-> NodeCollector<'ast> { | ||
let mut collector = NodeCollector { | ||
map: map, | ||
parent_node: parent_node, | ||
definitions: definitions, | ||
}; | ||
|
||
collector.insert_entry(parent_node, RootInlinedParent(parent)); | ||
collector.create_def(parent_node, DefPathData::InlinedRoot(parent_def_path)); | ||
|
||
collector | ||
} | ||
|
||
fn parent_def(&self) -> Option<DefIndex> { | ||
let mut parent_node = Some(self.parent_node); | ||
while let Some(p) = parent_node { | ||
if let Some(q) = self.definitions.opt_def_index(p) { | ||
return Some(q); | ||
} | ||
parent_node = self.map[p as usize].parent_node(); | ||
} | ||
None | ||
} | ||
|
||
fn create_def(&mut self, node_id: NodeId, data: DefPathData) -> DefIndex { | ||
let parent_def = self.parent_def(); | ||
self.definitions.create_def_with_parent(parent_def, node_id, data) | ||
} | ||
|
||
fn create_def_with_parent(&mut self, | ||
parent: Option<DefIndex>, | ||
node_id: NodeId, | ||
data: DefPathData) | ||
-> DefIndex { | ||
self.definitions.create_def_with_parent(parent, node_id, data) | ||
} | ||
|
||
fn insert_entry(&mut self, id: NodeId, entry: MapEntry<'ast>) { | ||
debug!("ast_map: {:?} => {:?}", id, entry); | ||
let len = self.map.len(); | ||
if id as usize >= len { | ||
self.map.extend(repeat(NotPresent).take(id as usize - len + 1)); | ||
} | ||
self.map[id as usize] = entry; | ||
} | ||
|
||
fn insert_def(&mut self, id: NodeId, node: Node<'ast>, data: DefPathData) -> DefIndex { | ||
self.insert(id, node); | ||
self.create_def(id, data) | ||
} | ||
|
||
fn insert(&mut self, id: NodeId, node: Node<'ast>) { | ||
let entry = MapEntry::from_node(self.parent_node, node); | ||
self.insert_entry(id, entry); | ||
} | ||
|
||
fn visit_fn_decl(&mut self, decl: &'ast FnDecl) { | ||
for a in &decl.inputs { | ||
self.insert(a.id, NodeArg(&*a.pat)); | ||
} | ||
} | ||
} | ||
|
||
impl<'ast> Visitor<'ast> for NodeCollector<'ast> { | ||
fn visit_item(&mut self, i: &'ast Item) { | ||
// Pick the def data. This need not be unique, but the more | ||
// information we encapsulate into | ||
let def_data = match i.node { | ||
ItemDefaultImpl(..) | ItemImpl(..) => DefPathData::Impl, | ||
ItemEnum(..) | ItemStruct(..) | ItemTrait(..) => DefPathData::Type(i.name), | ||
ItemExternCrate(..) | ItemMod(..) => DefPathData::Mod(i.name), | ||
ItemStatic(..) | ItemConst(..) | ItemFn(..) => DefPathData::Value(i.name), | ||
_ => DefPathData::Misc, | ||
}; | ||
|
||
self.insert_def(i.id, NodeItem(i), def_data); | ||
|
||
let parent_node = self.parent_node; | ||
self.parent_node = i.id; | ||
|
||
match i.node { | ||
ItemImpl(..) => {} | ||
ItemEnum(ref enum_definition, _) => { | ||
for v in &enum_definition.variants { | ||
let variant_def_index = | ||
self.insert_def(v.node.id, | ||
NodeVariant(&**v), | ||
DefPathData::EnumVariant(v.node.name)); | ||
|
||
match v.node.kind { | ||
TupleVariantKind(ref args) => { | ||
for arg in args { | ||
self.create_def_with_parent(Some(variant_def_index), | ||
arg.id, | ||
DefPathData::PositionalField); | ||
} | ||
} | ||
StructVariantKind(ref def) => { | ||
for field in &def.fields { | ||
self.create_def_with_parent( | ||
Some(variant_def_index), | ||
field.node.id, | ||
DefPathData::Field(field.node.kind)); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
ItemForeignMod(..) => { | ||
} | ||
ItemStruct(ref struct_def, _) => { | ||
// If this is a tuple-like struct, register the constructor. | ||
if let Some(ctor_id) = struct_def.ctor_id { | ||
self.insert_def(ctor_id, | ||
NodeStructCtor(&**struct_def), | ||
DefPathData::StructCtor); | ||
} | ||
|
||
for field in &struct_def.fields { | ||
self.create_def(field.node.id, DefPathData::Field(field.node.kind)); | ||
} | ||
} | ||
ItemTrait(_, _, ref bounds, _) => { | ||
for b in bounds.iter() { | ||
if let TraitTyParamBound(ref t, TraitBoundModifier::None) = *b { | ||
self.insert(t.trait_ref.ref_id, NodeItem(i)); | ||
} | ||
} | ||
} | ||
ItemUse(ref view_path) => { | ||
match view_path.node { | ||
ViewPathList(_, ref paths) => { | ||
for path in paths { | ||
self.insert(path.node.id(), NodeItem(i)); | ||
} | ||
} | ||
_ => () | ||
} | ||
} | ||
_ => {} | ||
} | ||
visit::walk_item(self, i); | ||
self.parent_node = parent_node; | ||
} | ||
|
||
fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) { | ||
self.insert_def(foreign_item.id, | ||
NodeForeignItem(foreign_item), | ||
DefPathData::Value(foreign_item.name)); | ||
|
||
let parent_node = self.parent_node; | ||
self.parent_node = foreign_item.id; | ||
visit::walk_foreign_item(self, foreign_item); | ||
self.parent_node = parent_node; | ||
} | ||
|
||
fn visit_generics(&mut self, generics: &'ast Generics) { | ||
for ty_param in generics.ty_params.iter() { | ||
self.insert_def(ty_param.id, | ||
NodeTyParam(ty_param), | ||
DefPathData::TypeParam(ty_param.name)); | ||
} | ||
|
||
visit::walk_generics(self, generics); | ||
} | ||
|
||
fn visit_trait_item(&mut self, ti: &'ast TraitItem) { | ||
let def_data = match ti.node { | ||
MethodTraitItem(..) | ConstTraitItem(..) => DefPathData::Value(ti.name), | ||
TypeTraitItem(..) => DefPathData::Type(ti.name), | ||
}; | ||
|
||
self.insert(ti.id, NodeTraitItem(ti)); | ||
self.create_def(ti.id, def_data); | ||
|
||
let parent_node = self.parent_node; | ||
self.parent_node = ti.id; | ||
|
||
match ti.node { | ||
ConstTraitItem(_, Some(ref expr)) => { | ||
self.create_def(expr.id, DefPathData::Initializer); | ||
} | ||
_ => { } | ||
} | ||
|
||
visit::walk_trait_item(self, ti); | ||
|
||
self.parent_node = parent_node; | ||
} | ||
|
||
fn visit_impl_item(&mut self, ii: &'ast ImplItem) { | ||
let def_data = match ii.node { | ||
MethodImplItem(..) | ConstImplItem(..) => DefPathData::Value(ii.name), | ||
TypeImplItem(..) => DefPathData::Type(ii.name), | ||
}; | ||
|
||
self.insert_def(ii.id, NodeImplItem(ii), def_data); | ||
|
||
let parent_node = self.parent_node; | ||
self.parent_node = ii.id; | ||
|
||
match ii.node { | ||
ConstImplItem(_, ref expr) => { | ||
self.create_def(expr.id, DefPathData::Initializer); | ||
} | ||
_ => { } | ||
} | ||
|
||
visit::walk_impl_item(self, ii); | ||
|
||
self.parent_node = parent_node; | ||
} | ||
|
||
fn visit_pat(&mut self, pat: &'ast Pat) { | ||
let maybe_binding = match pat.node { | ||
PatIdent(_, id, _) => Some(id.node), | ||
_ => None | ||
}; | ||
|
||
if let Some(id) = maybe_binding { | ||
self.insert_def(pat.id, NodeLocal(pat), DefPathData::Binding(id.name)); | ||
} else { | ||
self.insert(pat.id, NodePat(pat)); | ||
} | ||
|
||
let parent_node = self.parent_node; | ||
self.parent_node = pat.id; | ||
visit::walk_pat(self, pat); | ||
self.parent_node = parent_node; | ||
} | ||
|
||
fn visit_expr(&mut self, expr: &'ast Expr) { | ||
self.insert(expr.id, NodeExpr(expr)); | ||
|
||
match expr.node { | ||
ExprClosure(..) => { self.create_def(expr.id, DefPathData::ClosureExpr); } | ||
_ => { } | ||
} | ||
|
||
let parent_node = self.parent_node; | ||
self.parent_node = expr.id; | ||
visit::walk_expr(self, expr); | ||
self.parent_node = parent_node; | ||
} | ||
|
||
fn visit_stmt(&mut self, stmt: &'ast Stmt) { | ||
let id = util::stmt_id(stmt); | ||
self.insert(id, NodeStmt(stmt)); | ||
let parent_node = self.parent_node; | ||
self.parent_node = id; | ||
visit::walk_stmt(self, stmt); | ||
self.parent_node = parent_node; | ||
} | ||
|
||
fn visit_fn(&mut self, fk: visit::FnKind<'ast>, fd: &'ast FnDecl, | ||
b: &'ast Block, s: Span, id: NodeId) { | ||
assert_eq!(self.parent_node, id); | ||
self.visit_fn_decl(fd); | ||
visit::walk_fn(self, fk, fd, b, s); | ||
} | ||
|
||
fn visit_ty(&mut self, ty: &'ast Ty) { | ||
match ty.node { | ||
TyBareFn(ref fd) => { | ||
self.visit_fn_decl(&*fd.decl); | ||
} | ||
_ => {} | ||
} | ||
visit::walk_ty(self, ty); | ||
} | ||
|
||
fn visit_block(&mut self, block: &'ast Block) { | ||
self.insert(block.id, NodeBlock(block)); | ||
let parent_node = self.parent_node; | ||
self.parent_node = block.id; | ||
visit::walk_block(self, block); | ||
self.parent_node = parent_node; | ||
} | ||
|
||
fn visit_lifetime(&mut self, lifetime: &'ast Lifetime) { | ||
self.insert(lifetime.id, NodeLifetime(lifetime)); | ||
} | ||
|
||
fn visit_lifetime_def(&mut self, def: &'ast LifetimeDef) { | ||
self.create_def(def.lifetime.id, DefPathData::LifetimeDef(def.lifetime.name)); | ||
self.visit_lifetime(&def.lifetime); | ||
} | ||
|
||
fn visit_macro_def(&mut self, macro_def: &'ast MacroDef) { | ||
self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.name)); | ||
} | ||
} | ||
|
Oops, something went wrong.