From f1afc933530a87bd0cc7b25726c9a7fff3f3e007 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 9 Feb 2019 19:07:35 +0100 Subject: Fix handling of literal patterns Wrap them in a LiteralPat node so they can be distinguished from literal expressions. --- crates/ra_syntax/src/ast/generated.rs | 37 ++++++++++++++++++++++- crates/ra_syntax/src/grammar.ron | 3 ++ crates/ra_syntax/src/grammar/patterns.rs | 41 ++++++++++++++++---------- crates/ra_syntax/src/syntax_kinds/generated.rs | 2 ++ 4 files changed, 67 insertions(+), 16 deletions(-) (limited to 'crates/ra_syntax/src') diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 60314d245..256277609 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs @@ -1821,6 +1821,38 @@ impl LiteralExpr { impl LiteralExpr {} +// LiteralPat +#[derive(Debug, PartialEq, Eq, Hash)] +#[repr(transparent)] +pub struct LiteralPat { + pub(crate) syntax: SyntaxNode, +} +unsafe impl TransparentNewType for LiteralPat { + type Repr = rowan::SyntaxNode; +} + +impl AstNode for LiteralPat { + fn cast(syntax: &SyntaxNode) -> Option<&Self> { + match syntax.kind() { + LITERAL_PAT => Some(LiteralPat::from_repr(syntax.into_repr())), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} + +impl ToOwned for LiteralPat { + type Owned = TreeArc; + fn to_owned(&self) -> TreeArc { TreeArc::cast(self.syntax.to_owned()) } +} + + +impl LiteralPat { + pub fn literal(&self) -> Option<&Literal> { + super::child_opt(self) + } +} + // LoopExpr #[derive(Debug, PartialEq, Eq, Hash)] #[repr(transparent)] @@ -2594,6 +2626,7 @@ pub enum PatKind<'a> { TuplePat(&'a TuplePat), SlicePat(&'a SlicePat), RangePat(&'a RangePat), + LiteralPat(&'a LiteralPat), } impl AstNode for Pat { @@ -2607,7 +2640,8 @@ impl AstNode for Pat { | TUPLE_STRUCT_PAT | TUPLE_PAT | SLICE_PAT - | RANGE_PAT => Some(Pat::from_repr(syntax.into_repr())), + | RANGE_PAT + | LITERAL_PAT => Some(Pat::from_repr(syntax.into_repr())), _ => None, } } @@ -2631,6 +2665,7 @@ impl Pat { TUPLE_PAT => PatKind::TuplePat(TuplePat::cast(&self.syntax).unwrap()), SLICE_PAT => PatKind::SlicePat(SlicePat::cast(&self.syntax).unwrap()), RANGE_PAT => PatKind::RangePat(RangePat::cast(&self.syntax).unwrap()), + LITERAL_PAT => PatKind::LiteralPat(LiteralPat::cast(&self.syntax).unwrap()), _ => unreachable!(), } } diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 046db5885..d428bc595 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron @@ -161,6 +161,7 @@ Grammar( "TUPLE_PAT", "SLICE_PAT", "RANGE_PAT", + "LITERAL_PAT", // atoms "TUPLE_EXPR", @@ -524,6 +525,7 @@ Grammar( "TuplePat": ( collections: [["args", "Pat"]] ), "SlicePat": (), "RangePat": (), + "LiteralPat": (options: ["Literal"]), "Pat": ( enum: [ @@ -536,6 +538,7 @@ Grammar( "TuplePat", "SlicePat", "RangePat", + "LiteralPat", ], ), diff --git a/crates/ra_syntax/src/grammar/patterns.rs b/crates/ra_syntax/src/grammar/patterns.rs index f3f400ae0..9d7da639d 100644 --- a/crates/ra_syntax/src/grammar/patterns.rs +++ b/crates/ra_syntax/src/grammar/patterns.rs @@ -43,21 +43,8 @@ fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option { return Some(path_pat(p)); } - // test literal_pattern - // fn main() { - // match () { - // -1 => (), - // 92 => (), - // 'c' => (), - // "hello" => (), - // } - // } - if p.at(MINUS) && (p.nth(1) == INT_NUMBER || p.nth(1) == FLOAT_NUMBER) { - p.bump(); - } - - if let Some(m) = expressions::literal(p) { - return Some(m); + if is_literal_pat_start(p) { + return Some(literal_pat(p)); } let m = match la0 { @@ -73,6 +60,30 @@ fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option { Some(m) } +fn is_literal_pat_start(p: &mut Parser) -> bool { + p.at(MINUS) && (p.nth(1) == INT_NUMBER || p.nth(1) == FLOAT_NUMBER) + || p.at_ts(expressions::LITERAL_FIRST) +} + +// test literal_pattern +// fn main() { +// match () { +// -1 => (), +// 92 => (), +// 'c' => (), +// "hello" => (), +// } +// } +fn literal_pat(p: &mut Parser) -> CompletedMarker { + assert!(is_literal_pat_start(p)); + let m = p.start(); + if p.at(MINUS) { + p.bump(); + } + expressions::literal(p); + m.complete(p, LITERAL_PAT) +} + // test path_part // fn foo() { // let foo::Bar = (); diff --git a/crates/ra_syntax/src/syntax_kinds/generated.rs b/crates/ra_syntax/src/syntax_kinds/generated.rs index fea513458..266b95bbb 100644 --- a/crates/ra_syntax/src/syntax_kinds/generated.rs +++ b/crates/ra_syntax/src/syntax_kinds/generated.rs @@ -157,6 +157,7 @@ pub enum SyntaxKind { TUPLE_PAT, SLICE_PAT, RANGE_PAT, + LITERAL_PAT, TUPLE_EXPR, ARRAY_EXPR, PAREN_EXPR, @@ -493,6 +494,7 @@ impl SyntaxKind { TUPLE_PAT => &SyntaxInfo { name: "TUPLE_PAT" }, SLICE_PAT => &SyntaxInfo { name: "SLICE_PAT" }, RANGE_PAT => &SyntaxInfo { name: "RANGE_PAT" }, + LITERAL_PAT => &SyntaxInfo { name: "LITERAL_PAT" }, TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" }, ARRAY_EXPR => &SyntaxInfo { name: "ARRAY_EXPR" }, PAREN_EXPR => &SyntaxInfo { name: "PAREN_EXPR" }, -- cgit v1.2.3