From 100968b68999231368fbacf62e8b8f242fbfdd3a Mon Sep 17 00:00:00 2001 From: darksv Date: Fri, 14 Sep 2018 22:51:12 +0200 Subject: [PATCH] Support for unions --- crates/libsyntax2/src/grammar/items/mod.rs | 21 ++++- .../libsyntax2/src/grammar/items/nominal.rs | 16 ++-- .../data/parser/inline/0109_struct_items.txt | 86 +++++++++++++++++++ .../data/parser/inline/0110_union_items.txt | 45 ++++++++++ 4 files changed, 161 insertions(+), 7 deletions(-) create mode 100644 crates/libsyntax2/tests/data/parser/inline/0109_struct_items.txt create mode 100644 crates/libsyntax2/tests/data/parser/inline/0110_union_items.txt diff --git a/crates/libsyntax2/src/grammar/items/mod.rs b/crates/libsyntax2/src/grammar/items/mod.rs index 8c19aa1795..2567313ab1 100644 --- a/crates/libsyntax2/src/grammar/items/mod.rs +++ b/crates/libsyntax2/src/grammar/items/mod.rs @@ -181,7 +181,16 @@ fn items_without_modifiers(p: &mut Parser) -> Option { MODULE } STRUCT_KW => { - nominal::struct_def(p); + // test struct_items + // struct Foo; + // struct Foo {} + // struct Foo(); + // struct Foo(String, usize); + // struct Foo { + // a: i32, + // b: f32, + // } + nominal::struct_def(p, STRUCT_KW); if p.at(SEMI) { p.err_and_bump( "expected item, found `;`\n\ @@ -190,6 +199,16 @@ fn items_without_modifiers(p: &mut Parser) -> Option { } STRUCT_DEF } + IDENT if p.at_contextual_kw("union") => { + // test union_items + // union Foo {} + // union Foo { + // a: i32, + // b: f32, + // } + nominal::struct_def(p, UNION_KW); + STRUCT_DEF + } ENUM_KW => { nominal::enum_def(p); ENUM_DEF diff --git a/crates/libsyntax2/src/grammar/items/nominal.rs b/crates/libsyntax2/src/grammar/items/nominal.rs index 11c43e371e..8d02ad555a 100644 --- a/crates/libsyntax2/src/grammar/items/nominal.rs +++ b/crates/libsyntax2/src/grammar/items/nominal.rs @@ -1,8 +1,8 @@ use super::*; -pub(super) fn struct_def(p: &mut Parser) { - assert!(p.at(STRUCT_KW)); - p.bump(); +pub(super) fn struct_def(p: &mut Parser, kind: SyntaxKind) { + assert!(p.at(STRUCT_KW) || p.at_contextual_kw("union")); + p.bump_remap(kind); name_r(p, ITEM_RECOVERY_SET); type_params::opt_type_param_list(p); @@ -22,19 +22,23 @@ pub(super) fn struct_def(p: &mut Parser) { } } } - SEMI => { + SEMI if kind == STRUCT_KW => { p.bump(); return; } L_CURLY => named_field_def_list(p), - L_PAREN => { + L_PAREN if kind == STRUCT_KW => { pos_field_list(p); p.expect(SEMI); } - _ => { + _ if kind == STRUCT_KW => { p.error("expected `;`, `{`, or `(`"); return; } + _ => { + p.error("expected `{`"); + return; + } } } diff --git a/crates/libsyntax2/tests/data/parser/inline/0109_struct_items.txt b/crates/libsyntax2/tests/data/parser/inline/0109_struct_items.txt new file mode 100644 index 0000000000..ea016d393d --- /dev/null +++ b/crates/libsyntax2/tests/data/parser/inline/0109_struct_items.txt @@ -0,0 +1,86 @@ +ROOT@[0; 105) + STRUCT_DEF@[0; 11) + STRUCT_KW@[0; 6) + WHITESPACE@[6; 7) + NAME@[7; 10) + IDENT@[7; 10) "Foo" + SEMI@[10; 11) + WHITESPACE@[11; 12) + STRUCT_DEF@[12; 25) + STRUCT_KW@[12; 18) + WHITESPACE@[18; 19) + NAME@[19; 22) + IDENT@[19; 22) "Foo" + WHITESPACE@[22; 23) + NAMED_FIELD_DEF_LIST@[23; 25) + L_CURLY@[23; 24) + R_CURLY@[24; 25) + WHITESPACE@[25; 26) + STRUCT_DEF@[26; 39) + STRUCT_KW@[26; 32) + WHITESPACE@[32; 33) + NAME@[33; 36) + IDENT@[33; 36) "Foo" + POS_FIELD_LIST@[36; 38) + L_PAREN@[36; 37) + R_PAREN@[37; 38) + SEMI@[38; 39) + WHITESPACE@[39; 40) + STRUCT_DEF@[40; 66) + STRUCT_KW@[40; 46) + WHITESPACE@[46; 47) + NAME@[47; 50) + IDENT@[47; 50) "Foo" + POS_FIELD_LIST@[50; 65) + L_PAREN@[50; 51) + POS_FIELD@[51; 57) + PATH_TYPE@[51; 57) + PATH@[51; 57) + PATH_SEGMENT@[51; 57) + NAME_REF@[51; 57) + IDENT@[51; 57) "String" + COMMA@[57; 58) + WHITESPACE@[58; 59) + POS_FIELD@[59; 64) + PATH_TYPE@[59; 64) + PATH@[59; 64) + PATH_SEGMENT@[59; 64) + NAME_REF@[59; 64) + IDENT@[59; 64) "usize" + R_PAREN@[64; 65) + SEMI@[65; 66) + WHITESPACE@[66; 67) + STRUCT_DEF@[67; 105) + STRUCT_KW@[67; 73) + WHITESPACE@[73; 74) + NAME@[74; 77) + IDENT@[74; 77) "Foo" + WHITESPACE@[77; 78) + NAMED_FIELD_DEF_LIST@[78; 105) + L_CURLY@[78; 79) + WHITESPACE@[79; 84) + NAMED_FIELD_DEF@[84; 90) + NAME@[84; 85) + IDENT@[84; 85) "a" + COLON@[85; 86) + WHITESPACE@[86; 87) + PATH_TYPE@[87; 90) + PATH@[87; 90) + PATH_SEGMENT@[87; 90) + NAME_REF@[87; 90) + IDENT@[87; 90) "i32" + COMMA@[90; 91) + WHITESPACE@[91; 96) + NAMED_FIELD_DEF@[96; 102) + NAME@[96; 97) + IDENT@[96; 97) "b" + COLON@[97; 98) + WHITESPACE@[98; 99) + PATH_TYPE@[99; 102) + PATH@[99; 102) + PATH_SEGMENT@[99; 102) + NAME_REF@[99; 102) + IDENT@[99; 102) "f32" + COMMA@[102; 103) + WHITESPACE@[103; 104) + R_CURLY@[104; 105) diff --git a/crates/libsyntax2/tests/data/parser/inline/0110_union_items.txt b/crates/libsyntax2/tests/data/parser/inline/0110_union_items.txt new file mode 100644 index 0000000000..93e8a4e8de --- /dev/null +++ b/crates/libsyntax2/tests/data/parser/inline/0110_union_items.txt @@ -0,0 +1,45 @@ +ROOT@[0; 50) + STRUCT_DEF@[0; 12) + UNION_KW@[0; 5) + WHITESPACE@[5; 6) + NAME@[6; 9) + IDENT@[6; 9) "Foo" + WHITESPACE@[9; 10) + NAMED_FIELD_DEF_LIST@[10; 12) + L_CURLY@[10; 11) + R_CURLY@[11; 12) + WHITESPACE@[12; 13) + STRUCT_DEF@[13; 50) + UNION_KW@[13; 18) + WHITESPACE@[18; 19) + NAME@[19; 22) + IDENT@[19; 22) "Foo" + WHITESPACE@[22; 23) + NAMED_FIELD_DEF_LIST@[23; 50) + L_CURLY@[23; 24) + WHITESPACE@[24; 29) + NAMED_FIELD_DEF@[29; 35) + NAME@[29; 30) + IDENT@[29; 30) "a" + COLON@[30; 31) + WHITESPACE@[31; 32) + PATH_TYPE@[32; 35) + PATH@[32; 35) + PATH_SEGMENT@[32; 35) + NAME_REF@[32; 35) + IDENT@[32; 35) "i32" + COMMA@[35; 36) + WHITESPACE@[36; 41) + NAMED_FIELD_DEF@[41; 47) + NAME@[41; 42) + IDENT@[41; 42) "b" + COLON@[42; 43) + WHITESPACE@[43; 44) + PATH_TYPE@[44; 47) + PATH@[44; 47) + PATH_SEGMENT@[44; 47) + NAME_REF@[44; 47) + IDENT@[44; 47) "f32" + COMMA@[47; 48) + WHITESPACE@[48; 49) + R_CURLY@[49; 50)