From 3d2490ca97a038e97678f55a008627b4a395a8f7 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 1 Jul 2021 21:10:45 +0200 Subject: [PATCH 1/2] Simplify --- .../src/handlers/merge_match_arms.rs | 217 +++++++++--------- 1 file changed, 108 insertions(+), 109 deletions(-) diff --git a/crates/ide_assists/src/handlers/merge_match_arms.rs b/crates/ide_assists/src/handlers/merge_match_arms.rs index 9bf076cb9a49..5c6bb986b91c 100644 --- a/crates/ide_assists/src/handlers/merge_match_arms.rs +++ b/crates/ide_assists/src/handlers/merge_match_arms.rs @@ -10,7 +10,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists, TextRange}; // Assist: merge_match_arms // -// Merges identical match arms. +// Merges the current match arm with the following if their bodies are identical. // // ``` // enum Action { Move { distance: u32 }, Stop } @@ -44,14 +44,11 @@ pub(crate) fn merge_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option // We check if the following match arms match this one. We could, but don't, // compare to the previous match arm as well. let arms_to_merge = successors(Some(current_arm), |it| neighbor(it, Direction::Next)) - .take_while(|arm| { - if arm.guard().is_some() { - return false; - } - match arm.expr() { - Some(expr) => expr.syntax().text() == current_expr.syntax().text(), - None => false, + .take_while(|arm| match arm.expr() { + Some(expr) if arm.guard().is_none() => { + expr.syntax().text() == current_expr.syntax().text() } + _ => false, }) .collect::>(); @@ -77,10 +74,12 @@ pub(crate) fn merge_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option let arm = format!("{} => {}", pats, current_expr.syntax().text()); - let start = arms_to_merge.first().unwrap().syntax().text_range().start(); - let end = arms_to_merge.last().unwrap().syntax().text_range().end(); + if let [first, .., last] = &*arms_to_merge { + let start = first.syntax().text_range().start(); + let end = last.syntax().text_range().end(); - edit.replace(TextRange::new(start, end), arm); + edit.replace(TextRange::new(start, end), arm); + } }, ) } @@ -100,30 +99,30 @@ mod tests { check_assist( merge_match_arms, r#" - #[derive(Debug)] - enum X { A, B, C } +#[derive(Debug)] +enum X { A, B, C } - fn main() { - let x = X::A; - let y = match x { - X::A => { 1i32$0 } - X::B => { 1i32 } - X::C => { 2i32 } - } - } - "#, +fn main() { + let x = X::A; + let y = match x { + X::A => { 1i32$0 } + X::B => { 1i32 } + X::C => { 2i32 } + } +} +"#, r#" - #[derive(Debug)] - enum X { A, B, C } +#[derive(Debug)] +enum X { A, B, C } - fn main() { - let x = X::A; - let y = match x { - X::A | X::B => { 1i32 } - X::C => { 2i32 } - } - } - "#, +fn main() { + let x = X::A; + let y = match x { + X::A | X::B => { 1i32 } + X::C => { 2i32 } + } +} +"#, ); } @@ -132,30 +131,30 @@ mod tests { check_assist( merge_match_arms, r#" - #[derive(Debug)] - enum X { A, B, C, D, E } +#[derive(Debug)] +enum X { A, B, C, D, E } - fn main() { - let x = X::A; - let y = match x { - X::A | X::B => {$0 1i32 }, - X::C | X::D => { 1i32 }, - X::E => { 2i32 }, - } - } - "#, +fn main() { + let x = X::A; + let y = match x { + X::A | X::B => {$0 1i32 }, + X::C | X::D => { 1i32 }, + X::E => { 2i32 }, + } +} +"#, r#" - #[derive(Debug)] - enum X { A, B, C, D, E } +#[derive(Debug)] +enum X { A, B, C, D, E } - fn main() { - let x = X::A; - let y = match x { - X::A | X::B | X::C | X::D => { 1i32 }, - X::E => { 2i32 }, - } - } - "#, +fn main() { + let x = X::A; + let y = match x { + X::A | X::B | X::C | X::D => { 1i32 }, + X::E => { 2i32 }, + } +} +"#, ); } @@ -164,30 +163,30 @@ mod tests { check_assist( merge_match_arms, r#" - #[derive(Debug)] - enum X { A, B, C, D, E } +#[derive(Debug)] +enum X { A, B, C, D, E } - fn main() { - let x = X::A; - let y = match x { - X::A => { 1i32 }, - X::B => { 2i$032 }, - _ => { 2i32 } - } - } - "#, +fn main() { + let x = X::A; + let y = match x { + X::A => { 1i32 }, + X::B => { 2i$032 }, + _ => { 2i32 } + } +} +"#, r#" - #[derive(Debug)] - enum X { A, B, C, D, E } +#[derive(Debug)] +enum X { A, B, C, D, E } - fn main() { - let x = X::A; - let y = match x { - X::A => { 1i32 }, - _ => { 2i32 } - } - } - "#, +fn main() { + let x = X::A; + let y = match x { + X::A => { 1i32 }, + _ => { 2i32 } + } +} +"#, ); } @@ -196,29 +195,29 @@ mod tests { check_assist( merge_match_arms, r#" - enum X { A, B, C, D, E } +enum X { A, B, C, D, E } - fn main() { - match X::A { - X::A$0 => 92, - X::B => 92, - X::C => 92, - X::D => 62, - _ => panic!(), - } - } - "#, +fn main() { + match X::A { + X::A$0 => 92, + X::B => 92, + X::C => 92, + X::D => 62, + _ => panic!(), + } +} +"#, r#" - enum X { A, B, C, D, E } +enum X { A, B, C, D, E } - fn main() { - match X::A { - X::A | X::B | X::C => 92, - X::D => 62, - _ => panic!(), - } - } - "#, +fn main() { + match X::A { + X::A | X::B | X::C => 92, + X::D => 62, + _ => panic!(), + } +} +"#, ) } @@ -227,22 +226,22 @@ mod tests { check_assist_not_applicable( merge_match_arms, r#" - #[derive(Debug)] - enum X { - A(i32), - B, - C - } +#[derive(Debug)] +enum X { + A(i32), + B, + C +} - fn main() { - let x = X::A; - let y = match x { - X::A(a) if a > 5 => { $01i32 }, - X::B => { 1i32 }, - X::C => { 2i32 } - } - } - "#, +fn main() { + let x = X::A; + let y = match x { + X::A(a) if a > 5 => { $01i32 }, + X::B => { 1i32 }, + X::C => { 2i32 } + } +} +"#, ); } } From 7c8ef301cabbbd74eba5342b7c5bb3a880869428 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 1 Jul 2021 21:32:35 +0200 Subject: [PATCH 2/2] Add ModuleOrItem guess to import granularity guessing --- crates/ide_db/src/helpers/insert_use.rs | 18 ++++++++++++------ crates/ide_db/src/helpers/insert_use/tests.rs | 15 +++++++++++++-- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/crates/ide_db/src/helpers/insert_use.rs b/crates/ide_db/src/helpers/insert_use.rs index e6b4832e7db5..226b9f8e9cbe 100644 --- a/crates/ide_db/src/helpers/insert_use.rs +++ b/crates/ide_db/src/helpers/insert_use.rs @@ -145,14 +145,18 @@ impl ImportScope { let prefix_c = prev_prefix.qualifiers().count(); let curr_c = curr_path.qualifiers().count() - prefix_c; let prev_c = prev_path.qualifiers().count() - prefix_c; - if curr_c <= 1 || prev_c <= 1 { - // Same prefix but no use tree lists so this has to be of item style. - break ImportGranularityGuess::Item; // this overwrites CrateOrModule, technically the file doesn't adhere to anything here. + if curr_c == 1 && prev_c == 1 { + // Same prefix, only differing in the last segment and no use tree lists so this has to be of item style. + break ImportGranularityGuess::Item; + } else { + // Same prefix and no use tree list but differs in more than one segment at the end. This might be module style still. + res = ImportGranularityGuess::ModuleOrItem; } + } else { + // Same prefix with item tree lists, has to be module style as it + // can't be crate style since the trees wouldn't share a prefix then. + break ImportGranularityGuess::Module; } - // Same prefix with item tree lists, has to be module style as it - // can't be crate style since the trees wouldn't share a prefix then. - break ImportGranularityGuess::Module; } } } @@ -168,6 +172,7 @@ enum ImportGranularityGuess { Unknown, Item, Module, + ModuleOrItem, Crate, CrateOrModule, } @@ -186,6 +191,7 @@ pub fn insert_use<'a>(scope: &ImportScope, path: ast::Path, cfg: &InsertUseConfi ImportGranularityGuess::Unknown => mb, ImportGranularityGuess::Item => None, ImportGranularityGuess::Module => Some(MergeBehavior::Module), + ImportGranularityGuess::ModuleOrItem => mb.and(Some(MergeBehavior::Module)), ImportGranularityGuess::Crate => Some(MergeBehavior::Crate), ImportGranularityGuess::CrateOrModule => mb.or(Some(MergeBehavior::Crate)), }; diff --git a/crates/ide_db/src/helpers/insert_use/tests.rs b/crates/ide_db/src/helpers/insert_use/tests.rs index 01894630a8f3..2e0153a180d5 100644 --- a/crates/ide_db/src/helpers/insert_use/tests.rs +++ b/crates/ide_db/src/helpers/insert_use/tests.rs @@ -743,12 +743,23 @@ use foo::bar::qux; ", ImportGranularityGuess::Item, ); +} + +#[test] +fn guess_module_or_item() { check_guess( r" use foo::bar::Bar; -use foo::baz; +use foo::qux; ", - ImportGranularityGuess::Item, + ImportGranularityGuess::ModuleOrItem, + ); + check_guess( + r" +use foo::bar::Bar; +use foo::bar; +", + ImportGranularityGuess::ModuleOrItem, ); }