1
+ use iter_extended:: vecmap;
2
+
1
3
use crate :: {
2
4
parser:: { labels:: ParsingRuleLabel , Item , ItemKind } ,
3
5
token:: { Keyword , Token } ,
@@ -13,31 +15,32 @@ impl<'a> Parser<'a> {
13
15
}
14
16
15
17
pub ( crate ) fn parse_module_items ( & mut self , nested : bool ) -> Vec < Item > {
16
- self . parse_many ( "items" , without_separator ( ) , |parser| {
18
+ self . parse_many_to_many ( "items" , without_separator ( ) , |parser| {
17
19
parser. parse_module_item_in_list ( nested)
18
20
} )
19
21
}
20
22
21
- fn parse_module_item_in_list ( & mut self , nested : bool ) -> Option < Item > {
23
+ fn parse_module_item_in_list ( & mut self , nested : bool ) -> Vec < Item > {
22
24
loop {
23
25
// We only break out of the loop on `}` if we are inside a `mod { ..`
24
26
if nested && self . at ( Token :: RightBrace ) {
25
- return None ;
27
+ return vec ! [ ] ;
26
28
}
27
29
28
30
// We always break on EOF (we don't error because if we are inside `mod { ..`
29
31
// the outer parsing logic will error instead)
30
32
if self . at_eof ( ) {
31
- return None ;
33
+ return vec ! [ ] ;
32
34
}
33
35
34
- let Some ( item) = self . parse_item ( ) else {
36
+ let parsed_items = self . parse_item ( ) ;
37
+ if parsed_items. is_empty ( ) {
35
38
// If we couldn't parse an item we check which token we got
36
39
match self . token . token ( ) {
37
40
Token :: RightBrace if nested => {
38
- return None ;
41
+ return vec ! [ ] ;
39
42
}
40
- Token :: EOF => return None ,
43
+ Token :: EOF => return vec ! [ ] ,
41
44
_ => ( ) ,
42
45
}
43
46
@@ -47,7 +50,7 @@ impl<'a> Parser<'a> {
47
50
continue ;
48
51
} ;
49
52
50
- return Some ( item ) ;
53
+ return parsed_items ;
51
54
}
52
55
}
53
56
@@ -85,15 +88,19 @@ impl<'a> Parser<'a> {
85
88
}
86
89
87
90
/// Item = OuterDocComments ItemKind
88
- fn parse_item ( & mut self ) -> Option < Item > {
91
+ fn parse_item ( & mut self ) -> Vec < Item > {
89
92
let start_span = self . current_token_span ;
90
93
let doc_comments = self . parse_outer_doc_comments ( ) ;
91
- let kind = self . parse_item_kind ( ) ? ;
94
+ let kinds = self . parse_item_kind ( ) ;
92
95
let span = self . span_since ( start_span) ;
93
96
94
- Some ( Item { kind, span, doc_comments } )
97
+ vecmap ( kinds , |kind| Item { kind, span, doc_comments : doc_comments . clone ( ) } )
95
98
}
96
99
100
+ /// This method returns one 'ItemKind' in the majority of cases.
101
+ /// The current exception is when parsing a trait alias,
102
+ /// which returns both the trait and the impl.
103
+ ///
97
104
/// ItemKind
98
105
/// = InnerAttribute
99
106
/// | Attributes Modifiers
@@ -106,9 +113,9 @@ impl<'a> Parser<'a> {
106
113
/// | TypeAlias
107
114
/// | Function
108
115
/// )
109
- fn parse_item_kind ( & mut self ) -> Option < ItemKind > {
116
+ fn parse_item_kind ( & mut self ) -> Vec < ItemKind > {
110
117
if let Some ( kind) = self . parse_inner_attribute ( ) {
111
- return Some ( ItemKind :: InnerAttribute ( kind) ) ;
118
+ return vec ! [ ItemKind :: InnerAttribute ( kind) ] ;
112
119
}
113
120
114
121
let start_span = self . current_token_span ;
@@ -122,78 +129,81 @@ impl<'a> Parser<'a> {
122
129
self . comptime_mutable_and_unconstrained_not_applicable ( modifiers) ;
123
130
124
131
let use_tree = self . parse_use_tree ( ) ;
125
- return Some ( ItemKind :: Import ( use_tree, modifiers. visibility ) ) ;
132
+ return vec ! [ ItemKind :: Import ( use_tree, modifiers. visibility) ] ;
126
133
}
127
134
128
135
if let Some ( is_contract) = self . eat_mod_or_contract ( ) {
129
136
self . comptime_mutable_and_unconstrained_not_applicable ( modifiers) ;
130
137
131
- return Some ( self . parse_mod_or_contract ( attributes, is_contract, modifiers. visibility ) ) ;
138
+ return vec ! [ self . parse_mod_or_contract( attributes, is_contract, modifiers. visibility) ] ;
132
139
}
133
140
134
141
if self . eat_keyword ( Keyword :: Struct ) {
135
142
self . comptime_mutable_and_unconstrained_not_applicable ( modifiers) ;
136
143
137
- return Some ( ItemKind :: Struct ( self . parse_struct (
144
+ return vec ! [ ItemKind :: Struct ( self . parse_struct(
138
145
attributes,
139
146
modifiers. visibility,
140
147
start_span,
141
- ) ) ) ;
148
+ ) ) ] ;
142
149
}
143
150
144
151
if self . eat_keyword ( Keyword :: Impl ) {
145
152
self . comptime_mutable_and_unconstrained_not_applicable ( modifiers) ;
146
153
147
- return Some ( match self . parse_impl ( ) {
154
+ return vec ! [ match self . parse_impl( ) {
148
155
Impl :: Impl ( type_impl) => ItemKind :: Impl ( type_impl) ,
149
156
Impl :: TraitImpl ( noir_trait_impl) => ItemKind :: TraitImpl ( noir_trait_impl) ,
150
- } ) ;
157
+ } ] ;
151
158
}
152
159
153
160
if self . eat_keyword ( Keyword :: Trait ) {
154
161
self . comptime_mutable_and_unconstrained_not_applicable ( modifiers) ;
155
162
156
- return Some ( ItemKind :: Trait ( self . parse_trait (
157
- attributes,
158
- modifiers. visibility ,
159
- start_span,
160
- ) ) ) ;
163
+ let ( noir_trait, noir_impl) =
164
+ self . parse_trait ( attributes, modifiers. visibility , start_span) ;
165
+ let mut output = vec ! [ ItemKind :: Trait ( noir_trait) ] ;
166
+ if let Some ( noir_impl) = noir_impl {
167
+ output. push ( ItemKind :: TraitImpl ( noir_impl) ) ;
168
+ }
169
+
170
+ return output;
161
171
}
162
172
163
173
if self . eat_keyword ( Keyword :: Global ) {
164
174
self . unconstrained_not_applicable ( modifiers) ;
165
175
166
- return Some ( ItemKind :: Global (
176
+ return vec ! [ ItemKind :: Global (
167
177
self . parse_global(
168
178
attributes,
169
179
modifiers. comptime. is_some( ) ,
170
180
modifiers. mutable. is_some( ) ,
171
181
) ,
172
182
modifiers. visibility,
173
- ) ) ;
183
+ ) ] ;
174
184
}
175
185
176
186
if self . eat_keyword ( Keyword :: Type ) {
177
187
self . comptime_mutable_and_unconstrained_not_applicable ( modifiers) ;
178
188
179
- return Some ( ItemKind :: TypeAlias (
189
+ return vec ! [ ItemKind :: TypeAlias (
180
190
self . parse_type_alias( modifiers. visibility, start_span) ,
181
- ) ) ;
191
+ ) ] ;
182
192
}
183
193
184
194
if self . eat_keyword ( Keyword :: Fn ) {
185
195
self . mutable_not_applicable ( modifiers) ;
186
196
187
- return Some ( ItemKind :: Function ( self . parse_function (
197
+ return vec ! [ ItemKind :: Function ( self . parse_function(
188
198
attributes,
189
199
modifiers. visibility,
190
200
modifiers. comptime. is_some( ) ,
191
201
modifiers. unconstrained. is_some( ) ,
192
202
false , // allow_self
193
- ) ) ) ;
203
+ ) ) ] ;
194
204
}
195
205
196
- None
206
+ vec ! [ ]
197
207
}
198
208
199
209
fn eat_mod_or_contract ( & mut self ) -> Option < bool > {
0 commit comments