build up a set of node-ids that we can construct def-ids from
This commit is contained in:
parent
a0dc2d9a29
commit
d7b0eb0f39
7 changed files with 371 additions and 237 deletions
292
src/librustc/front/map/collector.rs
Normal file
292
src/librustc/front/map/collector.rs
Normal file
|
@ -0,0 +1,292 @@
|
||||||
|
// 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 std::iter::repeat;
|
||||||
|
use syntax::ast::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID};
|
||||||
|
use syntax::codemap::Span;
|
||||||
|
use util::nodemap::NodeSet;
|
||||||
|
|
||||||
|
/// 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_map: NodeSet,
|
||||||
|
pub parent_node: NodeId,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ast> NodeCollector<'ast> {
|
||||||
|
pub fn root() -> NodeCollector<'ast> {
|
||||||
|
let mut collector = NodeCollector {
|
||||||
|
map: vec![],
|
||||||
|
definitions_map: NodeSet(),
|
||||||
|
parent_node: CRATE_NODE_ID,
|
||||||
|
};
|
||||||
|
collector.insert_entry(CRATE_NODE_ID, RootCrate);
|
||||||
|
collector.create_def(CRATE_NODE_ID);
|
||||||
|
collector.create_def(DUMMY_NODE_ID);
|
||||||
|
collector
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn extend(parent: &'ast InlinedParent,
|
||||||
|
parent_node: NodeId,
|
||||||
|
map: Vec<MapEntry<'ast>>,
|
||||||
|
definitions_map: NodeSet)
|
||||||
|
-> NodeCollector<'ast> {
|
||||||
|
let mut collector = NodeCollector {
|
||||||
|
map: map,
|
||||||
|
definitions_map: definitions_map,
|
||||||
|
parent_node: parent_node
|
||||||
|
};
|
||||||
|
collector.insert_entry(parent_node, RootInlinedParent(parent));
|
||||||
|
|
||||||
|
collector
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_def(&mut self, node: NodeId) {
|
||||||
|
let is_new = self.definitions_map.insert(node);
|
||||||
|
assert!(is_new,
|
||||||
|
"two entries for node id `{}` -- previous is `{:?}`",
|
||||||
|
node, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
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(&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) {
|
||||||
|
self.insert(i.id, NodeItem(i));
|
||||||
|
|
||||||
|
let parent_node = self.parent_node;
|
||||||
|
self.parent_node = i.id;
|
||||||
|
|
||||||
|
self.create_def(i.id);
|
||||||
|
|
||||||
|
match i.node {
|
||||||
|
ItemImpl(..) => { }
|
||||||
|
ItemEnum(ref enum_definition, _) => {
|
||||||
|
for v in &enum_definition.variants {
|
||||||
|
self.insert(v.node.id, NodeVariant(&**v));
|
||||||
|
self.create_def(v.node.id);
|
||||||
|
|
||||||
|
match v.node.kind {
|
||||||
|
TupleVariantKind(ref args) => {
|
||||||
|
for arg in args {
|
||||||
|
self.create_def(arg.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StructVariantKind(ref def) => {
|
||||||
|
for field in &def.fields {
|
||||||
|
self.create_def(field.node.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ItemForeignMod(..) => {}
|
||||||
|
ItemStruct(ref struct_def, _) => {
|
||||||
|
// If this is a tuple-like struct, register the constructor.
|
||||||
|
match struct_def.ctor_id {
|
||||||
|
Some(ctor_id) => {
|
||||||
|
self.insert(ctor_id, NodeStructCtor(&**struct_def));
|
||||||
|
self.create_def(ctor_id);
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
for field in &struct_def.fields {
|
||||||
|
self.create_def(field.node.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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(foreign_item.id, NodeForeignItem(foreign_item));
|
||||||
|
self.create_def(foreign_item.id);
|
||||||
|
|
||||||
|
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.create_def(ty_param.id);
|
||||||
|
self.insert(ty_param.id, NodeTyParam(ty_param));
|
||||||
|
}
|
||||||
|
|
||||||
|
visit::walk_generics(self, generics);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_trait_item(&mut self, ti: &'ast TraitItem) {
|
||||||
|
self.insert(ti.id, NodeTraitItem(ti));
|
||||||
|
self.create_def(ti.id);
|
||||||
|
|
||||||
|
match ti.node {
|
||||||
|
ConstTraitItem(_, Some(ref expr)) => {
|
||||||
|
self.create_def(expr.id);
|
||||||
|
}
|
||||||
|
_ => { }
|
||||||
|
}
|
||||||
|
|
||||||
|
let parent_node = self.parent_node;
|
||||||
|
self.parent_node = ti.id;
|
||||||
|
visit::walk_trait_item(self, ti);
|
||||||
|
self.parent_node = parent_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_impl_item(&mut self, ii: &'ast ImplItem) {
|
||||||
|
self.insert(ii.id, NodeImplItem(ii));
|
||||||
|
self.create_def(ii.id);
|
||||||
|
|
||||||
|
match ii.node {
|
||||||
|
ConstImplItem(_, ref expr) => {
|
||||||
|
self.create_def(expr.id);
|
||||||
|
}
|
||||||
|
_ => { }
|
||||||
|
}
|
||||||
|
|
||||||
|
let parent_node = self.parent_node;
|
||||||
|
self.parent_node = ii.id;
|
||||||
|
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(..) => true,
|
||||||
|
_ => false
|
||||||
|
};
|
||||||
|
|
||||||
|
self.insert(pat.id,
|
||||||
|
if maybe_binding {NodeLocal(pat)} else {NodePat(pat)});
|
||||||
|
|
||||||
|
if maybe_binding {
|
||||||
|
self.create_def(pat.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
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),
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
let parent_node = self.parent_node;
|
||||||
|
self.parent_node = id;
|
||||||
|
self.visit_fn_decl(fd);
|
||||||
|
visit::walk_fn(self, fk, fd, b, s);
|
||||||
|
self.parent_node = parent_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_ty(&mut self, ty: &'ast Ty) {
|
||||||
|
let parent_node = self.parent_node;
|
||||||
|
self.parent_node = ty.id;
|
||||||
|
match ty.node {
|
||||||
|
TyBareFn(ref fd) => {
|
||||||
|
self.visit_fn_decl(&*fd.decl);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
visit::walk_ty(self, ty);
|
||||||
|
self.parent_node = parent_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
self.visit_lifetime(&def.lifetime);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_macro_def(&mut self, macro_def: &'ast MacroDef) {
|
||||||
|
self.create_def(macro_def.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -11,32 +11,34 @@
|
||||||
pub use self::Node::*;
|
pub use self::Node::*;
|
||||||
pub use self::PathElem::*;
|
pub use self::PathElem::*;
|
||||||
use self::MapEntry::*;
|
use self::MapEntry::*;
|
||||||
|
use self::collector::NodeCollector;
|
||||||
|
|
||||||
use metadata::cstore::LOCAL_CRATE;
|
use metadata::cstore::LOCAL_CRATE;
|
||||||
use metadata::inline::InlinedItem;
|
use metadata::inline::InlinedItem;
|
||||||
use metadata::inline::InlinedItem as II;
|
use metadata::inline::InlinedItem as II;
|
||||||
use middle::def_id::DefId;
|
use middle::def_id::DefId;
|
||||||
|
use util::nodemap::NodeSet;
|
||||||
|
|
||||||
use syntax::abi;
|
use syntax::abi;
|
||||||
use syntax::ast::{self, Name, NodeId, CRATE_NODE_ID, DUMMY_NODE_ID};
|
use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID};
|
||||||
use syntax::codemap::{Span, Spanned};
|
use syntax::codemap::{Span, Spanned};
|
||||||
use syntax::parse::token;
|
use syntax::parse::token;
|
||||||
|
|
||||||
use rustc_front::hir::*;
|
use rustc_front::hir::*;
|
||||||
use rustc_front::fold::Folder;
|
use rustc_front::fold::Folder;
|
||||||
use rustc_front::visit::{self, Visitor};
|
use rustc_front::visit;
|
||||||
use rustc_front::util;
|
|
||||||
use rustc_front::print::pprust;
|
use rustc_front::print::pprust;
|
||||||
|
|
||||||
use arena::TypedArena;
|
use arena::TypedArena;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::iter::{self, repeat};
|
use std::iter;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
|
||||||
pub mod blocks;
|
pub mod blocks;
|
||||||
|
mod collector;
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||||
pub enum PathElem {
|
pub enum PathElem {
|
||||||
|
@ -131,7 +133,7 @@ pub enum Node<'ast> {
|
||||||
/// Represents an entry and its parent NodeID.
|
/// Represents an entry and its parent NodeID.
|
||||||
/// The odd layout is to bring down the total size.
|
/// The odd layout is to bring down the total size.
|
||||||
#[derive(Copy, Debug)]
|
#[derive(Copy, Debug)]
|
||||||
enum MapEntry<'ast> {
|
pub enum MapEntry<'ast> {
|
||||||
/// Placeholder for holes in the map.
|
/// Placeholder for holes in the map.
|
||||||
NotPresent,
|
NotPresent,
|
||||||
|
|
||||||
|
@ -264,22 +266,46 @@ pub struct Map<'ast> {
|
||||||
///
|
///
|
||||||
/// Also, indexing is pretty quick when you've got a vector and
|
/// Also, indexing is pretty quick when you've got a vector and
|
||||||
/// plain old integers.
|
/// plain old integers.
|
||||||
map: RefCell<Vec<MapEntry<'ast>>>
|
map: RefCell<Vec<MapEntry<'ast>>>,
|
||||||
|
|
||||||
|
definitions_map: RefCell<NodeSet>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast> Map<'ast> {
|
impl<'ast> Map<'ast> {
|
||||||
pub fn local_def_id(&self, node: NodeId) -> DefId {
|
pub fn local_def_id(&self, node: NodeId) -> DefId {
|
||||||
DefId::xxx_local(node)
|
self.opt_local_def_id(node).unwrap_or_else(|| {
|
||||||
|
panic!("local_def_id: no entry for `{}`, which has a map of `{:?}`",
|
||||||
|
node, self.find_entry(node))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn opt_local_def_id(&self, node: NodeId) -> Option<DefId> {
|
||||||
|
if self.definitions_map.borrow().contains(&node) {
|
||||||
|
Some(DefId::xxx_local(node))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_local_node_id(&self, def_id: DefId) -> Option<NodeId> {
|
pub fn as_local_node_id(&self, def_id: DefId) -> Option<NodeId> {
|
||||||
if def_id.krate == LOCAL_CRATE {
|
if def_id.krate == LOCAL_CRATE {
|
||||||
|
assert!(self.definitions_map.borrow().contains(&def_id.xxx_node));
|
||||||
Some(def_id.xxx_node)
|
Some(def_id.xxx_node)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// for default methods, we create a fake node-id; this method
|
||||||
|
/// adds that fake node-id to the def-id tables
|
||||||
|
pub fn synthesize_default_method_def_id(&self,
|
||||||
|
_impl_def_id: DefId,
|
||||||
|
new_method_id: NodeId)
|
||||||
|
-> DefId {
|
||||||
|
self.definitions_map.borrow_mut().insert(new_method_id);
|
||||||
|
DefId::xxx_local(new_method_id)
|
||||||
|
}
|
||||||
|
|
||||||
fn entry_count(&self) -> usize {
|
fn entry_count(&self) -> usize {
|
||||||
self.map.borrow().len()
|
self.map.borrow().len()
|
||||||
}
|
}
|
||||||
|
@ -762,194 +788,10 @@ impl<F: FoldOps> Folder for IdAndSpanUpdater<F> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A Visitor that walks over an AST and collects Node's into an AST Map.
|
|
||||||
struct NodeCollector<'ast> {
|
|
||||||
map: Vec<MapEntry<'ast>>,
|
|
||||||
parent_node: NodeId,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ast> NodeCollector<'ast> {
|
|
||||||
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(&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) {
|
|
||||||
self.insert(i.id, NodeItem(i));
|
|
||||||
|
|
||||||
let parent_node = self.parent_node;
|
|
||||||
self.parent_node = i.id;
|
|
||||||
|
|
||||||
match i.node {
|
|
||||||
ItemImpl(_, _, _, _, _, ref impl_items) => {
|
|
||||||
for ii in impl_items {
|
|
||||||
self.insert(ii.id, NodeImplItem(ii));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ItemEnum(ref enum_definition, _) => {
|
|
||||||
for v in &enum_definition.variants {
|
|
||||||
self.insert(v.node.id, NodeVariant(&**v));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ItemForeignMod(ref nm) => {
|
|
||||||
for nitem in &nm.items {
|
|
||||||
self.insert(nitem.id, NodeForeignItem(&**nitem));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ItemStruct(ref struct_def, _) => {
|
|
||||||
// If this is a tuple-like struct, register the constructor.
|
|
||||||
match struct_def.ctor_id {
|
|
||||||
Some(ctor_id) => {
|
|
||||||
self.insert(ctor_id, NodeStructCtor(&**struct_def));
|
|
||||||
}
|
|
||||||
None => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ItemTrait(_, _, ref bounds, ref trait_items) => {
|
|
||||||
for b in bounds.iter() {
|
|
||||||
if let TraitTyParamBound(ref t, TraitBoundModifier::None) = *b {
|
|
||||||
self.insert(t.trait_ref.ref_id, NodeItem(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for ti in trait_items {
|
|
||||||
self.insert(ti.id, NodeTraitItem(ti));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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_generics(&mut self, generics: &'ast Generics) {
|
|
||||||
for ty_param in generics.ty_params.iter() {
|
|
||||||
self.insert(ty_param.id, NodeTyParam(ty_param));
|
|
||||||
}
|
|
||||||
|
|
||||||
visit::walk_generics(self, generics);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_trait_item(&mut self, ti: &'ast TraitItem) {
|
|
||||||
let parent_node = self.parent_node;
|
|
||||||
self.parent_node = ti.id;
|
|
||||||
visit::walk_trait_item(self, ti);
|
|
||||||
self.parent_node = parent_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_impl_item(&mut self, ii: &'ast ImplItem) {
|
|
||||||
let parent_node = self.parent_node;
|
|
||||||
self.parent_node = ii.id;
|
|
||||||
|
|
||||||
visit::walk_impl_item(self, ii);
|
|
||||||
|
|
||||||
self.parent_node = parent_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_pat(&mut self, pat: &'ast Pat) {
|
|
||||||
self.insert(pat.id, match pat.node {
|
|
||||||
// Note: this is at least *potentially* a pattern...
|
|
||||||
PatIdent(..) => NodeLocal(pat),
|
|
||||||
_ => 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));
|
|
||||||
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) {
|
|
||||||
let parent_node = self.parent_node;
|
|
||||||
self.parent_node = id;
|
|
||||||
self.visit_fn_decl(fd);
|
|
||||||
visit::walk_fn(self, fk, fd, b, s);
|
|
||||||
self.parent_node = parent_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_ty(&mut self, ty: &'ast Ty) {
|
|
||||||
let parent_node = self.parent_node;
|
|
||||||
self.parent_node = ty.id;
|
|
||||||
match ty.node {
|
|
||||||
TyBareFn(ref fd) => {
|
|
||||||
self.visit_fn_decl(&*fd.decl);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
visit::walk_ty(self, ty);
|
|
||||||
self.parent_node = parent_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
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.visit_lifetime(&def.lifetime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn map_crate<'ast>(forest: &'ast mut Forest) -> Map<'ast> {
|
pub fn map_crate<'ast>(forest: &'ast mut Forest) -> Map<'ast> {
|
||||||
let mut collector = NodeCollector {
|
let mut collector = NodeCollector::root();
|
||||||
map: vec![],
|
|
||||||
parent_node: CRATE_NODE_ID,
|
|
||||||
};
|
|
||||||
collector.insert_entry(CRATE_NODE_ID, RootCrate);
|
|
||||||
visit::walk_crate(&mut collector, &forest.krate);
|
visit::walk_crate(&mut collector, &forest.krate);
|
||||||
let map = collector.map;
|
let NodeCollector { map, definitions_map, .. } = collector;
|
||||||
|
|
||||||
if log_enabled!(::log::DEBUG) {
|
if log_enabled!(::log::DEBUG) {
|
||||||
// This only makes sense for ordered stores; note the
|
// This only makes sense for ordered stores; note the
|
||||||
|
@ -969,7 +811,8 @@ pub fn map_crate<'ast>(forest: &'ast mut Forest) -> Map<'ast> {
|
||||||
|
|
||||||
Map {
|
Map {
|
||||||
forest: forest,
|
forest: forest,
|
||||||
map: RefCell::new(map)
|
map: RefCell::new(map),
|
||||||
|
definitions_map: RefCell::new(definitions_map),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1001,29 +844,16 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
|
||||||
});
|
});
|
||||||
|
|
||||||
let ii_parent_id = fld.new_id(DUMMY_NODE_ID);
|
let ii_parent_id = fld.new_id(DUMMY_NODE_ID);
|
||||||
let mut collector = NodeCollector {
|
let mut collector =
|
||||||
map: mem::replace(&mut *map.map.borrow_mut(), vec![]),
|
NodeCollector::extend(ii_parent,
|
||||||
parent_node: ii_parent_id,
|
ii_parent_id,
|
||||||
};
|
mem::replace(&mut *map.map.borrow_mut(), vec![]),
|
||||||
collector.insert_entry(ii_parent_id, RootInlinedParent(ii_parent));
|
mem::replace(&mut *map.definitions_map.borrow_mut(), NodeSet()));
|
||||||
ii_parent.ii.visit(&mut collector);
|
ii_parent.ii.visit(&mut collector);
|
||||||
|
|
||||||
// Methods get added to the AST map when their impl is visited. Since we
|
|
||||||
// don't decode and instantiate the impl, but just the method, we have to
|
|
||||||
// add it to the table now. Likewise with foreign items.
|
|
||||||
match ii_parent.ii {
|
|
||||||
II::Item(_) => {}
|
|
||||||
II::TraitItem(_, ref ti) => {
|
|
||||||
collector.insert(ti.id, NodeTraitItem(ti));
|
|
||||||
}
|
|
||||||
II::ImplItem(_, ref ii) => {
|
|
||||||
collector.insert(ii.id, NodeImplItem(ii));
|
|
||||||
}
|
|
||||||
II::Foreign(ref i) => {
|
|
||||||
collector.insert(i.id, NodeForeignItem(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*map.map.borrow_mut() = collector.map;
|
*map.map.borrow_mut() = collector.map;
|
||||||
|
*map.definitions_map.borrow_mut() = collector.definitions_map;
|
||||||
|
|
||||||
&ii_parent.ii
|
&ii_parent.ii
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -957,12 +957,14 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let lid = tcx.map.local_def_id(id);
|
let opt_def_id = tcx.map.opt_local_def_id(id);
|
||||||
if let Some(type_scheme) = tcx.tcache.borrow().get(&lid) {
|
if let Some(lid) = opt_def_id {
|
||||||
rbml_w.tag(c::tag_table_tcache, |rbml_w| {
|
if let Some(type_scheme) = tcx.tcache.borrow().get(&lid) {
|
||||||
rbml_w.id(id);
|
rbml_w.tag(c::tag_table_tcache, |rbml_w| {
|
||||||
rbml_w.emit_type_scheme(ecx, type_scheme.clone());
|
rbml_w.id(id);
|
||||||
})
|
rbml_w.emit_type_scheme(ecx, type_scheme.clone());
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(type_param_def) = tcx.ty_param_defs.borrow().get(&id) {
|
if let Some(type_param_def) = tcx.ty_param_defs.borrow().get(&id) {
|
||||||
|
@ -1003,18 +1005,22 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(closure_type) = tcx.tables.borrow().closure_tys.get(&tcx.map.local_def_id(id)) {
|
if let Some(def_id) = opt_def_id {
|
||||||
rbml_w.tag(c::tag_table_closure_tys, |rbml_w| {
|
if let Some(closure_type) = tcx.tables.borrow().closure_tys.get(&def_id) {
|
||||||
rbml_w.id(id);
|
rbml_w.tag(c::tag_table_closure_tys, |rbml_w| {
|
||||||
rbml_w.emit_closure_type(ecx, closure_type);
|
rbml_w.id(id);
|
||||||
})
|
rbml_w.emit_closure_type(ecx, closure_type);
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(closure_kind) = tcx.tables.borrow().closure_kinds.get(&tcx.map.local_def_id(id)) {
|
if let Some(def_id) = opt_def_id {
|
||||||
rbml_w.tag(c::tag_table_closure_kinds, |rbml_w| {
|
if let Some(closure_kind) = tcx.tables.borrow().closure_kinds.get(&def_id) {
|
||||||
rbml_w.id(id);
|
rbml_w.tag(c::tag_table_closure_kinds, |rbml_w| {
|
||||||
encode_closure_kind(rbml_w, *closure_kind)
|
rbml_w.id(id);
|
||||||
})
|
encode_closure_kind(rbml_w, *closure_kind)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(cast_kind) = tcx.cast_kinds.borrow().get(&id) {
|
if let Some(cast_kind) = tcx.cast_kinds.borrow().get(&id) {
|
||||||
|
|
|
@ -27,7 +27,7 @@ use std::fmt;
|
||||||
use syntax::abi;
|
use syntax::abi;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::parse::token;
|
use syntax::parse::token;
|
||||||
use syntax::ast::DUMMY_NODE_ID;
|
use syntax::ast::{CRATE_NODE_ID};
|
||||||
use rustc_front::hir;
|
use rustc_front::hir;
|
||||||
|
|
||||||
pub fn verbose() -> bool {
|
pub fn verbose() -> bool {
|
||||||
|
@ -232,7 +232,7 @@ fn in_binder<'tcx, T, U>(f: &mut fmt::Formatter,
|
||||||
ty::BrEnv => {
|
ty::BrEnv => {
|
||||||
let name = token::intern("'r");
|
let name = token::intern("'r");
|
||||||
let _ = write!(f, "{}", name);
|
let _ = write!(f, "{}", name);
|
||||||
ty::BrNamed(tcx.map.local_def_id(DUMMY_NODE_ID), name)
|
ty::BrNamed(tcx.map.local_def_id(CRATE_NODE_ID), name)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}).0;
|
}).0;
|
||||||
|
|
|
@ -248,8 +248,11 @@ impl LateLintPass for NonShorthandFieldPatterns {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let def = def_map.get(&fieldpat.node.pat.id).map(|d| d.full_def());
|
let def = def_map.get(&fieldpat.node.pat.id).map(|d| d.full_def());
|
||||||
let def_id = cx.tcx.map.local_def_id(fieldpat.node.pat.id);
|
if let Some(def_id) = cx.tcx.map.opt_local_def_id(fieldpat.node.pat.id) {
|
||||||
def == Some(def::DefLocal(def_id, fieldpat.node.pat.id))
|
def == Some(def::DefLocal(def_id, fieldpat.node.pat.id))
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
});
|
});
|
||||||
for fieldpat in field_pats {
|
for fieldpat in field_pats {
|
||||||
if let hir::PatIdent(_, ident, None) = fieldpat.node.pat.node {
|
if let hir::PatIdent(_, ident, None) = fieldpat.node.pat.node {
|
||||||
|
|
|
@ -188,7 +188,7 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
|
||||||
attrs: child.attrs.clone(),
|
attrs: child.attrs.clone(),
|
||||||
visibility: Some(hir::Public),
|
visibility: Some(hir::Public),
|
||||||
stability: None,
|
stability: None,
|
||||||
def_id: cx.map.local_def_id(prim.to_node_id()),
|
def_id: DefId::xxx_local(prim.to_node_id()),
|
||||||
inner: PrimitiveItem(prim),
|
inner: PrimitiveItem(prim),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,8 +62,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stability(&self, id: ast::NodeId) -> Option<attr::Stability> {
|
fn stability(&self, id: ast::NodeId) -> Option<attr::Stability> {
|
||||||
self.cx.tcx_opt().and_then(
|
self.cx.tcx_opt().and_then(|tcx| {
|
||||||
|tcx| stability::lookup(tcx, self.cx.map.local_def_id(id)).map(|x| x.clone()))
|
self.cx.map.opt_local_def_id(id)
|
||||||
|
.and_then(|def_id| stability::lookup(tcx, def_id))
|
||||||
|
.cloned()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn visit(&mut self, krate: &hir::Crate) {
|
pub fn visit(&mut self, krate: &hir::Crate) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue