aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-11-25 13:55:09 +0000
committerAleksey Kladov <[email protected]>2019-11-25 14:50:49 +0000
commite1c0bdaf75f8d88a5c28b3e44def17d91d4f46b3 (patch)
tree15cb5466dd2fab58d1591afc50bd28aeab65359d
parentbe00d74c7b61fb82bdade482e95035a21f9dd736 (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.
-rw-r--r--crates/ra_parser/src/grammar/items.rs10
-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.rs1
-rw-r--r--crates/ra_syntax/src/ast/generated.rs28
-rw-r--r--crates/ra_syntax/src/grammar.ron10
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0068_union_items.txt4
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0035_weird_exprs.txt2
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
3mod consts; 3mod consts;
4mod nominal; 4mod adt;
5mod traits; 5mod traits;
6mod use_item; 6mod use_item;
7 7
8pub(crate) use self::{ 8pub(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
3use super::*; 3use super::*;
4 4
5pub(super) fn struct_def(p: &mut Parser, m: Marker, kind: SyntaxKind) { 5pub(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
11pub(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
17fn 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
47pub(super) fn enum_def(p: &mut Parser, m: Marker) { 56pub(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}
3790impl TypeRef {} 3790impl TypeRef {}
3791#[derive(Debug, Clone, PartialEq, Eq, Hash)] 3791#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3792pub struct UnionDef {
3793 pub(crate) syntax: SyntaxNode,
3794}
3795impl 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}
3813impl ast::VisibilityOwner for UnionDef {}
3814impl ast::NameOwner for UnionDef {}
3815impl ast::TypeParamsOwner for UnionDef {}
3816impl ast::AttrsOwner for UnionDef {}
3817impl ast::DocCommentsOwner for UnionDef {}
3818impl UnionDef {}
3819#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3792pub struct UseItem { 3820pub 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 @@
1SOURCE_FILE@[0; 51) 1SOURCE_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)