def_collector and crate reader operate on AST instead of HIR

And move extern crate reading earlier in the driver
This commit is contained in:
Nick Cameron 2016-04-14 14:51:21 +12:00
parent 6af7acab1c
commit 84c3f898f9
5 changed files with 112 additions and 150 deletions

View file

@ -10,10 +10,10 @@
use super::*;
use hir::*;
use hir::intravisit::Visitor;
use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex};
use syntax::ast::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID};
use syntax::ast::*;
use syntax::visit;
/// Creates def ids for nodes in the HIR.
pub struct DefCollector<'ast> {
@ -80,31 +80,23 @@ impl<'ast> DefCollector<'ast> {
}
}
impl<'ast> Visitor<'ast> for DefCollector<'ast> {
/// Because we want to track parent items and so forth, enable
/// deep walking so that we walk nested items in the context of
/// their outer items.
fn visit_nested_item(&mut self, item: ItemId) {
debug!("visit_nested_item: {:?}", item);
self.visit_item(self.krate.item(item.id))
}
impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> {
fn visit_item(&mut self, i: &'ast Item) {
debug!("visit_item: {:?}", i);
// Pick the def data. This need not be unique, but the more
// information we encapsulate into
let def_data = match i.node {
ItemDefaultImpl(..) | ItemImpl(..) =>
ItemKind::DefaultImpl(..) | ItemKind::Impl(..) =>
DefPathData::Impl,
ItemEnum(..) | ItemStruct(..) | ItemTrait(..) |
ItemExternCrate(..) | ItemMod(..) | ItemForeignMod(..) |
ItemTy(..) =>
DefPathData::TypeNs(i.name),
ItemStatic(..) | ItemConst(..) | ItemFn(..) =>
DefPathData::ValueNs(i.name),
ItemUse(..) =>
DefPathData::Misc,
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Trait(..) |
ItemKind::ExternCrate(..) | ItemKind::Mod(..) | ItemKind::ForeignMod(..) |
ItemKind::Ty(..) =>
DefPathData::TypeNs(i.ident.name),
ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) =>
DefPathData::ValueNs(i.ident.name),
ItemKind::Mac(..) => DefPathData::MacroDef(i.ident.name),
ItemKind::Use(..) => DefPathData::Misc,
};
let def = self.create_def(i.id, def_data);
@ -113,21 +105,22 @@ impl<'ast> Visitor<'ast> for DefCollector<'ast> {
self.parent_def = Some(def);
match i.node {
ItemEnum(ref enum_definition, _) => {
ItemKind::Enum(ref enum_definition, _) => {
for v in &enum_definition.variants {
let variant_def_index =
self.create_def(v.node.data.id(),
DefPathData::EnumVariant(v.node.name));
DefPathData::EnumVariant(v.node.name.name));
for field in v.node.data.fields() {
self.create_def_with_parent(
Some(variant_def_index),
field.id,
DefPathData::Field(field.name));
if let Some(ident) = field.ident {
self.create_def_with_parent(Some(variant_def_index),
field.id,
DefPathData::Field(ident.name));
}
}
}
}
ItemStruct(ref struct_def, _) => {
ItemKind::Struct(ref struct_def, _) => {
// If this is a tuple-like struct, register the constructor.
if !struct_def.is_struct() {
self.create_def(struct_def.id(),
@ -135,37 +128,40 @@ impl<'ast> Visitor<'ast> for DefCollector<'ast> {
}
for field in struct_def.fields() {
self.create_def(field.id, DefPathData::Field(field.name));
if let Some(ident) = field.ident {
self.create_def(field.id, DefPathData::Field(ident.name));
}
}
}
_ => {}
}
intravisit::walk_item(self, i);
visit::walk_item(self, i);
self.parent_def = parent_def;
}
fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) {
let def = self.create_def(foreign_item.id, DefPathData::ValueNs(foreign_item.name));
let def = self.create_def(foreign_item.id, DefPathData::ValueNs(foreign_item.ident.name));
let parent_def = self.parent_def;
self.parent_def = Some(def);
intravisit::walk_foreign_item(self, foreign_item);
visit::walk_foreign_item(self, foreign_item);
self.parent_def = parent_def;
}
fn visit_generics(&mut self, generics: &'ast Generics) {
for ty_param in generics.ty_params.iter() {
self.create_def(ty_param.id,
DefPathData::TypeParam(ty_param.name));
DefPathData::TypeParam(ty_param.ident.name));
}
intravisit::walk_generics(self, generics);
visit::walk_generics(self, generics);
}
fn visit_trait_item(&mut self, ti: &'ast TraitItem) {
let def_data = match ti.node {
MethodTraitItem(..) | ConstTraitItem(..) => DefPathData::ValueNs(ti.name),
TypeTraitItem(..) => DefPathData::TypeNs(ti.name),
TraitItemKind::Method(..) | TraitItemKind::Const(..) =>
DefPathData::ValueNs(ti.ident.name),
TraitItemKind::Type(..) => DefPathData::TypeNs(ti.ident.name),
};
let def = self.create_def(ti.id, def_data);
@ -174,21 +170,23 @@ impl<'ast> Visitor<'ast> for DefCollector<'ast> {
self.parent_def = Some(def);
match ti.node {
ConstTraitItem(_, Some(ref expr)) => {
TraitItemKind::Const(_, Some(ref expr)) => {
self.create_def(expr.id, DefPathData::Initializer);
}
_ => { }
}
intravisit::walk_trait_item(self, ti);
visit::walk_trait_item(self, ti);
self.parent_def = parent_def;
}
fn visit_impl_item(&mut self, ii: &'ast ImplItem) {
let def_data = match ii.node {
ImplItemKind::Method(..) | ImplItemKind::Const(..) => DefPathData::ValueNs(ii.name),
ImplItemKind::Type(..) => DefPathData::TypeNs(ii.name),
ImplItemKind::Method(..) | ImplItemKind::Const(..) =>
DefPathData::ValueNs(ii.ident.name),
ImplItemKind::Type(..) => DefPathData::TypeNs(ii.ident.name),
ImplItemKind::Macro(..) => DefPathData::MacroDef(ii.ident.name),
};
let def = self.create_def(ii.id, def_data);
@ -203,7 +201,7 @@ impl<'ast> Visitor<'ast> for DefCollector<'ast> {
_ => { }
}
intravisit::walk_impl_item(self, ii);
visit::walk_impl_item(self, ii);
self.parent_def = parent_def;
}
@ -220,28 +218,28 @@ impl<'ast> Visitor<'ast> for DefCollector<'ast> {
self.parent_def = Some(def);
}
intravisit::walk_pat(self, pat);
visit::walk_pat(self, pat);
self.parent_def = parent_def;
}
fn visit_expr(&mut self, expr: &'ast Expr) {
let parent_def = self.parent_def;
if let ExprClosure(..) = expr.node {
if let ExprKind::Closure(..) = expr.node {
let def = self.create_def(expr.id, DefPathData::ClosureExpr);
self.parent_def = Some(def);
}
intravisit::walk_expr(self, expr);
visit::walk_expr(self, expr);
self.parent_def = parent_def;
}
fn visit_stmt(&mut self, stmt: &'ast Stmt) {
intravisit::walk_stmt(self, stmt);
visit::walk_stmt(self, stmt);
}
fn visit_block(&mut self, block: &'ast Block) {
intravisit::walk_block(self, block);
visit::walk_block(self, block);
}
fn visit_lifetime_def(&mut self, def: &'ast LifetimeDef) {
@ -249,6 +247,6 @@ impl<'ast> Visitor<'ast> for DefCollector<'ast> {
}
fn visit_macro_def(&mut self, macro_def: &'ast MacroDef) {
self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.name));
self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.ident.name));
}
}

View file

@ -22,9 +22,10 @@ use middle::cstore::InlinedItem as II;
use hir::def_id::{CRATE_DEF_INDEX, DefId};
use syntax::abi::Abi;
use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID};
use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID, };
use syntax::attr::ThinAttributesExt;
use syntax::codemap::{Span, Spanned};
use syntax::visit;
use hir::*;
use hir::fold::Folder;
@ -782,10 +783,10 @@ impl<F: FoldOps> Folder for IdAndSpanUpdater<F> {
}
}
pub fn collect_definitions<'ast>(forest: &'ast mut Forest) -> Definitions {
let mut def_collector = DefCollector::root(&forest.krate);
intravisit::walk_crate(&mut def_collector, &forest.krate);
def_collector.definitions
pub fn collect_definitions<'ast>(krate: &'ast ast::Crate) -> Definitions {
let mut def_collector = DefCollector::root(krate);
visit::walk_crate(&mut def_collector, krate);
def_collector.definitions
}
pub fn map_crate<'ast>(forest: &'ast mut Forest, definitions: Definitions) -> Map<'ast> {
@ -842,14 +843,15 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
let ii = map.forest.inlined_items.alloc(ii);
let ii_parent_id = fld.new_id(DUMMY_NODE_ID);
let defs = mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new());
let mut def_collector = DefCollector::extend(map.krate(),
ii_parent_id,
parent_def_path.clone(),
parent_def_id,
defs);
ii.visit(&mut def_collector);
*map.definitions.borrow_mut() = def_collector.definitions;
// TODO need to save defs in metadata :-(
// let defs = mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new());
// let mut def_collector = DefCollector::extend(map.krate(),
// ii_parent_id,
// parent_def_path.clone(),
// parent_def_id,
// defs);
// ii.visit(&mut def_collector);
// *map.definitions.borrow_mut() = def_collector.definitions;
let mut collector = NodeCollector::extend(map.krate(),
ii,

View file

@ -122,32 +122,22 @@ pub fn compile_input(sess: &Session,
let expanded_crate = assign_node_ids(sess, expanded_crate);
let dep_graph = DepGraph::new(sess.opts.build_dep_graph);
// TODO
// time(sess.time_passes(),
// "external crate/lib resolution",
// || LocalCrateReader::new(sess, &cstore, &defs, &id).read_crates());
// Collect defintions for def ids.
let defs = time(sess.time_passes(),
"collecting defs",
|| hir_map::collect_definitions(&expanded_crate));
// TODO
panic!();
// TODO CrateMap result
// let resolve::CrateMap {
// def_map,
// freevars,
// export_map,
// trait_map,
// glob_map,
// } = time(sess.time_passes(),
// "name resolution",
// || resolve::resolve_crate(sess, &hir_map, control.make_glob_map));
time(sess.time_passes(),
"external crate/lib resolution",
|| LocalCrateReader::new(sess, &cstore, &defs, &expanded_crate, &id)
.read_crates(&dep_graph));
// Lower ast -> hir.
let lcx = LoweringContext::new(sess, Some(&expanded_crate));
let dep_graph = DepGraph::new(sess.opts.build_dep_graph());
let mut hir_forest = time(sess.time_passes(),
"lowering ast -> hir",
|| hir_map::Forest::new(lower_crate(&lcx, &expanded_crate),
dep_graph));
let hir_forest = &mut time(sess.time_passes(),
"lowering ast -> hir",
|| hir_map::Forest::new(lower_crate(&lcx, &expanded_crate),
dep_graph));
// Discard MTWT tables that aren't required past lowering to HIR.
if !sess.opts.debugging_opts.keep_mtwt_tables &&
@ -156,10 +146,6 @@ pub fn compile_input(sess: &Session,
}
let arenas = ty::CtxtArenas::new();
// Collect defintions for def ids.
let defs = time(sess.time_passes(),
"collecting defs",
move || hir_map::collect_defs(hir_forest));
// Construct the HIR map
let hir_map = time(sess.time_passes(),
@ -201,10 +187,10 @@ pub fn compile_input(sess: &Session,
};
phase_3_run_analysis_passes(sess,
&cstore,
hir_map,
&arenas,
&id,
control.make_glob_map,
|tcx, mir_map, analysis, result| {
{
// Eventually, we will want to track plugins.
@ -759,10 +745,10 @@ pub fn assign_node_ids(sess: &Session, krate: ast::Crate) -> ast::Crate {
/// miscellaneous analysis passes on the crate. Return various
/// structures carrying the results of the analysis.
pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
cstore: &CStore,
hir_map: hir_map::Map<'tcx>,
arenas: &'tcx ty::CtxtArenas<'tcx>,
name: &str,
make_glob_map: resolve::MakeGlobMap,
f: F)
-> Result<R, usize>
where F: FnOnce(&TyCtxt<'tcx>, Option<MirMap<'tcx>>, ty::CrateAnalysis, CompileResult) -> R
@ -787,6 +773,16 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
})
})?;
let resolve::CrateMap {
def_map,
freevars,
export_map,
trait_map,
glob_map,
} = time(sess.time_passes(),
"name resolution",
|| resolve::resolve_crate(sess, &hir_map, make_glob_map));
let mut analysis = ty::CrateAnalysis {
export_map: export_map,
access_levels: AccessLevels::default(),

View file

@ -179,7 +179,6 @@ impl PpSourceMode {
}
fn call_with_pp_support_hir<'tcx, A, B, F>(&self,
sess: &'tcx Session,
cstore: &CStore,
ast_map: &hir_map::Map<'tcx>,
arenas: &'tcx ty::CtxtArenas<'tcx>,
id: &str,
@ -206,7 +205,6 @@ impl PpSourceMode {
}
PpmTyped => {
abort_on_err(driver::phase_3_run_analysis_passes(sess,
cstore,
ast_map.clone(),
arenas,
id,
@ -737,9 +735,9 @@ pub fn pretty_print_input(sess: Session,
let dep_graph = DepGraph::new(false);
let _ignore = dep_graph.in_ignore();
let ast_map = if compute_ast_map {
let defs = hir_map::collect_definitions(&krate);
hir_forest = hir_map::Forest::new(lower_crate(&lcx, &krate), dep_graph.clone());
let defs = hir_map::collect_defs(hir_forest);
let map = hir_map::map_crate(hir_forest, defs);
let map = hir_map::map_crate(&mut hir_forest, defs);
Some(map)
} else {
None
@ -778,7 +776,6 @@ pub fn pretty_print_input(sess: Session,
(PpmHir(s), None) => {
let out: &mut Write = &mut out;
s.call_with_pp_support_hir(&sess,
cstore,
&ast_map.unwrap(),
&arenas,
&id,
@ -800,7 +797,6 @@ pub fn pretty_print_input(sess: Session,
(PpmHir(s), Some(uii)) => {
let out: &mut Write = &mut out;
s.call_with_pp_support_hir(&sess,
cstore,
&ast_map.unwrap(),
&arenas,
&id,
@ -841,7 +837,6 @@ pub fn pretty_print_input(sess: Session,
None
};
abort_on_err(driver::phase_3_run_analysis_passes(&sess,
&cstore,
ast_map,
&arenas,
&id,
@ -888,7 +883,6 @@ pub fn pretty_print_input(sess: Session,
Some(code) => {
let variants = gather_flowgraph_variants(&sess);
abort_on_err(driver::phase_3_run_analysis_passes(&sess,
&cstore,
ast_map,
&arenas,
&id,

View file

@ -18,7 +18,7 @@ use decoder;
use loader::{self, CratePaths};
use rustc::hir::svh::Svh;
use rustc::dep_graph::DepNode;
use rustc::dep_graph::{DepGraph, DepNode};
use rustc::session::{config, Session};
use rustc::session::search_paths::PathKind;
use rustc::middle::cstore::{CrateStore, validate_crate_name, ExternCrate};
@ -37,15 +37,15 @@ use syntax::parse;
use syntax::attr;
use syntax::attr::AttrMetaMethods;
use syntax::parse::token::InternedString;
use rustc::hir::intravisit::Visitor;
use rustc::hir;
use syntax::visit;
use log;
pub struct LocalCrateReader<'a, 'b:'a> {
pub struct LocalCrateReader<'a> {
sess: &'a Session,
cstore: &'a CStore,
creader: CrateReader<'a>,
ast_map: &'a hir_map::Map<'b>,
krate: &'a ast::Crate,
defintions: &'a hir_map::Definitions,
}
pub struct CrateReader<'a> {
@ -56,8 +56,8 @@ pub struct CrateReader<'a> {
local_crate_name: String,
}
impl<'a, 'b, 'hir> Visitor<'hir> for LocalCrateReader<'a, 'b> {
fn visit_item(&mut self, a: &'hir hir::Item) {
impl<'a, 'ast> visit::Visitor<'ast> for LocalCrateReader<'a> {
fn visit_item(&mut self, a: &'ast ast::Item) {
self.process_item(a);
}
}
@ -80,10 +80,6 @@ fn dump_crates(cstore: &CStore) {
fn should_link(i: &ast::Item) -> bool {
!attr::contains_name(&i.attrs, "no_link")
}
// Dup for the hir
fn should_link_hir(i: &hir::Item) -> bool {
!attr::contains_name(&i.attrs, "no_link")
}
struct CrateInfo {
ident: String,
@ -181,31 +177,6 @@ impl<'a> CrateReader<'a> {
}
}
// Dup of the above, but for the hir
fn extract_crate_info_hir(&self, i: &hir::Item) -> Option<CrateInfo> {
match i.node {
hir::ItemExternCrate(ref path_opt) => {
debug!("resolving extern crate stmt. ident: {} path_opt: {:?}",
i.name, path_opt);
let name = match *path_opt {
Some(name) => {
validate_crate_name(Some(self.sess), &name.as_str(),
Some(i.span));
name.to_string()
}
None => i.name.to_string(),
};
Some(CrateInfo {
ident: i.name.to_string(),
name: name,
id: i.id,
should_link: should_link_hir(i),
})
}
_ => None
}
}
fn existing_match(&self, name: &str, hash: Option<&Svh>, kind: PathKind)
-> Option<ast::CrateNum> {
let mut ret = None;
@ -776,29 +747,30 @@ impl<'a> CrateReader<'a> {
}
}
impl<'a, 'b> LocalCrateReader<'a, 'b> {
impl<'a> LocalCrateReader<'a> {
pub fn new(sess: &'a Session,
cstore: &'a CStore,
map: &'a hir_map::Map<'b>,
defs: &'a hir_map::Definitions,
krate: &'a ast::Crate,
local_crate_name: &str)
-> LocalCrateReader<'a, 'b> {
-> LocalCrateReader<'a> {
LocalCrateReader {
sess: sess,
cstore: cstore,
creader: CrateReader::new(sess, cstore, local_crate_name),
ast_map: map,
krate: krate,
defintions: defs,
}
}
// Traverses an AST, reading all the information about use'd crates and
// extern libraries necessary for later resolving, typechecking, linking,
// etc.
pub fn read_crates(&mut self) {
let _task = self.ast_map.dep_graph.in_task(DepNode::CrateReader);
let krate = self.ast_map.krate();
pub fn read_crates(&mut self, dep_graph: &DepGraph) {
let _task = dep_graph.in_task(DepNode::CrateReader);
self.process_crate(krate);
krate.visit_all_items(self);
self.process_crate(self.krate);
visit::walk_crate(self, self.krate);
self.creader.inject_allocator_crate();
if log_enabled!(log::INFO) {
@ -811,7 +783,7 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> {
self.creader.register_statically_included_foreign_items();
}
fn process_crate(&self, c: &hir::Crate) {
fn process_crate(&self, c: &ast::Crate) {
for a in c.attrs.iter().filter(|m| m.name() == "link_args") {
if let Some(ref linkarg) = a.value_str() {
self.cstore.add_used_link_args(&linkarg);
@ -819,14 +791,14 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> {
}
}
fn process_item(&mut self, i: &hir::Item) {
fn process_item(&mut self, i: &ast::Item) {
match i.node {
hir::ItemExternCrate(_) => {
if !should_link_hir(i) {
ast::ItemKind::ExternCrate(_) => {
if !should_link(i) {
return;
}
match self.creader.extract_crate_info_hir(i) {
match self.creader.extract_crate_info(i) {
Some(info) => {
let (cnum, _, _) = self.creader.resolve_crate(&None,
&info.ident,
@ -835,9 +807,9 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> {
i.span,
PathKind::Crate,
true);
let def_id = self.ast_map.local_def_id(i.id);
let def_id = self.defintions.opt_local_def_id(i.id).unwrap();
let len = self.ast_map.def_path(def_id).data.len();
let len = self.defintions.def_path(def_id.index).data.len();
self.creader.update_extern_crate(cnum,
ExternCrate {
@ -851,12 +823,12 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> {
None => ()
}
}
hir::ItemForeignMod(ref fm) => self.process_foreign_mod(i, fm),
ast::ItemKind::ForeignMod(ref fm) => self.process_foreign_mod(i, fm),
_ => { }
}
}
fn process_foreign_mod(&mut self, i: &hir::Item, fm: &hir::ForeignMod) {
fn process_foreign_mod(&mut self, i: &ast::Item, fm: &ast::ForeignMod) {
if fm.abi == Abi::Rust || fm.abi == Abi::RustIntrinsic || fm.abi == Abi::PlatformIntrinsic {
return;
}