// except according to those terms.
-use ast_map;
+use front::map as ast_map;
+use middle::def_id::{CRATE_DEF_INDEX};
use session::{config, Session};
-use syntax;
-use syntax::ast::{NodeId, Item};
+use syntax::ast::NodeId;
use syntax::attr;
use syntax::codemap::Span;
use syntax::entry::EntryPointType;
-use syntax::visit;
-use syntax::visit::Visitor;
+use rustc_front::hir::{Item, ItemFn};
+use rustc_front::intravisit::Visitor;
-struct EntryContext<'a> {
+struct EntryContext<'a, 'tcx: 'a> {
session: &'a Session,
- // The current depth in the ast
- depth: usize,
+ map: &'a ast_map::Map<'tcx>,
// The top-level function called 'main'
main_fn: Option<(NodeId, Span)>,
non_main_fns: Vec<(NodeId, Span)> ,
}
-impl<'a, 'v> Visitor<'v> for EntryContext<'a> {
- fn visit_item(&mut self, item: &Item) {
- self.depth += 1;
- find_item(item, self);
- self.depth -= 1;
+impl<'a, 'tcx> Visitor<'tcx> for EntryContext<'a, 'tcx> {
+ fn visit_item(&mut self, item: &'tcx Item) {
+ let def_id = self.map.local_def_id(item.id);
+ let def_key = self.map.def_key(def_id);
+ let at_root = def_key.parent == Some(CRATE_DEF_INDEX);
+ find_item(item, self, at_root);
}
}
let mut ctxt = EntryContext {
session: session,
- depth: 0,
+ map: ast_map,
main_fn: None,
attr_main_fn: None,
start_fn: None,
non_main_fns: Vec::new(),
};
- visit::walk_crate(&mut ctxt, ast_map.krate());
+ ast_map.krate().visit_all_items(&mut ctxt);
configure_main(&mut ctxt);
}
-fn find_item(item: &Item, ctxt: &mut EntryContext) {
- match syntax::entry::entry_point_type(item, ctxt.depth) {
+// Beware, this is duplicated in libsyntax/entry.rs, make sure to keep
+// them in sync.
+fn entry_point_type(item: &Item, at_root: bool) -> EntryPointType {
+ match item.node {
+ ItemFn(..) => {
+ if attr::contains_name(&item.attrs, "start") {
+ EntryPointType::Start
+ } else if attr::contains_name(&item.attrs, "main") {
+ EntryPointType::MainAttr
+ } else if item.name.as_str() == "main" {
+ if at_root {
+ // This is a top-level function so can be 'main'
+ EntryPointType::MainNamed
+ } else {
+ EntryPointType::OtherMain
+ }
+ } else {
+ EntryPointType::None
+ }
+ }
+ _ => EntryPointType::None,
+ }
+}
+
+
+fn find_item(item: &Item, ctxt: &mut EntryContext, at_root: bool) {
+ match entry_point_type(item, at_root) {
EntryPointType::MainNamed => {
if ctxt.main_fn.is_none() {
ctxt.main_fn = Some((item.id, item.span));
},
EntryPointType::None => ()
}
-
- visit::walk_item(ctxt, item);
}
fn configure_main(this: &mut EntryContext) {