aboutsummaryrefslogtreecommitdiff
path: root/crates/libsyntax2/src/grammar/items/nominal.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/libsyntax2/src/grammar/items/nominal.rs')
-rw-r--r--crates/libsyntax2/src/grammar/items/nominal.rs150
1 files changed, 150 insertions, 0 deletions
diff --git a/crates/libsyntax2/src/grammar/items/nominal.rs b/crates/libsyntax2/src/grammar/items/nominal.rs
new file mode 100644
index 000000000..3db5b24af
--- /dev/null
+++ b/crates/libsyntax2/src/grammar/items/nominal.rs
@@ -0,0 +1,150 @@
1use super::*;
2
3pub(super) fn struct_def(p: &mut Parser) {
4 assert!(p.at(STRUCT_KW));
5 p.bump();
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 => {
26 p.bump();
27 return;
28 }
29 L_CURLY => named_field_def_list(p),
30 L_PAREN => {
31 pos_field_list(p);
32 p.expect(SEMI);
33 }
34 _ => {
35 p.error("expected `;`, `{`, or `(`");
36 return;
37 }
38 }
39}
40
41pub(super) fn enum_def(p: &mut Parser) {
42 assert!(p.at(ENUM_KW));
43 p.bump();
44 name_r(p, ITEM_RECOVERY_SET);
45 type_params::opt_type_param_list(p);
46 type_params::opt_where_clause(p);
47 if p.at(L_CURLY) {
48 enum_variant_list(p);
49 } else {
50 p.error("expected `{`")
51 }
52}
53
54fn enum_variant_list(p: &mut Parser) {
55 assert!(p.at(L_CURLY));
56 let m = p.start();
57 p.bump();
58 while !p.at(EOF) && !p.at(R_CURLY) {
59 if p.at(L_CURLY) {
60 error_block(p, "expected enum variant");
61 continue;
62 }
63 let var = p.start();
64 attributes::outer_attributes(p);
65 if p.at(IDENT) {
66 name(p);
67 match p.current() {
68 L_CURLY => named_field_def_list(p),
69 L_PAREN => pos_field_list(p),
70 EQ => {
71 p.bump();
72 expressions::expr(p);
73 }
74 _ => (),
75 }
76 var.complete(p, ENUM_VARIANT);
77 } else {
78 var.abandon(p);
79 p.err_and_bump("expected enum variant");
80 }
81 if !p.at(R_CURLY) {
82 p.expect(COMMA);
83 }
84 }
85 p.expect(R_CURLY);
86 m.complete(p, ENUM_VARIANT_LIST);
87}
88
89pub(crate) fn named_field_def_list(p: &mut Parser) {
90 assert!(p.at(L_CURLY));
91 let m = p.start();
92 p.bump();
93 while !p.at(R_CURLY) && !p.at(EOF) {
94 if p.at(L_CURLY) {
95 error_block(p, "expected field");
96 continue;
97 }
98 named_field_def(p);
99 if !p.at(R_CURLY) {
100 p.expect(COMMA);
101 }
102 }
103 p.expect(R_CURLY);
104 m.complete(p, NAMED_FIELD_DEF_LIST);
105
106 fn named_field_def(p: &mut Parser) {
107 let m = p.start();
108 // test field_attrs
109 // struct S {
110 // #[serde(with = "url_serde")]
111 // pub uri: Uri,
112 // }
113 attributes::outer_attributes(p);
114 opt_visibility(p);
115 if p.at(IDENT) {
116 name(p);
117 p.expect(COLON);
118 types::type_(p);
119 m.complete(p, NAMED_FIELD_DEF);
120 } else {
121 m.abandon(p);
122 p.err_and_bump("expected field declaration");
123 }
124 }
125}
126
127fn pos_field_list(p: &mut Parser) {
128 assert!(p.at(L_PAREN));
129 let m = p.start();
130 if !p.expect(L_PAREN) {
131 return;
132 }
133 while !p.at(R_PAREN) && !p.at(EOF) {
134 let m = p.start();
135 opt_visibility(p);
136 if !p.at_ts(types::TYPE_FIRST) {
137 p.error("expected a type");
138 m.complete(p, ERROR);
139 break;
140 }
141 types::type_(p);
142 m.complete(p, POS_FIELD);
143
144 if !p.at(R_PAREN) {
145 p.expect(COMMA);
146 }
147 }
148 p.expect(R_PAREN);
149 m.complete(p, POS_FIELD_LIST);
150}