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