diff options
author | Aleksey Kladov <[email protected]> | 2019-11-25 13:55:09 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-11-25 14:50:49 +0000 |
commit | e1c0bdaf75f8d88a5c28b3e44def17d91d4f46b3 (patch) | |
tree | 15cb5466dd2fab58d1591afc50bd28aeab65359d /crates | |
parent | be00d74c7b61fb82bdade482e95035a21f9dd736 (diff) |
Introduce dedicated AST node for union
Although structs and unions have the same syntax and differ only in
the keyword, re-using the single syntax node for both of them leads to
confusion in practice, and propagates further down the hir in an
upleasent way.
Moreover, static and consts also share syntax, but we use different
nodes for them.
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_parser/src/grammar/items.rs | 10 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/items/adt.rs (renamed from crates/ra_parser/src/grammar/items/nominal.rs) | 23 | ||||
-rw-r--r-- | crates/ra_parser/src/syntax_kind/generated.rs | 1 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/generated.rs | 28 | ||||
-rw-r--r-- | crates/ra_syntax/src/grammar.ron | 10 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/inline/ok/0068_union_items.txt | 4 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt | 2 |
7 files changed, 63 insertions, 15 deletions
diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs index 85f7eeb00..630e6ce64 100644 --- a/crates/ra_parser/src/grammar/items.rs +++ b/crates/ra_parser/src/grammar/items.rs | |||
@@ -1,13 +1,13 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | mod consts; | 3 | mod consts; |
4 | mod nominal; | 4 | mod adt; |
5 | mod traits; | 5 | mod traits; |
6 | mod use_item; | 6 | mod use_item; |
7 | 7 | ||
8 | pub(crate) use self::{ | 8 | pub(crate) use self::{ |
9 | expressions::{match_arm_list, record_field_list}, | 9 | expressions::{match_arm_list, record_field_list}, |
10 | nominal::{enum_variant_list, record_field_def_list}, | 10 | adt::{enum_variant_list, record_field_def_list}, |
11 | traits::{impl_item_list, trait_item_list}, | 11 | traits::{impl_item_list, trait_item_list}, |
12 | use_item::use_tree_list, | 12 | use_item::use_tree_list, |
13 | }; | 13 | }; |
@@ -247,7 +247,7 @@ fn items_without_modifiers(p: &mut Parser, m: Marker) -> Result<(), Marker> { | |||
247 | // a: i32, | 247 | // a: i32, |
248 | // b: f32, | 248 | // b: f32, |
249 | // } | 249 | // } |
250 | nominal::struct_def(p, m, T![struct]); | 250 | adt::struct_def(p, m); |
251 | } | 251 | } |
252 | IDENT if p.at_contextual_kw("union") && p.nth(1) == IDENT => { | 252 | IDENT if p.at_contextual_kw("union") && p.nth(1) == IDENT => { |
253 | // test union_items | 253 | // test union_items |
@@ -256,9 +256,9 @@ fn items_without_modifiers(p: &mut Parser, m: Marker) -> Result<(), Marker> { | |||
256 | // a: i32, | 256 | // a: i32, |
257 | // b: f32, | 257 | // b: f32, |
258 | // } | 258 | // } |
259 | nominal::struct_def(p, m, T![union]); | 259 | adt::union_def(p, m); |
260 | } | 260 | } |
261 | T![enum] => nominal::enum_def(p, m), | 261 | T![enum] => adt::enum_def(p, m), |
262 | T![use] => use_item::use_item(p, m), | 262 | T![use] => use_item::use_item(p, m), |
263 | T![const] if (la == IDENT || la == T![_] || la == T![mut]) => consts::const_def(p, m), | 263 | T![const] if (la == IDENT || la == T![_] || la == T![mut]) => consts::const_def(p, m), |
264 | T![static] => consts::static_def(p, m), | 264 | T![static] => consts::static_def(p, m), |
diff --git a/crates/ra_parser/src/grammar/items/nominal.rs b/crates/ra_parser/src/grammar/items/adt.rs index 9d8fb8486..c777bc9d0 100644 --- a/crates/ra_parser/src/grammar/items/nominal.rs +++ b/crates/ra_parser/src/grammar/items/adt.rs | |||
@@ -2,10 +2,19 @@ | |||
2 | 2 | ||
3 | use super::*; | 3 | use super::*; |
4 | 4 | ||
5 | pub(super) fn struct_def(p: &mut Parser, m: Marker, kind: SyntaxKind) { | 5 | pub(super) fn struct_def(p: &mut Parser, m: Marker) { |
6 | assert!(p.at(T![struct]) || p.at_contextual_kw("union")); | 6 | assert!(p.at(T![struct])); |
7 | p.bump_remap(kind); | 7 | p.bump(T![struct]); |
8 | struct_or_union(p, m, T![struct], STRUCT_DEF); | ||
9 | } | ||
10 | |||
11 | pub(super) fn union_def(p: &mut Parser, m: Marker) { | ||
12 | assert!(p.at_contextual_kw("union")); | ||
13 | p.bump_remap(T![union]); | ||
14 | struct_or_union(p, m, T![union], UNION_DEF); | ||
15 | } | ||
8 | 16 | ||
17 | fn struct_or_union(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) { | ||
9 | name_r(p, ITEM_RECOVERY_SET); | 18 | name_r(p, ITEM_RECOVERY_SET); |
10 | type_params::opt_type_param_list(p); | 19 | type_params::opt_type_param_list(p); |
11 | match p.current() { | 20 | match p.current() { |
@@ -22,11 +31,11 @@ pub(super) fn struct_def(p: &mut Parser, m: Marker, kind: SyntaxKind) { | |||
22 | } | 31 | } |
23 | } | 32 | } |
24 | } | 33 | } |
25 | T![;] if kind == T![struct] => { | 34 | T![;] if kw == T![struct] => { |
26 | p.bump(T![;]); | 35 | p.bump(T![;]); |
27 | } | 36 | } |
28 | T!['{'] => record_field_def_list(p), | 37 | T!['{'] => record_field_def_list(p), |
29 | T!['('] if kind == T![struct] => { | 38 | T!['('] if kw == T![struct] => { |
30 | tuple_field_def_list(p); | 39 | tuple_field_def_list(p); |
31 | // test tuple_struct_where | 40 | // test tuple_struct_where |
32 | // struct Test<T>(T) where T: Clone; | 41 | // struct Test<T>(T) where T: Clone; |
@@ -34,14 +43,14 @@ pub(super) fn struct_def(p: &mut Parser, m: Marker, kind: SyntaxKind) { | |||
34 | type_params::opt_where_clause(p); | 43 | type_params::opt_where_clause(p); |
35 | p.expect(T![;]); | 44 | p.expect(T![;]); |
36 | } | 45 | } |
37 | _ if kind == T![struct] => { | 46 | _ if kw == T![struct] => { |
38 | p.error("expected `;`, `{`, or `(`"); | 47 | p.error("expected `;`, `{`, or `(`"); |
39 | } | 48 | } |
40 | _ => { | 49 | _ => { |
41 | p.error("expected `{`"); | 50 | p.error("expected `{`"); |
42 | } | 51 | } |
43 | } | 52 | } |
44 | m.complete(p, STRUCT_DEF); | 53 | m.complete(p, def); |
45 | } | 54 | } |
46 | 55 | ||
47 | pub(super) fn enum_def(p: &mut Parser, m: Marker) { | 56 | pub(super) fn enum_def(p: &mut Parser, m: Marker) { |
diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs index 96b5bce88..fe0fcdb33 100644 --- a/crates/ra_parser/src/syntax_kind/generated.rs +++ b/crates/ra_parser/src/syntax_kind/generated.rs | |||
@@ -122,6 +122,7 @@ pub enum SyntaxKind { | |||
122 | R_DOLLAR, | 122 | R_DOLLAR, |
123 | SOURCE_FILE, | 123 | SOURCE_FILE, |
124 | STRUCT_DEF, | 124 | STRUCT_DEF, |
125 | UNION_DEF, | ||
125 | ENUM_DEF, | 126 | ENUM_DEF, |
126 | FN_DEF, | 127 | FN_DEF, |
127 | RET_TYPE, | 128 | RET_TYPE, |
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index de506d7cd..1a03ae56c 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs | |||
@@ -3789,6 +3789,34 @@ impl AstNode for TypeRef { | |||
3789 | } | 3789 | } |
3790 | impl TypeRef {} | 3790 | impl TypeRef {} |
3791 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 3791 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
3792 | pub struct UnionDef { | ||
3793 | pub(crate) syntax: SyntaxNode, | ||
3794 | } | ||
3795 | impl AstNode for UnionDef { | ||
3796 | fn can_cast(kind: SyntaxKind) -> bool { | ||
3797 | match kind { | ||
3798 | UNION_DEF => true, | ||
3799 | _ => false, | ||
3800 | } | ||
3801 | } | ||
3802 | fn cast(syntax: SyntaxNode) -> Option<Self> { | ||
3803 | if Self::can_cast(syntax.kind()) { | ||
3804 | Some(Self { syntax }) | ||
3805 | } else { | ||
3806 | None | ||
3807 | } | ||
3808 | } | ||
3809 | fn syntax(&self) -> &SyntaxNode { | ||
3810 | &self.syntax | ||
3811 | } | ||
3812 | } | ||
3813 | impl ast::VisibilityOwner for UnionDef {} | ||
3814 | impl ast::NameOwner for UnionDef {} | ||
3815 | impl ast::TypeParamsOwner for UnionDef {} | ||
3816 | impl ast::AttrsOwner for UnionDef {} | ||
3817 | impl ast::DocCommentsOwner for UnionDef {} | ||
3818 | impl UnionDef {} | ||
3819 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
3792 | pub struct UseItem { | 3820 | pub struct UseItem { |
3793 | pub(crate) syntax: SyntaxNode, | 3821 | pub(crate) syntax: SyntaxNode, |
3794 | } | 3822 | } |
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 88d1dc109..c16bed891 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron | |||
@@ -126,6 +126,7 @@ Grammar( | |||
126 | "SOURCE_FILE", | 126 | "SOURCE_FILE", |
127 | 127 | ||
128 | "STRUCT_DEF", | 128 | "STRUCT_DEF", |
129 | "UNION_DEF", | ||
129 | "ENUM_DEF", | 130 | "ENUM_DEF", |
130 | "FN_DEF", | 131 | "FN_DEF", |
131 | "RET_TYPE", | 132 | "RET_TYPE", |
@@ -285,6 +286,15 @@ Grammar( | |||
285 | "DocCommentsOwner" | 286 | "DocCommentsOwner" |
286 | ] | 287 | ] |
287 | ), | 288 | ), |
289 | "UnionDef": ( | ||
290 | traits: [ | ||
291 | "VisibilityOwner", | ||
292 | "NameOwner", | ||
293 | "TypeParamsOwner", | ||
294 | "AttrsOwner", | ||
295 | "DocCommentsOwner" | ||
296 | ] | ||
297 | ), | ||
288 | "RecordFieldDefList": (collections: [("fields", "RecordFieldDef")]), | 298 | "RecordFieldDefList": (collections: [("fields", "RecordFieldDef")]), |
289 | "RecordFieldDef": ( | 299 | "RecordFieldDef": ( |
290 | traits: [ | 300 | traits: [ |
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0068_union_items.txt b/crates/ra_syntax/test_data/parser/inline/ok/0068_union_items.txt index f9ace02ee..9d7982684 100644 --- a/crates/ra_syntax/test_data/parser/inline/ok/0068_union_items.txt +++ b/crates/ra_syntax/test_data/parser/inline/ok/0068_union_items.txt | |||
@@ -1,5 +1,5 @@ | |||
1 | SOURCE_FILE@[0; 51) | 1 | SOURCE_FILE@[0; 51) |
2 | STRUCT_DEF@[0; 12) | 2 | UNION_DEF@[0; 12) |
3 | UNION_KW@[0; 5) "union" | 3 | UNION_KW@[0; 5) "union" |
4 | WHITESPACE@[5; 6) " " | 4 | WHITESPACE@[5; 6) " " |
5 | NAME@[6; 9) | 5 | NAME@[6; 9) |
@@ -9,7 +9,7 @@ SOURCE_FILE@[0; 51) | |||
9 | L_CURLY@[10; 11) "{" | 9 | L_CURLY@[10; 11) "{" |
10 | R_CURLY@[11; 12) "}" | 10 | R_CURLY@[11; 12) "}" |
11 | WHITESPACE@[12; 13) "\n" | 11 | WHITESPACE@[12; 13) "\n" |
12 | STRUCT_DEF@[13; 50) | 12 | UNION_DEF@[13; 50) |
13 | UNION_KW@[13; 18) "union" | 13 | UNION_KW@[13; 18) "union" |
14 | WHITESPACE@[18; 19) " " | 14 | WHITESPACE@[18; 19) " " |
15 | NAME@[19; 22) | 15 | NAME@[19; 22) |
diff --git a/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt b/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt index 3260cc589..90538b90d 100644 --- a/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt +++ b/crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt | |||
@@ -1592,7 +1592,7 @@ SOURCE_FILE@[0; 3813) | |||
1592 | BLOCK@[2845; 2906) | 1592 | BLOCK@[2845; 2906) |
1593 | L_CURLY@[2845; 2846) "{" | 1593 | L_CURLY@[2845; 2846) "{" |
1594 | WHITESPACE@[2846; 2851) "\n " | 1594 | WHITESPACE@[2846; 2851) "\n " |
1595 | STRUCT_DEF@[2851; 2904) | 1595 | UNION_DEF@[2851; 2904) |
1596 | UNION_KW@[2851; 2856) "union" | 1596 | UNION_KW@[2851; 2856) "union" |
1597 | WHITESPACE@[2856; 2857) " " | 1597 | WHITESPACE@[2856; 2857) " " |
1598 | NAME@[2857; 2862) | 1598 | NAME@[2857; 2862) |