diff options
Diffstat (limited to 'crates/ra_parser/src/grammar')
-rw-r--r-- | crates/ra_parser/src/grammar/expressions.rs | 2 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/items.rs | 93 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/items/consts.rs | 11 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/items/nominal.rs | 11 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/items/use_item.rs | 3 |
5 files changed, 52 insertions, 68 deletions
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs index 6d3e379a3..d8e825f46 100644 --- a/crates/ra_parser/src/grammar/expressions.rs +++ b/crates/ra_parser/src/grammar/expressions.rs | |||
@@ -67,8 +67,6 @@ pub(crate) fn expr_block_contents(p: &mut Parser) { | |||
67 | Err(m) => m, | 67 | Err(m) => m, |
68 | }; | 68 | }; |
69 | 69 | ||
70 | // test pub_expr | ||
71 | // fn foo() { pub 92; } //FIXME | ||
72 | if has_attrs { | 70 | if has_attrs { |
73 | m.abandon(p); | 71 | m.abandon(p); |
74 | p.error("expected a let statement or an item after attributes in block"); | 72 | p.error("expected a let statement or an item after attributes in block"); |
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 | ||
69 | pub(super) fn maybe_item(p: &mut Parser, m: Marker, flavor: ItemFlavor) -> Result<(), Marker> { | 69 | pub(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 | ||
166 | fn items_without_modifiers(p: &mut Parser) -> Option<SyntaxKind> { | 173 | fn 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 | ||
242 | fn extern_crate_item(p: &mut Parser) { | 226 | fn 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 | ||
252 | pub(crate) fn extern_item_list(p: &mut Parser) { | 237 | pub(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; |
298 | fn type_def(p: &mut Parser) { | 283 | fn 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 | ||
322 | pub(crate) fn mod_item(p: &mut Parser) { | 308 | pub(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 | ||
334 | pub(crate) fn mod_item_list(p: &mut Parser) { | 321 | pub(crate) fn mod_item_list(p: &mut Parser) { |
diff --git a/crates/ra_parser/src/grammar/items/consts.rs b/crates/ra_parser/src/grammar/items/consts.rs index 5a5852f83..e6e6011c6 100644 --- a/crates/ra_parser/src/grammar/items/consts.rs +++ b/crates/ra_parser/src/grammar/items/consts.rs | |||
@@ -1,14 +1,14 @@ | |||
1 | use super::*; | 1 | use super::*; |
2 | 2 | ||
3 | pub(super) fn static_def(p: &mut Parser) { | 3 | pub(super) fn static_def(p: &mut Parser, m: Marker) { |
4 | const_or_static(p, STATIC_KW) | 4 | const_or_static(p, m, STATIC_KW, STATIC_DEF) |
5 | } | 5 | } |
6 | 6 | ||
7 | pub(super) fn const_def(p: &mut Parser) { | 7 | pub(super) fn const_def(p: &mut Parser, m: Marker) { |
8 | const_or_static(p, CONST_KW) | 8 | const_or_static(p, m, CONST_KW, CONST_DEF) |
9 | } | 9 | } |
10 | 10 | ||
11 | fn const_or_static(p: &mut Parser, kw: SyntaxKind) { | 11 | fn const_or_static(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) { |
12 | assert!(p.at(kw)); | 12 | assert!(p.at(kw)); |
13 | p.bump(); | 13 | p.bump(); |
14 | p.eat(MUT_KW); // TODO: validator to forbid const mut | 14 | p.eat(MUT_KW); // TODO: validator to forbid const mut |
@@ -18,4 +18,5 @@ fn const_or_static(p: &mut Parser, kw: SyntaxKind) { | |||
18 | expressions::expr(p); | 18 | expressions::expr(p); |
19 | } | 19 | } |
20 | p.expect(SEMI); | 20 | p.expect(SEMI); |
21 | m.complete(p, def); | ||
21 | } | 22 | } |
diff --git a/crates/ra_parser/src/grammar/items/nominal.rs b/crates/ra_parser/src/grammar/items/nominal.rs index ff9b38f9c..a3579eebd 100644 --- a/crates/ra_parser/src/grammar/items/nominal.rs +++ b/crates/ra_parser/src/grammar/items/nominal.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use super::*; | 1 | use super::*; |
2 | 2 | ||
3 | pub(super) fn struct_def(p: &mut Parser, kind: SyntaxKind) { | 3 | pub(super) fn struct_def(p: &mut Parser, m: Marker, kind: SyntaxKind) { |
4 | assert!(p.at(STRUCT_KW) || p.at_contextual_kw("union")); | 4 | assert!(p.at(STRUCT_KW) || p.at_contextual_kw("union")); |
5 | p.bump_remap(kind); | 5 | p.bump_remap(kind); |
6 | 6 | ||
@@ -12,19 +12,16 @@ pub(super) fn struct_def(p: &mut Parser, kind: SyntaxKind) { | |||
12 | match p.current() { | 12 | match p.current() { |
13 | SEMI => { | 13 | SEMI => { |
14 | p.bump(); | 14 | p.bump(); |
15 | return; | ||
16 | } | 15 | } |
17 | L_CURLY => named_field_def_list(p), | 16 | L_CURLY => named_field_def_list(p), |
18 | _ => { | 17 | _ => { |
19 | //TODO: special case `(` error message | 18 | //TODO: special case `(` error message |
20 | p.error("expected `;` or `{`"); | 19 | p.error("expected `;` or `{`"); |
21 | return; | ||
22 | } | 20 | } |
23 | } | 21 | } |
24 | } | 22 | } |
25 | SEMI if kind == STRUCT_KW => { | 23 | SEMI if kind == STRUCT_KW => { |
26 | p.bump(); | 24 | p.bump(); |
27 | return; | ||
28 | } | 25 | } |
29 | L_CURLY => named_field_def_list(p), | 26 | L_CURLY => named_field_def_list(p), |
30 | L_PAREN if kind == STRUCT_KW => { | 27 | L_PAREN if kind == STRUCT_KW => { |
@@ -37,16 +34,15 @@ pub(super) fn struct_def(p: &mut Parser, kind: SyntaxKind) { | |||
37 | } | 34 | } |
38 | _ if kind == STRUCT_KW => { | 35 | _ if kind == STRUCT_KW => { |
39 | p.error("expected `;`, `{`, or `(`"); | 36 | p.error("expected `;`, `{`, or `(`"); |
40 | return; | ||
41 | } | 37 | } |
42 | _ => { | 38 | _ => { |
43 | p.error("expected `{`"); | 39 | p.error("expected `{`"); |
44 | return; | ||
45 | } | 40 | } |
46 | } | 41 | } |
42 | m.complete(p, STRUCT_DEF); | ||
47 | } | 43 | } |
48 | 44 | ||
49 | pub(super) fn enum_def(p: &mut Parser) { | 45 | pub(super) fn enum_def(p: &mut Parser, m: Marker) { |
50 | assert!(p.at(ENUM_KW)); | 46 | assert!(p.at(ENUM_KW)); |
51 | p.bump(); | 47 | p.bump(); |
52 | name_r(p, ITEM_RECOVERY_SET); | 48 | name_r(p, ITEM_RECOVERY_SET); |
@@ -57,6 +53,7 @@ pub(super) fn enum_def(p: &mut Parser) { | |||
57 | } else { | 53 | } else { |
58 | p.error("expected `{`") | 54 | p.error("expected `{`") |
59 | } | 55 | } |
56 | m.complete(p, ENUM_DEF); | ||
60 | } | 57 | } |
61 | 58 | ||
62 | pub(crate) fn enum_variant_list(p: &mut Parser) { | 59 | pub(crate) fn enum_variant_list(p: &mut Parser) { |
diff --git a/crates/ra_parser/src/grammar/items/use_item.rs b/crates/ra_parser/src/grammar/items/use_item.rs index b36612726..ea2f94604 100644 --- a/crates/ra_parser/src/grammar/items/use_item.rs +++ b/crates/ra_parser/src/grammar/items/use_item.rs | |||
@@ -1,10 +1,11 @@ | |||
1 | use super::*; | 1 | use super::*; |
2 | 2 | ||
3 | pub(super) fn use_item(p: &mut Parser) { | 3 | pub(super) fn use_item(p: &mut Parser, m: Marker) { |
4 | assert!(p.at(USE_KW)); | 4 | assert!(p.at(USE_KW)); |
5 | p.bump(); | 5 | p.bump(); |
6 | use_tree(p); | 6 | use_tree(p); |
7 | p.expect(SEMI); | 7 | p.expect(SEMI); |
8 | m.complete(p, USE_ITEM); | ||
8 | } | 9 | } |
9 | 10 | ||
10 | /// Parse a use 'tree', such as `some::path` in `use some::path;` | 11 | /// Parse a use 'tree', such as `some::path` in `use some::path;` |