Unnamed repository; edit this file 'description' to name the repository.
Reduce trigger range of `generate_impl` assist and update tests
| -rw-r--r-- | crates/ide-assists/src/handlers/generate_impl.rs | 196 | ||||
| -rw-r--r-- | crates/ide-assists/src/tests/generated.rs | 4 |
2 files changed, 118 insertions, 82 deletions
diff --git a/crates/ide-assists/src/handlers/generate_impl.rs b/crates/ide-assists/src/handlers/generate_impl.rs index 9af26c04eb..1bea220f38 100644 --- a/crates/ide-assists/src/handlers/generate_impl.rs +++ b/crates/ide-assists/src/handlers/generate_impl.rs @@ -7,8 +7,8 @@ use crate::{utils::generate_impl_text, AssistContext, AssistId, AssistKind, Assi // Adds a new inherent impl for a type. // // ``` -// struct Ctx<T: Clone> { -// data: T,$0 +// struct Ctx$0<T: Clone> { +// data: T, // } // ``` // -> @@ -26,6 +26,10 @@ pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio let name = nominal.name()?; let target = nominal.syntax().text_range(); + if let Some(_) = ctx.find_node_at_offset::<ast::RecordFieldList>() { + return None; + } + acc.add( AssistId("generate_impl", AssistKind::Generate), format!("Generate impl for `{name}`"), @@ -52,139 +56,171 @@ mod tests { use super::*; - // FIXME: break up into separate test fns #[test] fn test_add_impl() { check_assist( generate_impl, - "struct Foo {$0}\n", - "struct Foo {}\n\nimpl Foo {\n $0\n}\n", - ); - check_assist( - generate_impl, - "struct Foo<T: Clone> {$0}", - "struct Foo<T: Clone> {}\n\nimpl<T: Clone> Foo<T> {\n $0\n}", - ); - check_assist( - generate_impl, - "struct Foo<'a, T: Foo<'a>> {$0}", - "struct Foo<'a, T: Foo<'a>> {}\n\nimpl<'a, T: Foo<'a>> Foo<'a, T> {\n $0\n}", + r#" + struct Foo$0 {} + "#, + r#" + struct Foo {} + + impl Foo { + $0 + } + "#, ); + } + + #[test] + fn test_add_impl_with_generics() { check_assist( generate_impl, r#" - struct MyOwnArray<T, const S: usize> {}$0"#, + struct Foo$0<T: Clone> {} + "#, r#" - struct MyOwnArray<T, const S: usize> {} + struct Foo<T: Clone> {} - impl<T, const S: usize> MyOwnArray<T, S> { - $0 - }"#, + impl<T: Clone> Foo<T> { + $0 + } + "#, ); + } + + #[test] + fn test_add_impl_with_generics_and_lifetime_parameters() { check_assist( generate_impl, r#" - #[cfg(feature = "foo")] - struct Foo<'a, T: Foo<'a>> {$0}"#, + struct Foo<'a, T: Foo<'a>>$0 {} + "#, r#" - #[cfg(feature = "foo")] - struct Foo<'a, T: Foo<'a>> {} + struct Foo<'a, T: Foo<'a>> {} - #[cfg(feature = "foo")] - impl<'a, T: Foo<'a>> Foo<'a, T> { - $0 - }"#, + impl<'a, T: Foo<'a>> Foo<'a, T> { + $0 + } + "#, ); + } + #[test] + fn test_add_impl_with_attributes() { check_assist( generate_impl, r#" - #[cfg(not(feature = "foo"))] - struct Foo<'a, T: Foo<'a>> {$0}"#, + #[cfg(feature = "foo")] + struct Foo<'a, T: Foo$0<'a>> {} + "#, r#" - #[cfg(not(feature = "foo"))] - struct Foo<'a, T: Foo<'a>> {} + #[cfg(feature = "foo")] + struct Foo<'a, T: Foo<'a>> {} - #[cfg(not(feature = "foo"))] - impl<'a, T: Foo<'a>> Foo<'a, T> { - $0 - }"#, + #[cfg(feature = "foo")] + impl<'a, T: Foo<'a>> Foo<'a, T> { + $0 + } + "#, ); + } + #[test] + fn test_add_impl_with_default_generic() { check_assist( generate_impl, r#" - struct Defaulted<T = i32> {}$0"#, + struct Defaulted$0<T = i32> {} + "#, r#" - struct Defaulted<T = i32> {} + struct Defaulted<T = i32> {} - impl<T> Defaulted<T> { - $0 - }"#, + impl<T> Defaulted<T> { + $0 + } + "#, ); + } + #[test] + fn test_add_impl_with_constrained_default_generic() { check_assist( generate_impl, r#" - struct Defaulted<'a, 'b: 'a, T: Debug + Clone + 'a + 'b = String, const S: usize> {}$0"#, + 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> {} + 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> Defaulted<'a, 'b, T, S> { - $0 - }"#, + impl<'a, 'b: 'a, T: Debug + Clone + 'a + 'b, const S: usize> Defaulted<'a, 'b, T, S> { + $0 + } + "#, ); + } + #[test] + fn test_add_impl_with_const_defaulted_generic() { check_assist( generate_impl, r#" - struct Defaulted<const N: i32 = 0> {}$0"#, + struct Defaulted$0<const N: i32 = 0> {} + "#, r#" - struct Defaulted<const N: i32 = 0> {} + struct Defaulted<const N: i32 = 0> {} - impl<const N: i32> Defaulted<N> { - $0 - }"#, + impl<const N: i32> Defaulted<N> { + $0 + } + "#, ); + } + #[test] + fn test_add_impl_with_trait_constraint() { check_assist( generate_impl, - r#"pub trait Trait {} -struct Struct<T>$0 -where - T: Trait, -{ - inner: T, -}"#, - r#"pub trait Trait {} -struct Struct<T> -where - T: Trait, -{ - inner: T, -} + r#" + pub trait Trait {} + struct Struct$0<T> + where + T: Trait, + { + inner: T, + } + "#, + r#" + pub trait Trait {} + struct Struct<T> + where + T: Trait, + { + inner: T, + } -impl<T> Struct<T> -where - T: Trait, -{ - $0 -}"#, + impl<T> Struct<T> + where + T: Trait, + { + $0 + } + "#, ); } #[test] - fn add_impl_target() { + fn add_trait_impl_target() { check_assist_target( generate_impl, - " -struct SomeThingIrrelevant; -/// Has a lifetime parameter -struct Foo<'a, T: Foo<'a>> {$0} -struct EvenMoreIrrelevant; -", - "/// Has a lifetime parameter -struct Foo<'a, T: Foo<'a>> {}", + 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/tests/generated.rs b/crates/ide-assists/src/tests/generated.rs index 67657b61bb..d797f07767 100644 --- a/crates/ide-assists/src/tests/generated.rs +++ b/crates/ide-assists/src/tests/generated.rs @@ -1249,8 +1249,8 @@ fn doctest_generate_impl() { check_doc_test( "generate_impl", r#####" -struct Ctx<T: Clone> { - data: T,$0 +struct Ctx$0<T: Clone> { + data: T, } "#####, r#####" |