aboutsummaryrefslogtreecommitdiff
path: root/crates/parser/src/grammar/items/adt.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/parser/src/grammar/items/adt.rs')
-rw-r--r--crates/parser/src/grammar/items/adt.rs178
1 files changed, 178 insertions, 0 deletions
diff --git a/crates/parser/src/grammar/items/adt.rs b/crates/parser/src/grammar/items/adt.rs
new file mode 100644
index 000000000..67c0c5697
--- /dev/null
+++ b/crates/parser/src/grammar/items/adt.rs
@@ -0,0 +1,178 @@
1//! FIXME: write short doc here
2
3use super::*;
4
5pub(super) fn strukt(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);
9}
10
11pub(super) fn union(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);
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_generic_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_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_list(p),
38 T!['('] if kw == T![struct] => {
39 tuple_field_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_(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_generic_param_list(p);
61 type_params::opt_where_clause(p);
62 if p.at(T!['{']) {
63 variant_list(p);
64 } else {
65 p.error("expected `{`")
66 }
67 m.complete(p, ENUM);
68}
69
70pub(crate) fn 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_attrs(p);
81 if p.at(IDENT) {
82 name(p);
83 match p.current() {
84 T!['{'] => record_field_list(p),
85 T!['('] => tuple_field_list(p),
86 _ => (),
87 }
88
89 // test variant_discriminant
90 // enum E { X(i32) = 10 }
91 if p.eat(T![=]) {
92 expressions::expr(p);
93 }
94 var.complete(p, VARIANT);
95 } else {
96 var.abandon(p);
97 p.err_and_bump("expected enum variant");
98 }
99 if !p.at(T!['}']) {
100 p.expect(T![,]);
101 }
102 }
103 p.expect(T!['}']);
104 m.complete(p, VARIANT_LIST);
105}
106
107pub(crate) fn record_field_list(p: &mut Parser) {
108 assert!(p.at(T!['{']));
109 let m = p.start();
110 p.bump(T!['{']);
111 while !p.at(T!['}']) && !p.at(EOF) {
112 if p.at(T!['{']) {
113 error_block(p, "expected field");
114 continue;
115 }
116 record_field_def(p);
117 if !p.at(T!['}']) {
118 p.expect(T![,]);
119 }
120 }
121 p.expect(T!['}']);
122 m.complete(p, RECORD_FIELD_LIST);
123
124 fn record_field_def(p: &mut Parser) {
125 let m = p.start();
126 // test record_field_attrs
127 // struct S {
128 // #[serde(with = "url_serde")]
129 // pub uri: Uri,
130 // }
131 attributes::outer_attrs(p);
132 opt_visibility(p);
133 if p.at(IDENT) {
134 name(p);
135 p.expect(T![:]);
136 types::type_(p);
137 m.complete(p, RECORD_FIELD);
138 } else {
139 m.abandon(p);
140 p.err_and_bump("expected field declaration");
141 }
142 }
143}
144
145fn tuple_field_list(p: &mut Parser) {
146 assert!(p.at(T!['(']));
147 let m = p.start();
148 if !p.expect(T!['(']) {
149 return;
150 }
151 while !p.at(T![')']) && !p.at(EOF) {
152 let m = p.start();
153 // test tuple_field_attrs
154 // struct S (
155 // #[serde(with = "url_serde")]
156 // pub Uri,
157 // );
158 //
159 // enum S {
160 // Uri(#[serde(with = "url_serde")] Uri),
161 // }
162 attributes::outer_attrs(p);
163 opt_visibility(p);
164 if !p.at_ts(types::TYPE_FIRST) {
165 p.error("expected a type");
166 m.complete(p, ERROR);
167 break;
168 }
169 types::type_(p);
170 m.complete(p, TUPLE_FIELD);
171
172 if !p.at(T![')']) {
173 p.expect(T![,]);
174 }
175 }
176 p.expect(T![')']);
177 m.complete(p, TUPLE_FIELD_LIST);
178}