1111
1212use ast_map;
1313use session:: { config, Session } ;
14- use syntax:: ast:: { Name , NodeId , Item , ItemFn } ;
14+ use syntax;
15+ use syntax:: ast:: { NodeId , Item } ;
1516use syntax:: attr;
1617use syntax:: codemap:: Span ;
17- use syntax:: parse :: token ;
18+ use syntax:: entry :: EntryPointType ;
1819use syntax:: visit;
1920use syntax:: visit:: Visitor ;
2021
21- struct EntryContext < ' a , ' ast : ' a > {
22+ struct EntryContext < ' a > {
2223 session : & ' a Session ,
2324
24- ast_map : & ' a ast_map:: Map < ' ast > ,
25-
26- // The interned Name for "main".
27- main_name : Name ,
25+ // The current depth in the ast
26+ depth : usize ,
2827
2928 // The top-level function called 'main'
3029 main_fn : Option < ( NodeId , Span ) > ,
@@ -40,9 +39,11 @@ struct EntryContext<'a, 'ast: 'a> {
4039 non_main_fns : Vec < ( NodeId , Span ) > ,
4140}
4241
43- impl < ' a , ' ast , ' v > Visitor < ' v > for EntryContext < ' a , ' ast > {
42+ impl < ' a , ' v > Visitor < ' v > for EntryContext < ' a > {
4443 fn visit_item ( & mut self , item : & Item ) {
44+ self . depth += 1 ;
4545 find_item ( item, self ) ;
46+ self . depth -= 1 ;
4647 }
4748}
4849
@@ -63,8 +64,7 @@ pub fn find_entry_point(session: &Session, ast_map: &ast_map::Map) {
6364
6465 let mut ctxt = EntryContext {
6566 session : session,
66- main_name : token:: intern ( "main" ) ,
67- ast_map : ast_map,
67+ depth : 0 ,
6868 main_fn : None ,
6969 attr_main_fn : None ,
7070 start_fn : None ,
@@ -77,44 +77,35 @@ pub fn find_entry_point(session: &Session, ast_map: &ast_map::Map) {
7777}
7878
7979fn find_item ( item : & Item , ctxt : & mut EntryContext ) {
80- match item. node {
81- ItemFn ( ..) => {
82- if item. ident . name == ctxt. main_name {
83- ctxt. ast_map . with_path ( item. id , |path| {
84- if path. count ( ) == 1 {
85- // This is a top-level function so can be 'main'
86- if ctxt. main_fn . is_none ( ) {
87- ctxt. main_fn = Some ( ( item. id , item. span ) ) ;
88- } else {
89- span_err ! ( ctxt. session, item. span, E0136 ,
90- "multiple 'main' functions" ) ;
91- }
92- } else {
93- // This isn't main
94- ctxt. non_main_fns . push ( ( item. id , item. span ) ) ;
95- }
96- } ) ;
80+ match syntax:: entry:: entry_point_type ( item, ctxt. depth ) {
81+ EntryPointType :: MainNamed => {
82+ if ctxt. main_fn . is_none ( ) {
83+ ctxt. main_fn = Some ( ( item. id , item. span ) ) ;
84+ } else {
85+ span_err ! ( ctxt. session, item. span, E0136 ,
86+ "multiple 'main' functions" ) ;
9787 }
98-
99- if attr:: contains_name ( & item. attrs , "main" ) {
100- if ctxt. attr_main_fn . is_none ( ) {
101- ctxt. attr_main_fn = Some ( ( item. id , item. span ) ) ;
102- } else {
103- span_err ! ( ctxt. session, item. span, E0137 ,
104- "multiple functions with a #[main] attribute" ) ;
105- }
88+ } ,
89+ EntryPointType :: OtherMain => {
90+ ctxt. non_main_fns . push ( ( item. id , item. span ) ) ;
91+ } ,
92+ EntryPointType :: MainAttr => {
93+ if ctxt. attr_main_fn . is_none ( ) {
94+ ctxt. attr_main_fn = Some ( ( item. id , item. span ) ) ;
95+ } else {
96+ span_err ! ( ctxt. session, item. span, E0137 ,
97+ "multiple functions with a #[main] attribute" ) ;
10698 }
107-
108- if attr:: contains_name ( & item. attrs , "start" ) {
109- if ctxt. start_fn . is_none ( ) {
110- ctxt. start_fn = Some ( ( item. id , item. span ) ) ;
111- } else {
112- span_err ! ( ctxt. session, item. span, E0138 ,
113- "multiple 'start' functions" ) ;
114- }
99+ } ,
100+ EntryPointType :: Start => {
101+ if ctxt. start_fn . is_none ( ) {
102+ ctxt. start_fn = Some ( ( item. id , item. span ) ) ;
103+ } else {
104+ span_err ! ( ctxt. session, item. span, E0138 ,
105+ "multiple 'start' functions" ) ;
115106 }
116- }
117- _ => ( )
107+ } ,
108+ EntryPointType :: None => ( )
118109 }
119110
120111 visit:: walk_item ( ctxt, item) ;
0 commit comments