diff options
Diffstat (limited to 'crates/libsyntax2/src/grammar/items')
-rw-r--r-- | crates/libsyntax2/src/grammar/items/mod.rs | 26 | ||||
-rw-r--r-- | crates/libsyntax2/src/grammar/items/structs.rs | 75 | ||||
-rw-r--r-- | crates/libsyntax2/src/grammar/items/traits.rs | 54 | ||||
-rw-r--r-- | crates/libsyntax2/src/grammar/items/use_item.rs | 8 |
4 files changed, 106 insertions, 57 deletions
diff --git a/crates/libsyntax2/src/grammar/items/mod.rs b/crates/libsyntax2/src/grammar/items/mod.rs index 18b681ee2..d236fb506 100644 --- a/crates/libsyntax2/src/grammar/items/mod.rs +++ b/crates/libsyntax2/src/grammar/items/mod.rs | |||
@@ -194,8 +194,8 @@ fn items_without_modifiers(p: &mut Parser) -> Option<SyntaxKind> { | |||
194 | // extern {} | 194 | // extern {} |
195 | EXTERN_KW if la == L_CURLY || ((la == STRING || la == RAW_STRING) && p.nth(2) == L_CURLY) => { | 195 | EXTERN_KW if la == L_CURLY || ((la == STRING || la == RAW_STRING) && p.nth(2) == L_CURLY) => { |
196 | abi(p); | 196 | abi(p); |
197 | extern_block(p); | 197 | extern_item_list(p); |
198 | EXTERN_BLOCK_EXPR | 198 | EXTERN_BLOCK |
199 | } | 199 | } |
200 | _ => return None, | 200 | _ => return None, |
201 | }; | 201 | }; |
@@ -212,10 +212,12 @@ fn extern_crate_item(p: &mut Parser) { | |||
212 | p.expect(SEMI); | 212 | p.expect(SEMI); |
213 | } | 213 | } |
214 | 214 | ||
215 | fn extern_block(p: &mut Parser) { | 215 | fn extern_item_list(p: &mut Parser) { |
216 | assert!(p.at(L_CURLY)); | 216 | assert!(p.at(L_CURLY)); |
217 | let m = p.start(); | ||
217 | p.bump(); | 218 | p.bump(); |
218 | p.expect(R_CURLY); | 219 | p.expect(R_CURLY); |
220 | m.complete(p, EXTERN_ITEM_LIST); | ||
219 | } | 221 | } |
220 | 222 | ||
221 | fn function(p: &mut Parser, flavor: ItemFlavor) { | 223 | fn function(p: &mut Parser, flavor: ItemFlavor) { |
@@ -284,14 +286,22 @@ fn mod_item(p: &mut Parser) { | |||
284 | p.bump(); | 286 | p.bump(); |
285 | 287 | ||
286 | name(p); | 288 | name(p); |
287 | if !p.eat(SEMI) { | 289 | if p.at(L_CURLY) { |
288 | if p.expect(L_CURLY) { | 290 | mod_item_list(p); |
289 | mod_contents(p, true); | 291 | } else if !p.eat(SEMI) { |
290 | p.expect(R_CURLY); | 292 | p.error("expected `;` or `{`"); |
291 | } | ||
292 | } | 293 | } |
293 | } | 294 | } |
294 | 295 | ||
296 | fn mod_item_list(p: &mut Parser) { | ||
297 | assert!(p.at(L_CURLY)); | ||
298 | let m = p.start(); | ||
299 | p.bump(); | ||
300 | mod_contents(p, true); | ||
301 | p.expect(R_CURLY); | ||
302 | m.complete(p, ITEM_LIST); | ||
303 | } | ||
304 | |||
295 | fn macro_call(p: &mut Parser) -> BlockLike { | 305 | fn macro_call(p: &mut Parser) -> BlockLike { |
296 | assert!(paths::is_path_start(p)); | 306 | assert!(paths::is_path_start(p)); |
297 | paths::use_path(p); | 307 | paths::use_path(p); |
diff --git a/crates/libsyntax2/src/grammar/items/structs.rs b/crates/libsyntax2/src/grammar/items/structs.rs index cde9d0ae6..ca027d718 100644 --- a/crates/libsyntax2/src/grammar/items/structs.rs +++ b/crates/libsyntax2/src/grammar/items/structs.rs | |||
@@ -14,7 +14,7 @@ pub(super) fn struct_def(p: &mut Parser) { | |||
14 | p.bump(); | 14 | p.bump(); |
15 | return; | 15 | return; |
16 | } | 16 | } |
17 | L_CURLY => named_fields(p), | 17 | L_CURLY => named_field_def_list(p), |
18 | _ => { | 18 | _ => { |
19 | //TODO: special case `(` error message | 19 | //TODO: special case `(` error message |
20 | p.error("expected `;` or `{`"); | 20 | p.error("expected `;` or `{`"); |
@@ -26,9 +26,9 @@ pub(super) fn struct_def(p: &mut Parser) { | |||
26 | p.bump(); | 26 | p.bump(); |
27 | return; | 27 | return; |
28 | } | 28 | } |
29 | L_CURLY => named_fields(p), | 29 | L_CURLY => named_field_def_list(p), |
30 | L_PAREN => { | 30 | L_PAREN => { |
31 | pos_fields(p); | 31 | pos_field_list(p); |
32 | p.expect(SEMI); | 32 | p.expect(SEMI); |
33 | } | 33 | } |
34 | _ => { | 34 | _ => { |
@@ -44,46 +44,58 @@ pub(super) fn enum_def(p: &mut Parser) { | |||
44 | name(p); | 44 | name(p); |
45 | type_params::opt_type_param_list(p); | 45 | type_params::opt_type_param_list(p); |
46 | type_params::opt_where_clause(p); | 46 | type_params::opt_where_clause(p); |
47 | if p.expect(L_CURLY) { | 47 | if p.at(L_CURLY) { |
48 | while !p.at(EOF) && !p.at(R_CURLY) { | 48 | enum_variant_list(p); |
49 | let var = p.start(); | 49 | } else { |
50 | attributes::outer_attributes(p); | 50 | p.error("expected `{`") |
51 | if p.at(IDENT) { | 51 | } |
52 | name(p); | 52 | } |
53 | match p.current() { | 53 | |
54 | L_CURLY => named_fields(p), | 54 | fn enum_variant_list(p: &mut Parser) { |
55 | L_PAREN => pos_fields(p), | 55 | assert!(p.at(L_CURLY)); |
56 | EQ => { | 56 | let m = p.start(); |
57 | p.bump(); | 57 | p.bump(); |
58 | expressions::expr(p); | 58 | while !p.at(EOF) && !p.at(R_CURLY) { |
59 | } | 59 | let var = p.start(); |
60 | _ => (), | 60 | attributes::outer_attributes(p); |
61 | if p.at(IDENT) { | ||
62 | name(p); | ||
63 | match p.current() { | ||
64 | L_CURLY => named_field_def_list(p), | ||
65 | L_PAREN => pos_field_list(p), | ||
66 | EQ => { | ||
67 | p.bump(); | ||
68 | expressions::expr(p); | ||
61 | } | 69 | } |
62 | var.complete(p, ENUM_VARIANT); | 70 | _ => (), |
63 | } else { | ||
64 | var.abandon(p); | ||
65 | p.err_and_bump("expected enum variant"); | ||
66 | } | ||
67 | if !p.at(R_CURLY) { | ||
68 | p.expect(COMMA); | ||
69 | } | 71 | } |
72 | var.complete(p, ENUM_VARIANT); | ||
73 | } else { | ||
74 | var.abandon(p); | ||
75 | p.err_and_bump("expected enum variant"); | ||
76 | } | ||
77 | if !p.at(R_CURLY) { | ||
78 | p.expect(COMMA); | ||
70 | } | 79 | } |
71 | p.expect(R_CURLY); | ||
72 | } | 80 | } |
81 | p.expect(R_CURLY); | ||
82 | m.complete(p, ENUM_VARIANT_LIST); | ||
73 | } | 83 | } |
74 | 84 | ||
75 | fn named_fields(p: &mut Parser) { | 85 | fn named_field_def_list(p: &mut Parser) { |
76 | assert!(p.at(L_CURLY)); | 86 | assert!(p.at(L_CURLY)); |
87 | let m = p.start(); | ||
77 | p.bump(); | 88 | p.bump(); |
78 | while !p.at(R_CURLY) && !p.at(EOF) { | 89 | while !p.at(R_CURLY) && !p.at(EOF) { |
79 | named_field(p); | 90 | named_field_def(p); |
80 | if !p.at(R_CURLY) { | 91 | if !p.at(R_CURLY) { |
81 | p.expect(COMMA); | 92 | p.expect(COMMA); |
82 | } | 93 | } |
83 | } | 94 | } |
84 | p.expect(R_CURLY); | 95 | p.expect(R_CURLY); |
96 | m.complete(p, NAMED_FIELD_DEF_LIST); | ||
85 | 97 | ||
86 | fn named_field(p: &mut Parser) { | 98 | fn named_field_def(p: &mut Parser) { |
87 | let m = p.start(); | 99 | let m = p.start(); |
88 | // test field_attrs | 100 | // test field_attrs |
89 | // struct S { | 101 | // struct S { |
@@ -96,7 +108,7 @@ fn named_fields(p: &mut Parser) { | |||
96 | name(p); | 108 | name(p); |
97 | p.expect(COLON); | 109 | p.expect(COLON); |
98 | types::type_(p); | 110 | types::type_(p); |
99 | m.complete(p, NAMED_FIELD); | 111 | m.complete(p, NAMED_FIELD_DEF); |
100 | } else { | 112 | } else { |
101 | m.abandon(p); | 113 | m.abandon(p); |
102 | p.err_and_bump("expected field declaration"); | 114 | p.err_and_bump("expected field declaration"); |
@@ -104,7 +116,9 @@ fn named_fields(p: &mut Parser) { | |||
104 | } | 116 | } |
105 | } | 117 | } |
106 | 118 | ||
107 | fn pos_fields(p: &mut Parser) { | 119 | fn pos_field_list(p: &mut Parser) { |
120 | assert!(p.at(L_PAREN)); | ||
121 | let m = p.start(); | ||
108 | if !p.expect(L_PAREN) { | 122 | if !p.expect(L_PAREN) { |
109 | return; | 123 | return; |
110 | } | 124 | } |
@@ -119,4 +133,5 @@ fn pos_fields(p: &mut Parser) { | |||
119 | } | 133 | } |
120 | } | 134 | } |
121 | p.expect(R_PAREN); | 135 | p.expect(R_PAREN); |
136 | m.complete(p, POS_FIELD_LIST); | ||
122 | } | 137 | } |
diff --git a/crates/libsyntax2/src/grammar/items/traits.rs b/crates/libsyntax2/src/grammar/items/traits.rs index 73ecd4bef..3853ccaab 100644 --- a/crates/libsyntax2/src/grammar/items/traits.rs +++ b/crates/libsyntax2/src/grammar/items/traits.rs | |||
@@ -11,18 +11,29 @@ pub(super) fn trait_def(p: &mut Parser) { | |||
11 | type_params::bounds(p); | 11 | type_params::bounds(p); |
12 | } | 12 | } |
13 | type_params::opt_where_clause(p); | 13 | type_params::opt_where_clause(p); |
14 | p.expect(L_CURLY); | 14 | if p.at(L_CURLY) { |
15 | // test trait_item_items | 15 | trait_item_list(p); |
16 | // impl F { | 16 | } else { |
17 | // type A: Clone; | 17 | p.error("expected `{`"); |
18 | // const B: i32; | 18 | } |
19 | // fn foo() {} | 19 | } |
20 | // fn bar(&self); | 20 | |
21 | // } | 21 | // test trait_item_list |
22 | // impl F { | ||
23 | // type A: Clone; | ||
24 | // const B: i32; | ||
25 | // fn foo() {} | ||
26 | // fn bar(&self); | ||
27 | // } | ||
28 | fn trait_item_list(p: &mut Parser) { | ||
29 | assert!(p.at(L_CURLY)); | ||
30 | let m = p.start(); | ||
31 | p.bump(); | ||
22 | while !p.at(EOF) && !p.at(R_CURLY) { | 32 | while !p.at(EOF) && !p.at(R_CURLY) { |
23 | item_or_macro(p, true, ItemFlavor::Trait); | 33 | item_or_macro(p, true, ItemFlavor::Trait); |
24 | } | 34 | } |
25 | p.expect(R_CURLY); | 35 | p.expect(R_CURLY); |
36 | m.complete(p, ITEM_LIST); | ||
26 | } | 37 | } |
27 | 38 | ||
28 | // test impl_item | 39 | // test impl_item |
@@ -45,19 +56,30 @@ pub(super) fn impl_item(p: &mut Parser) { | |||
45 | types::type_(p); | 56 | types::type_(p); |
46 | } | 57 | } |
47 | type_params::opt_where_clause(p); | 58 | type_params::opt_where_clause(p); |
48 | p.expect(L_CURLY); | 59 | if p.at(L_CURLY) { |
60 | impl_item_list(p); | ||
61 | } else { | ||
62 | p.error("expected `{`"); | ||
63 | } | ||
64 | } | ||
65 | |||
66 | // test impl_item_list | ||
67 | // impl F { | ||
68 | // type A = i32; | ||
69 | // const B: i32 = 92; | ||
70 | // fn foo() {} | ||
71 | // fn bar(&self) {} | ||
72 | // } | ||
73 | fn impl_item_list(p: &mut Parser) { | ||
74 | assert!(p.at(L_CURLY)); | ||
75 | let m = p.start(); | ||
76 | p.bump(); | ||
49 | 77 | ||
50 | // test impl_item_items | ||
51 | // impl F { | ||
52 | // type A = i32; | ||
53 | // const B: i32 = 92; | ||
54 | // fn foo() {} | ||
55 | // fn bar(&self) {} | ||
56 | // } | ||
57 | while !p.at(EOF) && !p.at(R_CURLY) { | 78 | while !p.at(EOF) && !p.at(R_CURLY) { |
58 | item_or_macro(p, true, ItemFlavor::Mod); | 79 | item_or_macro(p, true, ItemFlavor::Mod); |
59 | } | 80 | } |
60 | p.expect(R_CURLY); | 81 | p.expect(R_CURLY); |
82 | m.complete(p, ITEM_LIST); | ||
61 | } | 83 | } |
62 | 84 | ||
63 | fn choose_type_params_over_qpath(p: &Parser) -> bool { | 85 | fn choose_type_params_over_qpath(p: &Parser) -> bool { |
diff --git a/crates/libsyntax2/src/grammar/items/use_item.rs b/crates/libsyntax2/src/grammar/items/use_item.rs index 3da40a629..2fbf2234a 100644 --- a/crates/libsyntax2/src/grammar/items/use_item.rs +++ b/crates/libsyntax2/src/grammar/items/use_item.rs | |||
@@ -20,7 +20,7 @@ fn use_tree(p: &mut Parser) { | |||
20 | if p.at(COLONCOLON) { | 20 | if p.at(COLONCOLON) { |
21 | p.bump(); | 21 | p.bump(); |
22 | } | 22 | } |
23 | nested_trees(p); | 23 | use_tree_list(p); |
24 | } | 24 | } |
25 | _ if paths::is_path_start(p) => { | 25 | _ if paths::is_path_start(p) => { |
26 | paths::use_path(p); | 26 | paths::use_path(p); |
@@ -34,7 +34,7 @@ fn use_tree(p: &mut Parser) { | |||
34 | STAR => { | 34 | STAR => { |
35 | p.bump(); | 35 | p.bump(); |
36 | } | 36 | } |
37 | L_CURLY => nested_trees(p), | 37 | L_CURLY => use_tree_list(p), |
38 | _ => { | 38 | _ => { |
39 | // is this unreachable? | 39 | // is this unreachable? |
40 | p.error("expected `{` or `*`"); | 40 | p.error("expected `{` or `*`"); |
@@ -53,8 +53,9 @@ fn use_tree(p: &mut Parser) { | |||
53 | m.complete(p, USE_TREE); | 53 | m.complete(p, USE_TREE); |
54 | } | 54 | } |
55 | 55 | ||
56 | fn nested_trees(p: &mut Parser) { | 56 | fn use_tree_list(p: &mut Parser) { |
57 | assert!(p.at(L_CURLY)); | 57 | assert!(p.at(L_CURLY)); |
58 | let m = p.start(); | ||
58 | p.bump(); | 59 | p.bump(); |
59 | while !p.at(EOF) && !p.at(R_CURLY) { | 60 | while !p.at(EOF) && !p.at(R_CURLY) { |
60 | use_tree(p); | 61 | use_tree(p); |
@@ -63,4 +64,5 @@ fn nested_trees(p: &mut Parser) { | |||
63 | } | 64 | } |
64 | } | 65 | } |
65 | p.expect(R_CURLY); | 66 | p.expect(R_CURLY); |
67 | m.complete(p, USE_TREE_LIST); | ||
66 | } | 68 | } |