about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/middle/entry.rs81
-rw-r--r--src/libsyntax/entry.rs42
-rw-r--r--src/libsyntax/lib.rs1
3 files changed, 79 insertions, 45 deletions
diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs
index c6e5b654f9a..8cdd4f7fe74 100644
--- a/src/librustc/middle/entry.rs
+++ b/src/librustc/middle/entry.rs
@@ -11,20 +11,19 @@
 
 use ast_map;
 use session::{config, Session};
-use syntax::ast::{Name, NodeId, Item, ItemFn};
+use syntax;
+use syntax::ast::{NodeId, Item};
 use syntax::attr;
 use syntax::codemap::Span;
-use syntax::parse::token;
+use syntax::entry::EntryPointType;
 use syntax::visit;
 use syntax::visit::Visitor;
 
-struct EntryContext<'a, 'ast: 'a> {
+struct EntryContext<'a> {
     session: &'a Session,
 
-    ast_map: &'a ast_map::Map<'ast>,
-
-    // The interned Name for "main".
-    main_name: Name,
+    // The current depth in the ast
+    depth: usize,
 
     // The top-level function called 'main'
     main_fn: Option<(NodeId, Span)>,
@@ -40,9 +39,11 @@ struct EntryContext<'a, 'ast: 'a> {
     non_main_fns: Vec<(NodeId, Span)> ,
 }
 
-impl<'a, 'ast, 'v> Visitor<'v> for EntryContext<'a, 'ast> {
+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;
     }
 }
 
@@ -63,8 +64,7 @@ pub fn find_entry_point(session: &Session, ast_map: &ast_map::Map) {
 
     let mut ctxt = EntryContext {
         session: session,
-        main_name: token::intern("main"),
-        ast_map: ast_map,
+        depth: 0,
         main_fn: None,
         attr_main_fn: None,
         start_fn: None,
@@ -77,44 +77,35 @@ pub fn find_entry_point(session: &Session, ast_map: &ast_map::Map) {
 }
 
 fn find_item(item: &Item, ctxt: &mut EntryContext) {
-    match item.node {
-        ItemFn(..) => {
-            if item.ident.name == ctxt.main_name {
-                 ctxt.ast_map.with_path(item.id, |path| {
-                        if path.count() == 1 {
-                            // This is a top-level function so can be 'main'
-                            if ctxt.main_fn.is_none() {
-                                ctxt.main_fn = Some((item.id, item.span));
-                            } else {
-                                span_err!(ctxt.session, item.span, E0136,
-                                          "multiple 'main' functions");
-                            }
-                        } else {
-                            // This isn't main
-                            ctxt.non_main_fns.push((item.id, item.span));
-                        }
-                });
+    match syntax::entry::entry_point_type(item, ctxt.depth) {
+        EntryPointType::MainNamed => {
+            if ctxt.main_fn.is_none() {
+                ctxt.main_fn = Some((item.id, item.span));
+            } else {
+                span_err!(ctxt.session, item.span, E0136,
+                          "multiple 'main' functions");
             }
-
-            if attr::contains_name(&item.attrs, "main") {
-                if ctxt.attr_main_fn.is_none() {
-                    ctxt.attr_main_fn = Some((item.id, item.span));
-                } else {
-                    span_err!(ctxt.session, item.span, E0137,
-                              "multiple functions with a #[main] attribute");
-                }
+        },
+        EntryPointType::OtherMain => {
+            ctxt.non_main_fns.push((item.id, item.span));
+        },
+        EntryPointType::MainAttr => {
+            if ctxt.attr_main_fn.is_none() {
+                ctxt.attr_main_fn = Some((item.id, item.span));
+            } else {
+                span_err!(ctxt.session, item.span, E0137,
+                          "multiple functions with a #[main] attribute");
             }
-
-            if attr::contains_name(&item.attrs, "start") {
-                if ctxt.start_fn.is_none() {
-                    ctxt.start_fn = Some((item.id, item.span));
-                } else {
-                    span_err!(ctxt.session, item.span, E0138,
-                              "multiple 'start' functions");
-                }
+        },
+        EntryPointType::Start => {
+            if ctxt.start_fn.is_none() {
+                ctxt.start_fn = Some((item.id, item.span));
+            } else {
+                span_err!(ctxt.session, item.span, E0138,
+                          "multiple 'start' functions");
             }
-        }
-        _ => ()
+        },
+        EntryPointType::None => ()
     }
 
     visit::walk_item(ctxt, item);
diff --git a/src/libsyntax/entry.rs b/src/libsyntax/entry.rs
new file mode 100644
index 00000000000..b6c5d0066a2
--- /dev/null
+++ b/src/libsyntax/entry.rs
@@ -0,0 +1,42 @@
+// Copyright 2012-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 attr;
+use ast::{Item, ItemFn};
+
+pub enum EntryPointType {
+    None,
+    MainNamed,
+    MainAttr,
+    Start,
+    OtherMain, // Not an entry point, but some other function named main
+}
+
+pub fn entry_point_type(item: &Item, depth: usize) -> 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.ident.name == "main" {
+                if depth == 1 {
+                    // This is a top-level function so can be 'main'
+                    EntryPointType::MainNamed
+                } else {
+                    EntryPointType::OtherMain
+                }
+            } else {
+                EntryPointType::None
+            }
+        }
+        _ => EntryPointType::None,
+    }
+}
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 0d1fa6dd726..d1c862ad40b 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -90,6 +90,7 @@ pub mod attr;
 pub mod codemap;
 pub mod config;
 pub mod diagnostic;
+pub mod entry;
 pub mod feature_gate;
 pub mod fold;
 pub mod owned_slice;