From f48b9d9be737339be988042ca88d31330738618c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 8 Sep 2018 10:55:09 +0300 Subject: Fix block structure in enums --- crates/libsyntax2/src/grammar/items/mod.rs | 8 +- crates/libsyntax2/src/grammar/items/nominal.rs | 150 +++++++++++++++++++++++++ crates/libsyntax2/src/grammar/items/structs.rs | 141 ----------------------- 3 files changed, 154 insertions(+), 145 deletions(-) create mode 100644 crates/libsyntax2/src/grammar/items/nominal.rs delete mode 100644 crates/libsyntax2/src/grammar/items/structs.rs (limited to 'crates/libsyntax2/src') diff --git a/crates/libsyntax2/src/grammar/items/mod.rs b/crates/libsyntax2/src/grammar/items/mod.rs index 57742ecb9..85d7fe770 100644 --- a/crates/libsyntax2/src/grammar/items/mod.rs +++ b/crates/libsyntax2/src/grammar/items/mod.rs @@ -1,11 +1,11 @@ mod consts; -mod structs; +mod nominal; mod traits; mod use_item; use super::*; -pub(crate) use self::structs::named_field_def_list; +pub(crate) use self::nominal::named_field_def_list; // test mod_contents // fn foo() {} @@ -176,7 +176,7 @@ fn items_without_modifiers(p: &mut Parser) -> Option { MODULE } STRUCT_KW => { - structs::struct_def(p); + nominal::struct_def(p); if p.at(SEMI) { p.err_and_bump( "expected item, found `;`\n\ @@ -186,7 +186,7 @@ fn items_without_modifiers(p: &mut Parser) -> Option { STRUCT_DEF } ENUM_KW => { - structs::enum_def(p); + nominal::enum_def(p); ENUM_DEF } USE_KW => { 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 @@ +use super::*; + +pub(super) fn struct_def(p: &mut Parser) { + assert!(p.at(STRUCT_KW)); + p.bump(); + + name_r(p, ITEM_RECOVERY_SET); + type_params::opt_type_param_list(p); + match p.current() { + WHERE_KW => { + type_params::opt_where_clause(p); + match p.current() { + SEMI => { + p.bump(); + return; + } + L_CURLY => named_field_def_list(p), + _ => { + //TODO: special case `(` error message + p.error("expected `;` or `{`"); + return; + } + } + } + SEMI => { + p.bump(); + return; + } + L_CURLY => named_field_def_list(p), + L_PAREN => { + pos_field_list(p); + p.expect(SEMI); + } + _ => { + p.error("expected `;`, `{`, or `(`"); + return; + } + } +} + +pub(super) fn enum_def(p: &mut Parser) { + assert!(p.at(ENUM_KW)); + p.bump(); + name_r(p, ITEM_RECOVERY_SET); + type_params::opt_type_param_list(p); + type_params::opt_where_clause(p); + if p.at(L_CURLY) { + enum_variant_list(p); + } else { + p.error("expected `{`") + } +} + +fn enum_variant_list(p: &mut Parser) { + assert!(p.at(L_CURLY)); + let m = p.start(); + p.bump(); + while !p.at(EOF) && !p.at(R_CURLY) { + if p.at(L_CURLY) { + error_block(p, "expected enum variant"); + continue; + } + let var = p.start(); + attributes::outer_attributes(p); + if p.at(IDENT) { + name(p); + match p.current() { + L_CURLY => named_field_def_list(p), + L_PAREN => pos_field_list(p), + EQ => { + p.bump(); + expressions::expr(p); + } + _ => (), + } + 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); + m.complete(p, ENUM_VARIANT_LIST); +} + +pub(crate) fn named_field_def_list(p: &mut Parser) { + assert!(p.at(L_CURLY)); + let m = p.start(); + p.bump(); + while !p.at(R_CURLY) && !p.at(EOF) { + if p.at(L_CURLY) { + error_block(p, "expected field"); + continue; + } + named_field_def(p); + if !p.at(R_CURLY) { + p.expect(COMMA); + } + } + p.expect(R_CURLY); + m.complete(p, NAMED_FIELD_DEF_LIST); + + fn named_field_def(p: &mut Parser) { + let m = p.start(); + // test field_attrs + // struct S { + // #[serde(with = "url_serde")] + // pub uri: Uri, + // } + attributes::outer_attributes(p); + opt_visibility(p); + if p.at(IDENT) { + name(p); + p.expect(COLON); + types::type_(p); + m.complete(p, NAMED_FIELD_DEF); + } else { + m.abandon(p); + p.err_and_bump("expected field declaration"); + } + } +} + +fn pos_field_list(p: &mut Parser) { + assert!(p.at(L_PAREN)); + let m = p.start(); + if !p.expect(L_PAREN) { + return; + } + while !p.at(R_PAREN) && !p.at(EOF) { + let m = p.start(); + opt_visibility(p); + if !p.at_ts(types::TYPE_FIRST) { + p.error("expected a type"); + m.complete(p, ERROR); + break; + } + types::type_(p); + m.complete(p, POS_FIELD); + + if !p.at(R_PAREN) { + p.expect(COMMA); + } + } + p.expect(R_PAREN); + m.complete(p, POS_FIELD_LIST); +} diff --git a/crates/libsyntax2/src/grammar/items/structs.rs b/crates/libsyntax2/src/grammar/items/structs.rs deleted file mode 100644 index f1e78865c..000000000 --- a/crates/libsyntax2/src/grammar/items/structs.rs +++ /dev/null @@ -1,141 +0,0 @@ -use super::*; - -pub(super) fn struct_def(p: &mut Parser) { - assert!(p.at(STRUCT_KW)); - p.bump(); - - name_r(p, ITEM_RECOVERY_SET); - type_params::opt_type_param_list(p); - match p.current() { - WHERE_KW => { - type_params::opt_where_clause(p); - match p.current() { - SEMI => { - p.bump(); - return; - } - L_CURLY => named_field_def_list(p), - _ => { - //TODO: special case `(` error message - p.error("expected `;` or `{`"); - return; - } - } - } - SEMI => { - p.bump(); - return; - } - L_CURLY => named_field_def_list(p), - L_PAREN => { - pos_field_list(p); - p.expect(SEMI); - } - _ => { - p.error("expected `;`, `{`, or `(`"); - return; - } - } -} - -pub(super) fn enum_def(p: &mut Parser) { - assert!(p.at(ENUM_KW)); - p.bump(); - name_r(p, ITEM_RECOVERY_SET); - type_params::opt_type_param_list(p); - type_params::opt_where_clause(p); - if p.at(L_CURLY) { - enum_variant_list(p); - } else { - p.error("expected `{`") - } -} - -fn enum_variant_list(p: &mut Parser) { - assert!(p.at(L_CURLY)); - let m = p.start(); - p.bump(); - while !p.at(EOF) && !p.at(R_CURLY) { - if p.at(L_CURLY) { - error_block(p, "expected enum variant"); - continue; - } - let var = p.start(); - attributes::outer_attributes(p); - if p.at(IDENT) { - name(p); - match p.current() { - L_CURLY => named_field_def_list(p), - L_PAREN => pos_field_list(p), - EQ => { - p.bump(); - expressions::expr(p); - } - _ => (), - } - 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); - m.complete(p, ENUM_VARIANT_LIST); -} - -pub(crate) fn named_field_def_list(p: &mut Parser) { - assert!(p.at(L_CURLY)); - let m = p.start(); - p.bump(); - while !p.at(R_CURLY) && !p.at(EOF) { - named_field_def(p); - if !p.at(R_CURLY) { - p.expect(COMMA); - } - } - p.expect(R_CURLY); - m.complete(p, NAMED_FIELD_DEF_LIST); - - fn named_field_def(p: &mut Parser) { - let m = p.start(); - // test field_attrs - // struct S { - // #[serde(with = "url_serde")] - // pub uri: Uri, - // } - attributes::outer_attributes(p); - opt_visibility(p); - if p.at(IDENT) { - name(p); - p.expect(COLON); - types::type_(p); - m.complete(p, NAMED_FIELD_DEF); - } else { - m.abandon(p); - p.err_and_bump("expected field declaration"); - } - } -} - -fn pos_field_list(p: &mut Parser) { - assert!(p.at(L_PAREN)); - let m = p.start(); - if !p.expect(L_PAREN) { - return; - } - while !p.at(R_PAREN) && !p.at(EOF) { - let pos_field = p.start(); - opt_visibility(p); - types::type_(p); - pos_field.complete(p, POS_FIELD); - - if !p.at(R_PAREN) { - p.expect(COMMA); - } - } - p.expect(R_PAREN); - m.complete(p, POS_FIELD_LIST); -} -- cgit v1.2.3