aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorMarcus Klaas de Vries <[email protected]>2019-01-18 13:52:31 +0000
committerAleksey Kladov <[email protected]>2019-01-19 12:37:26 +0000
commitf9a6050034b2ab4358d8a46dd8432de41cebdf0c (patch)
tree9de2701b95000fc0a089213bebf8b88924ff61c4 /crates
parentd2769837f1f9c94b977bd6022090f8e5cd02410c (diff)
Move parsing of field pattern lists to the parser (where it belongs)
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/expr.rs16
-rw-r--r--crates/ra_syntax/src/ast.rs49
-rw-r--r--crates/ra_syntax/src/ast/generated.rs35
-rw-r--r--crates/ra_syntax/src/grammar.ron7
-rw-r--r--crates/ra_syntax/src/grammar/patterns.rs26
-rw-r--r--crates/ra_syntax/src/syntax_kinds/generated.rs2
6 files changed, 71 insertions, 64 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index 1d0beb148..b52f7591d 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -857,11 +857,19 @@ impl ExprCollector {
857 let fields = p 857 let fields = p
858 .field_pat_list() 858 .field_pat_list()
859 .expect("every struct should have a field list") 859 .expect("every struct should have a field list")
860 .field_pats() 860 .pats()
861 .into_iter()
862 .map(|f| { 861 .map(|f| {
863 let name = Name::new(f.ident); 862 let ast_pat = f.pat().expect("field pat always contains a pattern");
864 let pat = self.collect_pat(&*f.pat); 863 let pat = self.collect_pat(ast_pat);
864 let name = f
865 .name()
866 .unwrap_or_else(|| {
867 ast::BindPat::cast(ast_pat.syntax())
868 .expect("field pat without label is a bind pat")
869 .name()
870 .expect("bind pat has a name")
871 })
872 .as_name();
865 FieldPat { name, pat } 873 FieldPat { name, pat }
866 }) 874 })
867 .collect(); 875 .collect();
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
index 0ee9ef199..5a5f56057 100644
--- a/crates/ra_syntax/src/ast.rs
+++ b/crates/ra_syntax/src/ast.rs
@@ -664,55 +664,6 @@ impl LiteralExpr {
664 } 664 }
665} 665}
666 666
667#[derive(Clone, Debug, PartialEq, Eq, Hash)]
668pub struct FieldPat {
669 pub ident: SmolStr,
670 // FIXME: could we use a regular reference?
671 pub pat: TreeArc<Pat>,
672}
673
674impl FieldPatList {
675 // TODO: try returning an iterator?
676 // FIXME: shouldnt the parser do this? :o
677 pub fn field_pats(&self) -> Vec<FieldPat> {
678 let mut child_iter = self.syntax().children();
679 let mut pats = Vec::new();
680
681 while let Some(node) = child_iter.next() {
682 let kind = node.kind();
683 if kind != IDENT && kind != BIND_PAT {
684 continue;
685 }
686
687 let ident = if let Some(text) = node.leaf_text() {
688 text.clone()
689 } else {
690 SmolStr::new(node.text().to_string())
691 };
692 let mut pat = Pat::cast(node).map(AstNode::to_owned);
693
694 // get pat
695 while let Some(node) = child_iter.next() {
696 if node.kind() == COMMA {
697 break;
698 }
699
700 if let Some(p) = Pat::cast(node) {
701 pat = Some(p.to_owned());
702 }
703 }
704
705 let field_pat = FieldPat {
706 ident: ident,
707 pat: pat.unwrap(),
708 };
709 pats.push(field_pat);
710 }
711
712 pats
713 }
714}
715
716impl BindPat { 667impl BindPat {
717 pub fn is_mutable(&self) -> bool { 668 pub fn is_mutable(&self) -> bool {
718 self.syntax().children().any(|n| n.kind() == MUT_KW) 669 self.syntax().children().any(|n| n.kind() == MUT_KW)
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
index ead0f1293..23a573d74 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -858,6 +858,35 @@ impl FieldExpr {
858 } 858 }
859} 859}
860 860
861// FieldPat
862#[derive(Debug, PartialEq, Eq, Hash)]
863#[repr(transparent)]
864pub struct FieldPat {
865 pub(crate) syntax: SyntaxNode,
866}
867unsafe impl TransparentNewType for FieldPat {
868 type Repr = rowan::SyntaxNode<RaTypes>;
869}
870
871impl AstNode for FieldPat {
872 fn cast(syntax: &SyntaxNode) -> Option<&Self> {
873 match syntax.kind() {
874 FIELD_PAT => Some(FieldPat::from_repr(syntax.into_repr())),
875 _ => None,
876 }
877 }
878 fn syntax(&self) -> &SyntaxNode { &self.syntax }
879 fn to_owned(&self) -> TreeArc<FieldPat> { TreeArc::cast(self.syntax.to_owned()) }
880}
881
882
883impl ast::NameOwner for FieldPat {}
884impl FieldPat {
885 pub fn pat(&self) -> Option<&Pat> {
886 super::child_opt(self)
887 }
888}
889
861// FieldPatList 890// FieldPatList
862#[derive(Debug, PartialEq, Eq, Hash)] 891#[derive(Debug, PartialEq, Eq, Hash)]
863#[repr(transparent)] 892#[repr(transparent)]
@@ -880,7 +909,11 @@ impl AstNode for FieldPatList {
880} 909}
881 910
882 911
883impl FieldPatList {} 912impl FieldPatList {
913 pub fn pats(&self) -> impl Iterator<Item = &FieldPat> {
914 super::children(self)
915 }
916}
884 917
885// FloatNumber 918// FloatNumber
886#[derive(Debug, PartialEq, Eq, Hash)] 919#[derive(Debug, PartialEq, Eq, Hash)]
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron
index d58e0dd35..d8c1ae538 100644
--- a/crates/ra_syntax/src/grammar.ron
+++ b/crates/ra_syntax/src/grammar.ron
@@ -154,6 +154,7 @@ Grammar(
154 "PATH_PAT", 154 "PATH_PAT",
155 "STRUCT_PAT", 155 "STRUCT_PAT",
156 "FIELD_PAT_LIST", 156 "FIELD_PAT_LIST",
157 "FIELD_PAT",
157 "TUPLE_STRUCT_PAT", 158 "TUPLE_STRUCT_PAT",
158 "TUPLE_PAT", 159 "TUPLE_PAT",
159 "SLICE_PAT", 160 "SLICE_PAT",
@@ -495,7 +496,11 @@ Grammar(
495 "PlaceholderPat": (), 496 "PlaceholderPat": (),
496 "PathPat": ( options: [ "Path" ] ), 497 "PathPat": ( options: [ "Path" ] ),
497 "StructPat": ( options: ["FieldPatList", "Path"] ), 498 "StructPat": ( options: ["FieldPatList", "Path"] ),
498 "FieldPatList": (), 499 "FieldPatList": ( collections: [["pats", "FieldPat"]] ),
500 "FieldPat": (
501 traits: ["NameOwner"],
502 options: ["Pat"]
503 ),
499 "TupleStructPat": ( 504 "TupleStructPat": (
500 options: ["Path"], 505 options: ["Path"],
501 collections: [["args", "Pat"]], 506 collections: [["args", "Pat"]],
diff --git a/crates/ra_syntax/src/grammar/patterns.rs b/crates/ra_syntax/src/grammar/patterns.rs
index 7820c4e02..ff9d94f8a 100644
--- a/crates/ra_syntax/src/grammar/patterns.rs
+++ b/crates/ra_syntax/src/grammar/patterns.rs
@@ -128,15 +128,7 @@ fn field_pat_list(p: &mut Parser) {
128 while !p.at(EOF) && !p.at(R_CURLY) { 128 while !p.at(EOF) && !p.at(R_CURLY) {
129 match p.current() { 129 match p.current() {
130 DOTDOT => p.bump(), 130 DOTDOT => p.bump(),
131 IDENT if p.nth(1) == COLON => { 131 _ => field_pat(p),
132 p.bump();
133 p.bump();
134 pattern(p);
135 }
136 L_CURLY => error_block(p, "expected ident"),
137 _ => {
138 bind_pat(p, false);
139 }
140 } 132 }
141 if !p.at(R_CURLY) { 133 if !p.at(R_CURLY) {
142 p.expect(COMMA); 134 p.expect(COMMA);
@@ -146,6 +138,22 @@ fn field_pat_list(p: &mut Parser) {
146 m.complete(p, FIELD_PAT_LIST); 138 m.complete(p, FIELD_PAT_LIST);
147} 139}
148 140
141fn field_pat(p: &mut Parser) {
142 let m = p.start();
143 match p.current() {
144 IDENT if p.nth(1) == COLON => {
145 name(p);
146 p.bump();
147 pattern(p);
148 }
149 L_CURLY => error_block(p, "expected ident"),
150 _ => {
151 bind_pat(p, false);
152 }
153 }
154 m.complete(p, FIELD_PAT);
155}
156
149// test placeholder_pat 157// test placeholder_pat
150// fn main() { let _ = (); } 158// fn main() { let _ = (); }
151fn placeholder_pat(p: &mut Parser) -> CompletedMarker { 159fn placeholder_pat(p: &mut Parser) -> CompletedMarker {
diff --git a/crates/ra_syntax/src/syntax_kinds/generated.rs b/crates/ra_syntax/src/syntax_kinds/generated.rs
index 830fac9f4..06faf7557 100644
--- a/crates/ra_syntax/src/syntax_kinds/generated.rs
+++ b/crates/ra_syntax/src/syntax_kinds/generated.rs
@@ -152,6 +152,7 @@ pub enum SyntaxKind {
152 PATH_PAT, 152 PATH_PAT,
153 STRUCT_PAT, 153 STRUCT_PAT,
154 FIELD_PAT_LIST, 154 FIELD_PAT_LIST,
155 FIELD_PAT,
155 TUPLE_STRUCT_PAT, 156 TUPLE_STRUCT_PAT,
156 TUPLE_PAT, 157 TUPLE_PAT,
157 SLICE_PAT, 158 SLICE_PAT,
@@ -414,6 +415,7 @@ impl SyntaxKind {
414 PATH_PAT => &SyntaxInfo { name: "PATH_PAT" }, 415 PATH_PAT => &SyntaxInfo { name: "PATH_PAT" },
415 STRUCT_PAT => &SyntaxInfo { name: "STRUCT_PAT" }, 416 STRUCT_PAT => &SyntaxInfo { name: "STRUCT_PAT" },
416 FIELD_PAT_LIST => &SyntaxInfo { name: "FIELD_PAT_LIST" }, 417 FIELD_PAT_LIST => &SyntaxInfo { name: "FIELD_PAT_LIST" },
418 FIELD_PAT => &SyntaxInfo { name: "FIELD_PAT" },
417 TUPLE_STRUCT_PAT => &SyntaxInfo { name: "TUPLE_STRUCT_PAT" }, 419 TUPLE_STRUCT_PAT => &SyntaxInfo { name: "TUPLE_STRUCT_PAT" },
418 TUPLE_PAT => &SyntaxInfo { name: "TUPLE_PAT" }, 420 TUPLE_PAT => &SyntaxInfo { name: "TUPLE_PAT" },
419 SLICE_PAT => &SyntaxInfo { name: "SLICE_PAT" }, 421 SLICE_PAT => &SyntaxInfo { name: "SLICE_PAT" },