From 888157b52eace7a4dbf4138ad48926a78ed1d0e1 Mon Sep 17 00:00:00 2001 From: ironyman Date: Sun, 23 Jun 2019 21:05:50 -0700 Subject: fill_match_arm works with trivial arm --- crates/ra_assists/src/fill_match_arms.rs | 56 ++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/crates/ra_assists/src/fill_match_arms.rs b/crates/ra_assists/src/fill_match_arms.rs index c7a8bce20..a0e0f110f 100644 --- a/crates/ra_assists/src/fill_match_arms.rs +++ b/crates/ra_assists/src/fill_match_arms.rs @@ -8,13 +8,39 @@ use ra_syntax::ast::{self, AstNode}; use crate::{AssistCtx, Assist, AssistId}; +fn is_trivial_arm(arm: &ast::MatchArm) -> bool { + for (i, p) in arm.pats().enumerate() { + if i > 0 { + return false; + } + + match p.kind() { + ast::PatKind::PlaceholderPat(_) => {} + _ => { + return false; + } + }; + } + return true; +} + pub(crate) fn fill_match_arms(mut ctx: AssistCtx) -> Option { let match_expr = ctx.node_at_offset::()?; // We already have some match arms, so we don't provide any assists. + // Unless if there is only one trivial match arm possibly created + // by match postfix complete. Trivial match arm is the catch all arm. match match_expr.match_arm_list() { - Some(arm_list) if arm_list.arms().count() > 0 => { - return None; + Some(arm_list) => { + for (i, a) in arm_list.arms().enumerate() { + if i > 0 { + return None; + } + + if !is_trivial_arm(a) { + return None; + } + } } _ => {} } @@ -228,4 +254,30 @@ mod tests { "match E::X {}", ); } + + #[test] + fn fill_match_arms_trivial_arm() { + check_assist( + fill_match_arms, + r#" + enum E { X, Y } + + fn main() { + match E::X { + <|>_ => {}, + } + } + "#, + r#" + enum E { X, Y } + + fn main() { + match <|>E::X { + E::X => (), + E::Y => (), + } + } + "#, + ); + } } -- cgit v1.2.3 From 3a2a13756f325b1dd8ddd54a0a0b24b99180fb82 Mon Sep 17 00:00:00 2001 From: Changyu Li Date: Tue, 25 Jun 2019 13:14:54 -0700 Subject: Review 1 --- crates/ra_assists/src/fill_match_arms.rs | 35 +++++++++++++++++--------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/crates/ra_assists/src/fill_match_arms.rs b/crates/ra_assists/src/fill_match_arms.rs index a0e0f110f..71b101b40 100644 --- a/crates/ra_assists/src/fill_match_arms.rs +++ b/crates/ra_assists/src/fill_match_arms.rs @@ -1,4 +1,5 @@ use std::fmt::Write; +use itertools::Itertools; use hir::{ AdtDef, FieldSource, HasSource, @@ -9,19 +10,14 @@ use ra_syntax::ast::{self, AstNode}; use crate::{AssistCtx, Assist, AssistId}; fn is_trivial_arm(arm: &ast::MatchArm) -> bool { - for (i, p) in arm.pats().enumerate() { - if i > 0 { - return false; - } - - match p.kind() { - ast::PatKind::PlaceholderPat(_) => {} - _ => { - return false; - } - }; + fn single_pattern(arm: &ast::MatchArm) -> Option { + let (pat,) = arm.pats().collect_tuple()?; + Some(pat.kind()) + } + match single_pattern(arm) { + Some(ast::PatKind::PlaceholderPat(..)) => true, + _ => false, } - return true; } pub(crate) fn fill_match_arms(mut ctx: AssistCtx) -> Option { @@ -32,12 +28,19 @@ pub(crate) fn fill_match_arms(mut ctx: AssistCtx) -> Option { - for (i, a) in arm_list.arms().enumerate() { - if i > 0 { - return None; + let mut arm_iter = arm_list.arms(); + let first = arm_iter.next(); + + match first { + // If there arm list is empty or there is only one trivial arm, then proceed. + Some(arm) if is_trivial_arm(arm) => { + if arm_iter.next() != None { + return None; + } } + None => {} - if !is_trivial_arm(a) { + _ => { return None; } } -- cgit v1.2.3