diff options
-rw-r--r-- | crates/ra_hir/src/expr.rs | 16 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast.rs | 49 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/generated.rs | 35 | ||||
-rw-r--r-- | crates/ra_syntax/src/grammar.ron | 7 | ||||
-rw-r--r-- | crates/ra_syntax/src/grammar/patterns.rs | 26 | ||||
-rw-r--r-- | crates/ra_syntax/src/syntax_kinds/generated.rs | 2 |
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)] | ||
668 | pub struct FieldPat { | ||
669 | pub ident: SmolStr, | ||
670 | // FIXME: could we use a regular reference? | ||
671 | pub pat: TreeArc<Pat>, | ||
672 | } | ||
673 | |||
674 | impl 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 | |||
716 | impl BindPat { | 667 | impl 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)] | ||
864 | pub struct FieldPat { | ||
865 | pub(crate) syntax: SyntaxNode, | ||
866 | } | ||
867 | unsafe impl TransparentNewType for FieldPat { | ||
868 | type Repr = rowan::SyntaxNode<RaTypes>; | ||
869 | } | ||
870 | |||
871 | impl 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 | |||
883 | impl ast::NameOwner for FieldPat {} | ||
884 | impl 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 | ||
883 | impl FieldPatList {} | 912 | impl 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 | ||
141 | fn 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 _ = (); } |
151 | fn placeholder_pat(p: &mut Parser) -> CompletedMarker { | 159 | fn 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" }, |