Files
rust/crates/libsyntax2/src/grammar/items/structs.rs

123 lines
2.9 KiB
Rust
Raw Normal View History

use super::*;
2018-08-13 18:34:02 +03:00
pub(super) fn struct_def(p: &mut Parser) {
assert!(p.at(STRUCT_KW));
p.bump();
2018-02-10 14:10:02 +03:00
name(p);
2018-07-31 23:16:07 +03:00
type_params::type_param_list(p);
match p.current() {
WHERE_KW => {
type_params::where_clause(p);
match p.current() {
SEMI => {
p.bump();
return;
}
L_CURLY => named_fields(p),
_ => {
//TODO: special case `(` error message
2018-02-09 22:44:50 +03:00
p.error("expected `;` or `{`");
return;
}
}
}
SEMI => {
p.bump();
return;
}
L_CURLY => named_fields(p),
L_PAREN => {
pos_fields(p);
p.expect(SEMI);
}
_ => {
2018-02-09 22:44:50 +03:00
p.error("expected `;`, `{`, or `(`");
return;
}
}
}
2018-08-13 18:34:02 +03:00
pub(super) fn enum_def(p: &mut Parser) {
2018-01-28 22:59:18 +03:00
assert!(p.at(ENUM_KW));
p.bump();
2018-02-10 14:10:50 +03:00
name(p);
2018-07-31 23:16:07 +03:00
type_params::type_param_list(p);
type_params::where_clause(p);
2018-01-28 22:59:18 +03:00
if p.expect(L_CURLY) {
while !p.at(EOF) && !p.at(R_CURLY) {
let var = p.start();
attributes::outer_attributes(p);
if p.at(IDENT) {
2018-08-01 10:44:23 +03:00
name(p);
2018-01-28 22:59:18 +03:00
match p.current() {
L_CURLY => named_fields(p),
L_PAREN => pos_fields(p),
EQ => {
p.bump();
expressions::expr(p);
}
2018-01-28 23:14:00 +03:00
_ => (),
2018-01-28 22:59:18 +03:00
}
var.complete(p, ENUM_VARIANT);
} else {
var.abandon(p);
p.err_and_bump("expected enum variant");
}
if !p.at(R_CURLY) {
p.expect(COMMA);
}
}
p.expect(R_CURLY);
}
}
fn named_fields(p: &mut Parser) {
assert!(p.at(L_CURLY));
p.bump();
while !p.at(R_CURLY) && !p.at(EOF) {
named_field(p);
if !p.at(R_CURLY) {
p.expect(COMMA);
}
}
p.expect(R_CURLY);
fn named_field(p: &mut Parser) {
2018-08-16 13:20:59 +03:00
let m = p.start();
// test field_attrs
// struct S {
// #[serde(with = "url_serde")]
// pub uri: Uri,
// }
attributes::outer_attributes(p);
2018-08-24 00:16:29 +03:00
opt_visibility(p);
2018-02-10 14:13:30 +03:00
if p.at(IDENT) {
name(p);
p.expect(COLON);
2018-02-11 11:01:00 +03:00
types::type_(p);
2018-08-16 13:20:59 +03:00
m.complete(p, NAMED_FIELD);
} else {
2018-08-16 13:20:59 +03:00
m.abandon(p);
p.err_and_bump("expected field declaration");
}
}
}
fn pos_fields(p: &mut Parser) {
if !p.expect(L_PAREN) {
return;
}
while !p.at(R_PAREN) && !p.at(EOF) {
let pos_field = p.start();
2018-08-24 00:16:29 +03:00
opt_visibility(p);
2018-02-11 11:01:00 +03:00
types::type_(p);
pos_field.complete(p, POS_FIELD);
if !p.at(R_PAREN) {
p.expect(COMMA);
}
}
p.expect(R_PAREN);
}