aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser/src/grammar/items.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_parser/src/grammar/items.rs')
-rw-r--r--crates/ra_parser/src/grammar/items.rs93
1 files changed, 40 insertions, 53 deletions
diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs
index 94b93a02b..c24e6d1e0 100644
--- a/crates/ra_parser/src/grammar/items.rs
+++ b/crates/ra_parser/src/grammar/items.rs
@@ -67,11 +67,14 @@ pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool, flavor: ItemF
67} 67}
68 68
69pub(super) fn maybe_item(p: &mut Parser, m: Marker, flavor: ItemFlavor) -> Result<(), Marker> { 69pub(super) fn maybe_item(p: &mut Parser, m: Marker, flavor: ItemFlavor) -> Result<(), Marker> {
70 opt_visibility(p); 70 // test_err pub_expr
71 if let Some(kind) = items_without_modifiers(p) { 71 // fn foo() { pub 92; }
72 m.complete(p, kind); 72 let has_visibility = opt_visibility(p);
73 return Ok(()); 73
74 } 74 let m = match items_without_modifiers(p, m) {
75 Ok(()) => return Ok(()),
76 Err(m) => m,
77 };
75 78
76 let mut has_mods = false; 79 let mut has_mods = false;
77 80
@@ -152,10 +155,14 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker, flavor: ItemFlavor) -> Resul
152 m.complete(p, IMPL_BLOCK); 155 m.complete(p, IMPL_BLOCK);
153 } 156 }
154 _ => { 157 _ => {
155 if !has_mods { 158 if !has_visibility && !has_mods {
156 return Err(m); 159 return Err(m);
157 } else { 160 } else {
158 p.error("expected fn, trait or impl"); 161 if has_mods {
162 p.error("expected fn, trait or impl");
163 } else {
164 p.error("expected an item");
165 }
159 m.complete(p, ERROR); 166 m.complete(p, ERROR);
160 } 167 }
161 } 168 }
@@ -163,23 +170,14 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker, flavor: ItemFlavor) -> Resul
163 Ok(()) 170 Ok(())
164} 171}
165 172
166fn items_without_modifiers(p: &mut Parser) -> Option<SyntaxKind> { 173fn items_without_modifiers(p: &mut Parser, m: Marker) -> Result<(), Marker> {
167 let la = p.nth(1); 174 let la = p.nth(1);
168 let kind = match p.current() { 175 match p.current() {
169 // test extern_crate 176 // test extern_crate
170 // extern crate foo; 177 // extern crate foo;
171 EXTERN_KW if la == CRATE_KW => { 178 EXTERN_KW if la == CRATE_KW => extern_crate_item(p, m),
172 extern_crate_item(p); 179 TYPE_KW => type_def(p, m),
173 EXTERN_CRATE_ITEM 180 MOD_KW => mod_item(p, m),
174 }
175 TYPE_KW => {
176 type_def(p);
177 TYPE_ALIAS_DEF
178 }
179 MOD_KW => {
180 mod_item(p);
181 MODULE
182 }
183 STRUCT_KW => { 181 STRUCT_KW => {
184 // test struct_items 182 // test struct_items
185 // struct Foo; 183 // struct Foo;
@@ -190,14 +188,7 @@ fn items_without_modifiers(p: &mut Parser) -> Option<SyntaxKind> {
190 // a: i32, 188 // a: i32,
191 // b: f32, 189 // b: f32,
192 // } 190 // }
193 nominal::struct_def(p, STRUCT_KW); 191 nominal::struct_def(p, m, STRUCT_KW);
194 if p.at(SEMI) {
195 p.err_and_bump(
196 "expected item, found `;`\n\
197 consider removing this semicolon",
198 );
199 }
200 STRUCT_DEF
201 } 192 }
202 IDENT if p.at_contextual_kw("union") && p.nth(1) == IDENT => { 193 IDENT if p.at_contextual_kw("union") && p.nth(1) == IDENT => {
203 // test union_items 194 // test union_items
@@ -206,25 +197,12 @@ fn items_without_modifiers(p: &mut Parser) -> Option<SyntaxKind> {
206 // a: i32, 197 // a: i32,
207 // b: f32, 198 // b: f32,
208 // } 199 // }
209 nominal::struct_def(p, UNION_KW); 200 nominal::struct_def(p, m, UNION_KW);
210 STRUCT_DEF
211 }
212 ENUM_KW => {
213 nominal::enum_def(p);
214 ENUM_DEF
215 }
216 USE_KW => {
217 use_item::use_item(p);
218 USE_ITEM
219 }
220 CONST_KW if (la == IDENT || la == MUT_KW) => {
221 consts::const_def(p);
222 CONST_DEF
223 }
224 STATIC_KW => {
225 consts::static_def(p);
226 STATIC_DEF
227 } 201 }
202 ENUM_KW => nominal::enum_def(p, m),
203 USE_KW => use_item::use_item(p, m),
204 CONST_KW if (la == IDENT || la == MUT_KW) => consts::const_def(p, m),
205 STATIC_KW => consts::static_def(p, m),
228 // test extern_block 206 // test extern_block
229 // extern {} 207 // extern {}
230 EXTERN_KW 208 EXTERN_KW
@@ -232,14 +210,20 @@ fn items_without_modifiers(p: &mut Parser) -> Option<SyntaxKind> {
232 { 210 {
233 abi(p); 211 abi(p);
234 extern_item_list(p); 212 extern_item_list(p);
235 EXTERN_BLOCK 213 m.complete(p, EXTERN_BLOCK);
236 } 214 }
237 _ => return None, 215 _ => return Err(m),
238 }; 216 };
239 Some(kind) 217 if p.at(SEMI) {
218 p.err_and_bump(
219 "expected item, found `;`\n\
220 consider removing this semicolon",
221 );
222 }
223 Ok(())
240} 224}
241 225
242fn extern_crate_item(p: &mut Parser) { 226fn extern_crate_item(p: &mut Parser, m: Marker) {
243 assert!(p.at(EXTERN_KW)); 227 assert!(p.at(EXTERN_KW));
244 p.bump(); 228 p.bump();
245 assert!(p.at(CRATE_KW)); 229 assert!(p.at(CRATE_KW));
@@ -247,6 +231,7 @@ fn extern_crate_item(p: &mut Parser) {
247 name_ref(p); 231 name_ref(p);
248 opt_alias(p); 232 opt_alias(p);
249 p.expect(SEMI); 233 p.expect(SEMI);
234 m.complete(p, EXTERN_CRATE_ITEM);
250} 235}
251 236
252pub(crate) fn extern_item_list(p: &mut Parser) { 237pub(crate) fn extern_item_list(p: &mut Parser) {
@@ -295,7 +280,7 @@ fn fn_def(p: &mut Parser, flavor: ItemFlavor) {
295 280
296// test type_item 281// test type_item
297// type Foo = Bar; 282// type Foo = Bar;
298fn type_def(p: &mut Parser) { 283fn type_def(p: &mut Parser, m: Marker) {
299 assert!(p.at(TYPE_KW)); 284 assert!(p.at(TYPE_KW));
300 p.bump(); 285 p.bump();
301 286
@@ -317,9 +302,10 @@ fn type_def(p: &mut Parser) {
317 types::type_(p); 302 types::type_(p);
318 } 303 }
319 p.expect(SEMI); 304 p.expect(SEMI);
305 m.complete(p, TYPE_ALIAS_DEF);
320} 306}
321 307
322pub(crate) fn mod_item(p: &mut Parser) { 308pub(crate) fn mod_item(p: &mut Parser, m: Marker) {
323 assert!(p.at(MOD_KW)); 309 assert!(p.at(MOD_KW));
324 p.bump(); 310 p.bump();
325 311
@@ -329,6 +315,7 @@ pub(crate) fn mod_item(p: &mut Parser) {
329 } else if !p.eat(SEMI) { 315 } else if !p.eat(SEMI) {
330 p.error("expected `;` or `{`"); 316 p.error("expected `;` or `{`");
331 } 317 }
318 m.complete(p, MODULE);
332} 319}
333 320
334pub(crate) fn mod_item_list(p: &mut Parser) { 321pub(crate) fn mod_item_list(p: &mut Parser) {