From 469f620b064d2935c741222927dc955da395532b Mon Sep 17 00:00:00 2001 From: Mihail Mihov Date: Mon, 21 Nov 2022 22:58:01 +0200 Subject: [PATCH] Combine `generate_impl` and `generate_trait_impl` into a single file --- .../ide-assists/src/handlers/generate_impl.rs | 223 ++++++++++++++++- .../src/handlers/generate_trait_impl.rs | 226 ------------------ crates/ide-assists/src/lib.rs | 3 +- 3 files changed, 222 insertions(+), 230 deletions(-) delete mode 100644 crates/ide-assists/src/handlers/generate_trait_impl.rs diff --git a/crates/ide-assists/src/handlers/generate_impl.rs b/crates/ide-assists/src/handlers/generate_impl.rs index 1bea220f389..690c97e26d8 100644 --- a/crates/ide-assists/src/handlers/generate_impl.rs +++ b/crates/ide-assists/src/handlers/generate_impl.rs @@ -1,6 +1,9 @@ use syntax::ast::{self, AstNode, HasName}; -use crate::{utils::generate_impl_text, AssistContext, AssistId, AssistKind, Assists}; +use crate::{ + utils::{generate_impl_text, generate_trait_impl_text}, + AssistContext, AssistId, AssistKind, Assists, +}; // Assist: generate_impl // @@ -50,6 +53,54 @@ pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio ) } +// Assist: generate_trait_impl +// +// Adds a new trait impl for a type. +// +// ``` +// struct $0Ctx { +// data: T, +// } +// ``` +// -> +// ``` +// struct Ctx { +// data: T, +// } +// +// impl $0 for Ctx { +// +// } +// ``` +pub(crate) fn generate_trait_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { + let nominal = ctx.find_node_at_offset::()?; + let name = nominal.name()?; + let target = nominal.syntax().text_range(); + + if let Some(_) = ctx.find_node_at_offset::() { + return None; + } + + acc.add( + AssistId("generate_trait_impl", AssistKind::Generate), + format!("Generate trait impl for `{name}`"), + target, + |edit| { + let start_offset = nominal.syntax().text_range().end(); + match ctx.config.snippet_cap { + Some(cap) => { + let snippet = generate_trait_impl_text(&nominal, "$0", ""); + edit.insert_snippet(cap, start_offset, snippet); + } + None => { + let text = generate_trait_impl_text(&nominal, "", ""); + edit.insert(start_offset, text); + } + } + }, + ) +} + #[cfg(test)] mod tests { use crate::tests::{check_assist, check_assist_target}; @@ -211,7 +262,7 @@ mod tests { } #[test] - fn add_trait_impl_target() { + fn add_impl_target() { check_assist_target( generate_impl, r#" @@ -223,4 +274,172 @@ mod tests { "/// Has a lifetime parameter\nstruct Foo<'a, T: Foo<'a>> {}", ); } + + #[test] + fn test_add_trait_impl() { + check_assist( + generate_trait_impl, + r#" + struct Foo$0 {} + "#, + r#" + struct Foo {} + + impl $0 for Foo { + + } + "#, + ); + } + + #[test] + fn test_add_trait_impl_with_generics() { + check_assist( + generate_trait_impl, + r#" + struct Foo$0 {} + "#, + r#" + struct Foo {} + + impl $0 for Foo { + + } + "#, + ); + } + + #[test] + fn test_add_trait_impl_with_generics_and_lifetime_parameters() { + check_assist( + generate_trait_impl, + r#" + struct Foo<'a, T: Foo<'a>>$0 {} + "#, + r#" + struct Foo<'a, T: Foo<'a>> {} + + impl<'a, T: Foo<'a>> $0 for Foo<'a, T> { + + } + "#, + ); + } + + #[test] + fn test_add_trait_impl_with_attributes() { + check_assist( + generate_trait_impl, + r#" + #[cfg(feature = "foo")] + struct Foo<'a, T: Foo$0<'a>> {} + "#, + r#" + #[cfg(feature = "foo")] + struct Foo<'a, T: Foo<'a>> {} + + #[cfg(feature = "foo")] + impl<'a, T: Foo<'a>> $0 for Foo<'a, T> { + + } + "#, + ); + } + + #[test] + fn test_add_trait_impl_with_default_generic() { + check_assist( + generate_trait_impl, + r#" + struct Defaulted$0 {} + "#, + r#" + struct Defaulted {} + + impl $0 for Defaulted { + + } + "#, + ); + } + + #[test] + fn test_add_trait_impl_with_constrained_default_generic() { + check_assist( + generate_trait_impl, + r#" + struct Defaulted$0<'a, 'b: 'a, T: Debug + Clone + 'a + 'b = String, const S: usize> {} + "#, + r#" + struct Defaulted<'a, 'b: 'a, T: Debug + Clone + 'a + 'b = String, const S: usize> {} + + impl<'a, 'b: 'a, T: Debug + Clone + 'a + 'b, const S: usize> $0 for Defaulted<'a, 'b, T, S> { + + } + "#, + ); + } + + #[test] + fn test_add_trait_impl_with_const_defaulted_generic() { + check_assist( + generate_trait_impl, + r#" + struct Defaulted$0 {} + "#, + r#" + struct Defaulted {} + + impl $0 for Defaulted { + + } + "#, + ); + } + + #[test] + fn test_add_trait_impl_with_trait_constraint() { + check_assist( + generate_trait_impl, + r#" + pub trait Trait {} + struct Struct$0 + where + T: Trait, + { + inner: T, + } + "#, + r#" + pub trait Trait {} + struct Struct + where + T: Trait, + { + inner: T, + } + + impl $0 for Struct + where + T: Trait, + { + + } + "#, + ); + } + + #[test] + fn add_trait_impl_target() { + check_assist_target( + generate_trait_impl, + r#" + struct SomeThingIrrelevant; + /// Has a lifetime parameter + struct Foo$0<'a, T: Foo<'a>> {} + struct EvenMoreIrrelevant; + "#, + "/// Has a lifetime parameter\nstruct Foo<'a, T: Foo<'a>> {}", + ); + } } diff --git a/crates/ide-assists/src/handlers/generate_trait_impl.rs b/crates/ide-assists/src/handlers/generate_trait_impl.rs deleted file mode 100644 index 7b1ee5b5c31..00000000000 --- a/crates/ide-assists/src/handlers/generate_trait_impl.rs +++ /dev/null @@ -1,226 +0,0 @@ -use syntax::ast::{self, AstNode, HasName}; - -use crate::{utils::generate_trait_impl_text, AssistContext, AssistId, AssistKind, Assists}; - -// Assist: generate_trait_impl -// -// Adds a new trait impl for a type. -// -// ``` -// struct $0Ctx { -// data: T, -// } -// ``` -// -> -// ``` -// struct Ctx { -// data: T, -// } -// -// impl $0 for Ctx { -// -// } -// ``` -pub(crate) fn generate_trait_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { - let nominal = ctx.find_node_at_offset::()?; - let name = nominal.name()?; - let target = nominal.syntax().text_range(); - - if let Some(_) = ctx.find_node_at_offset::() { - return None; - } - - acc.add( - AssistId("generate_trait_impl", AssistKind::Generate), - format!("Generate trait impl for `{name}`"), - target, - |edit| { - let start_offset = nominal.syntax().text_range().end(); - match ctx.config.snippet_cap { - Some(cap) => { - let snippet = generate_trait_impl_text(&nominal, "$0", ""); - edit.insert_snippet(cap, start_offset, snippet); - } - None => { - let text = generate_trait_impl_text(&nominal, "", ""); - edit.insert(start_offset, text); - } - } - }, - ) -} - -#[cfg(test)] -mod tests { - use crate::tests::{check_assist, check_assist_target}; - - use super::*; - - #[test] - fn test_add_trait_impl() { - check_assist( - generate_trait_impl, - r#" - struct Foo$0 {} - "#, - r#" - struct Foo {} - - impl $0 for Foo { - - } - "#, - ); - } - - #[test] - fn test_add_trait_impl_with_generics() { - check_assist( - generate_trait_impl, - r#" - struct Foo$0 {} - "#, - r#" - struct Foo {} - - impl $0 for Foo { - - } - "#, - ); - } - - #[test] - fn test_add_trait_impl_with_generics_and_lifetime_parameters() { - check_assist( - generate_trait_impl, - r#" - struct Foo<'a, T: Foo<'a>>$0 {} - "#, - r#" - struct Foo<'a, T: Foo<'a>> {} - - impl<'a, T: Foo<'a>> $0 for Foo<'a, T> { - - } - "#, - ); - } - - #[test] - fn test_add_trait_impl_with_attributes() { - check_assist( - generate_trait_impl, - r#" - #[cfg(feature = "foo")] - struct Foo<'a, T: Foo$0<'a>> {} - "#, - r#" - #[cfg(feature = "foo")] - struct Foo<'a, T: Foo<'a>> {} - - #[cfg(feature = "foo")] - impl<'a, T: Foo<'a>> $0 for Foo<'a, T> { - - } - "#, - ); - } - - #[test] - fn test_add_trait_impl_with_default_generic() { - check_assist( - generate_trait_impl, - r#" - struct Defaulted$0 {} - "#, - r#" - struct Defaulted {} - - impl $0 for Defaulted { - - } - "#, - ); - } - - #[test] - fn test_add_trait_impl_with_constrained_default_generic() { - check_assist( - generate_trait_impl, - r#" - struct Defaulted$0<'a, 'b: 'a, T: Debug + Clone + 'a + 'b = String, const S: usize> {} - "#, - r#" - struct Defaulted<'a, 'b: 'a, T: Debug + Clone + 'a + 'b = String, const S: usize> {} - - impl<'a, 'b: 'a, T: Debug + Clone + 'a + 'b, const S: usize> $0 for Defaulted<'a, 'b, T, S> { - - } - "#, - ); - } - - #[test] - fn test_add_trait_impl_with_const_defaulted_generic() { - check_assist( - generate_trait_impl, - r#" - struct Defaulted$0 {} - "#, - r#" - struct Defaulted {} - - impl $0 for Defaulted { - - } - "#, - ); - } - - #[test] - fn test_add_trait_impl_with_trait_constraint() { - check_assist( - generate_trait_impl, - r#" - pub trait Trait {} - struct Struct$0 - where - T: Trait, - { - inner: T, - } - "#, - r#" - pub trait Trait {} - struct Struct - where - T: Trait, - { - inner: T, - } - - impl $0 for Struct - where - T: Trait, - { - - } - "#, - ); - } - - #[test] - fn add_trait_impl_target() { - check_assist_target( - generate_trait_impl, - r#" - struct SomeThingIrrelevant; - /// Has a lifetime parameter - struct Foo$0<'a, T: Foo<'a>> {} - struct EvenMoreIrrelevant; - "#, - "/// Has a lifetime parameter\nstruct Foo<'a, T: Foo<'a>> {}", - ); - } -} diff --git a/crates/ide-assists/src/lib.rs b/crates/ide-assists/src/lib.rs index e3c483cf0a9..b12f99cc532 100644 --- a/crates/ide-assists/src/lib.rs +++ b/crates/ide-assists/src/lib.rs @@ -152,7 +152,6 @@ mod handlers { mod generate_function; mod generate_getter; mod generate_impl; - mod generate_trait_impl; mod generate_is_empty_from_len; mod generate_new; mod generate_setter; @@ -248,7 +247,7 @@ mod handlers { generate_from_impl_for_enum::generate_from_impl_for_enum, generate_function::generate_function, generate_impl::generate_impl, - generate_trait_impl::generate_trait_impl, + generate_impl::generate_trait_impl, generate_is_empty_from_len::generate_is_empty_from_len, generate_new::generate_new, inline_call::inline_call,