aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser/src/grammar/items/adt.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_parser/src/grammar/items/adt.rs')
-rw-r--r--crates/ra_parser/src/grammar/items/adt.rs176
1 files changed, 176 insertions, 0 deletions
diff --git a/crates/ra_parser/src/grammar/items/adt.rs b/crates/ra_parser/src/grammar/items/adt.rs
new file mode 100644
index 000000000..c777bc9d0
--- /dev/null
+++ b/crates/ra_parser/src/grammar/items/adt.rs
@@ -0,0 +1,176 @@
1//! FIXME: write short doc here
2
3use super::*;
4
5pub(super) fn struct_def(p: &mut Parser, m: Marker) {
6 assert!(p.at(T![struct]));
7 p.bump(T![struct]);
8 struct_or_union(p, m, T![struct], STRUCT_DEF);
9}
10
11pub(super) fn union_def(p: &mut Parser, m: Marker) {
12 assert!(p.at_contextual_kw("union"));
13 p.bump_remap(T![union]);
14 struct_or_union(p, m, T![union], UNION_DEF);
15}
16
17fn struct_or_union(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) {
18 name_r(p, ITEM_RECOVERY_SET);
19 type_params::opt_type_param_list(p);
20 match p.current() {
21 T![where] => {
22 type_params::opt_where_clause(p);
23 match p.current() {
24 T![;] => {
25 p.bump(T![;]);
26 }
27 T!['{'] => record_field_def_list(p),
28 _ => {
29 //FIXME: special case `(` error message
30 p.error("expected `;` or `{`");
31 }
32 }
33 }
34 T![;] if kw == T![struct] => {
35 p.bump(T![;]);
36 }
37 T!['{'] => record_field_def_list(p),
38 T!['('] if kw == T![struct] => {
39 tuple_field_def_list(p);
40 // test tuple_struct_where
41 // struct Test<T>(T) where T: Clone;
42 // struct Test<T>(T);
43 type_params::opt_where_clause(p);
44 p.expect(T![;]);
45 }
46 _ if kw == T![struct] => {
47 p.error("expected `;`, `{`, or `(`");
48 }
49 _ => {
50 p.error("expected `{`");
51 }
52 }
53 m.complete(p, def);
54}
55
56pub(super) fn enum_def(p: &mut Parser, m: Marker) {
57 assert!(p.at(T![enum]));
58 p.bump(T![enum]);
59 name_r(p, ITEM_RECOVERY_SET);
60 type_params::opt_type_param_list(p);
61 type_params::opt_where_clause(p);
62 if p.at(T!['{']) {
63 enum_variant_list(p);
64 } else {
65 p.error("expected `{`")
66 }
67 m.complete(p, ENUM_DEF);
68}
69
70pub(crate) fn enum_variant_list(p: &mut Parser) {
71 assert!(p.at(T!['{']));
72 let m = p.start();
73 p.bump(T!['{']);
74 while !p.at(EOF) && !p.at(T!['}']) {
75 if p.at(T!['{']) {
76 error_block(p, "expected enum variant");
77 continue;
78 }
79 let var = p.start();
80 attributes::outer_attributes(p);
81 if p.at(IDENT) {
82 name(p);
83 match p.current() {
84 T!['{'] => record_field_def_list(p),
85 T!['('] => tuple_field_def_list(p),
86 T![=] => {
87 p.bump(T![=]);
88 expressions::expr(p);
89 }
90 _ => (),
91 }
92 var.complete(p, ENUM_VARIANT);
93 } else {
94 var.abandon(p);
95 p.err_and_bump("expected enum variant");
96 }
97 if !p.at(T!['}']) {
98 p.expect(T![,]);
99 }
100 }
101 p.expect(T!['}']);
102 m.complete(p, ENUM_VARIANT_LIST);
103}
104
105pub(crate) fn record_field_def_list(p: &mut Parser) {
106 assert!(p.at(T!['{']));
107 let m = p.start();
108 p.bump(T!['{']);
109 while !p.at(T!['}']) && !p.at(EOF) {
110 if p.at(T!['{']) {
111 error_block(p, "expected field");
112 continue;
113 }
114 record_field_def(p);
115 if !p.at(T!['}']) {
116 p.expect(T![,]);
117 }
118 }
119 p.expect(T!['}']);
120 m.complete(p, RECORD_FIELD_DEF_LIST);
121
122 fn record_field_def(p: &mut Parser) {
123 let m = p.start();
124 // test record_field_attrs
125 // struct S {
126 // #[serde(with = "url_serde")]
127 // pub uri: Uri,
128 // }
129 attributes::outer_attributes(p);
130 opt_visibility(p);
131 if p.at(IDENT) {
132 name(p);
133 p.expect(T![:]);
134 types::type_(p);
135 m.complete(p, RECORD_FIELD_DEF);
136 } else {
137 m.abandon(p);
138 p.err_and_bump("expected field declaration");
139 }
140 }
141}
142
143fn tuple_field_def_list(p: &mut Parser) {
144 assert!(p.at(T!['(']));
145 let m = p.start();
146 if !p.expect(T!['(']) {
147 return;
148 }
149 while !p.at(T![')']) && !p.at(EOF) {
150 let m = p.start();
151 // test tuple_field_attrs
152 // struct S (
153 // #[serde(with = "url_serde")]
154 // pub Uri,
155 // );
156 //
157 // enum S {
158 // Uri(#[serde(with = "url_serde")] Uri),
159 // }
160 attributes::outer_attributes(p);
161 opt_visibility(p);
162 if !p.at_ts(types::TYPE_FIRST) {
163 p.error("expected a type");
164 m.complete(p, ERROR);
165 break;
166 }
167 types::type_(p);
168 m.complete(p, TUPLE_FIELD_DEF);
169
170 if !p.at(T![')']) {
171 p.expect(T![,]);
172 }
173 }
174 p.expect(T![')']);
175 m.complete(p, TUPLE_FIELD_DEF_LIST);
176}