11
11
12
12
use ast_map;
13
13
use session:: { config, Session } ;
14
- use syntax:: ast:: { Name , NodeId , Item , ItemFn } ;
14
+ use syntax;
15
+ use syntax:: ast:: { NodeId , Item } ;
15
16
use syntax:: attr;
16
17
use syntax:: codemap:: Span ;
17
- use syntax:: parse :: token ;
18
+ use syntax:: entry :: EntryPointType ;
18
19
use syntax:: visit;
19
20
use syntax:: visit:: Visitor ;
20
21
21
- struct EntryContext < ' a , ' ast : ' a > {
22
+ struct EntryContext < ' a > {
22
23
session : & ' a Session ,
23
24
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 ,
28
27
29
28
// The top-level function called 'main'
30
29
main_fn : Option < ( NodeId , Span ) > ,
@@ -40,9 +39,11 @@ struct EntryContext<'a, 'ast: 'a> {
40
39
non_main_fns : Vec < ( NodeId , Span ) > ,
41
40
}
42
41
43
- impl < ' a , ' ast , ' v > Visitor < ' v > for EntryContext < ' a , ' ast > {
42
+ impl < ' a , ' v > Visitor < ' v > for EntryContext < ' a > {
44
43
fn visit_item ( & mut self , item : & Item ) {
44
+ self . depth += 1 ;
45
45
find_item ( item, self ) ;
46
+ self . depth -= 1 ;
46
47
}
47
48
}
48
49
@@ -63,8 +64,7 @@ pub fn find_entry_point(session: &Session, ast_map: &ast_map::Map) {
63
64
64
65
let mut ctxt = EntryContext {
65
66
session : session,
66
- main_name : token:: intern ( "main" ) ,
67
- ast_map : ast_map,
67
+ depth : 0 ,
68
68
main_fn : None ,
69
69
attr_main_fn : None ,
70
70
start_fn : None ,
@@ -77,44 +77,35 @@ pub fn find_entry_point(session: &Session, ast_map: &ast_map::Map) {
77
77
}
78
78
79
79
fn 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" ) ;
97
87
}
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" ) ;
106
98
}
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" ) ;
115
106
}
116
- }
117
- _ => ( )
107
+ } ,
108
+ EntryPointType :: None => ( )
118
109
}
119
110
120
111
visit:: walk_item ( ctxt, item) ;
0 commit comments