diff options
| author | Dorian Scheidt <dorian.scheidt@gmail.com> | 2022-08-13 13:29:41 -0500 |
|---|---|---|
| committer | Dorian Scheidt <dorian.scheidt@gmail.com> | 2022-08-16 15:37:24 -0500 |
| commit | 39d17efde7d2da436f349c1b0ca55c37bae0254f (patch) | |
| tree | 3fbe786bb6c5c34632eb2b10c79ca5f6406ea2ad | |
| parent | baa2cccb24023a246d4258b08ff4064c9169e67e (diff) | |
| download | rust-39d17efde7d2da436f349c1b0ca55c37bae0254f.tar.gz rust-39d17efde7d2da436f349c1b0ca55c37bae0254f.zip | |
feat: Generate static method using Self::assoc() syntax
This change improves the `generate_function` assist to support generating static methods/associated functions using the `Self::assoc()` syntax. Previously, one could generate a static method, but only when specifying the type name directly (like `Foo::assoc()`). After this change, `Self` is supported as well as the type name. Fixes #13012
| -rw-r--r-- | crates/ide-assists/src/handlers/generate_function.rs | 64 |
1 files changed, 53 insertions, 11 deletions
diff --git a/crates/ide-assists/src/handlers/generate_function.rs b/crates/ide-assists/src/handlers/generate_function.rs index d564a054089..49345cb983f 100644 --- a/crates/ide-assists/src/handlers/generate_function.rs +++ b/crates/ide-assists/src/handlers/generate_function.rs @@ -61,7 +61,7 @@ fn gen_fn(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { } let fn_name = &*name_ref.text(); - let target_module; + let mut target_module = None; let mut adt_name = None; let (target, file, insert_offset) = match path.qualifier() { @@ -78,16 +78,11 @@ fn gen_fn(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { } } - let current_module = ctx.sema.scope(call.syntax())?.module(); - let module = adt.module(ctx.sema.db); - target_module = if current_module == module { None } else { Some(module) }; - if current_module.krate() != module.krate() { - return None; - } - let (impl_, file) = get_adt_source(ctx, &adt, fn_name)?; - let (target, insert_offset) = get_method_target(ctx, &module, &impl_)?; - adt_name = if impl_.is_none() { Some(adt.name(ctx.sema.db)) } else { None }; - (target, file, insert_offset) + static_method_target(ctx, &call, adt, &mut target_module, fn_name, &mut adt_name)? + } + Some(hir::PathResolution::SelfType(impl_)) => { + let adt = impl_.self_ty(ctx.db()).as_adt()?; + static_method_target(ctx, &call, adt, &mut target_module, fn_name, &mut adt_name)? } _ => { return None; @@ -399,6 +394,26 @@ fn get_method_target( Some((target.clone(), get_insert_offset(&target))) } +fn static_method_target( + ctx: &AssistContext<'_>, + call: &CallExpr, + adt: hir::Adt, + target_module: &mut Option<Module>, + fn_name: &str, + adt_name: &mut Option<hir::Name>, +) -> Option<(GeneratedFunctionTarget, FileId, TextSize)> { + let current_module = ctx.sema.scope(call.syntax())?.module(); + let module = adt.module(ctx.sema.db); + *target_module = if current_module == module { None } else { Some(module) }; + if current_module.krate() != module.krate() { + return None; + } + let (impl_, file) = get_adt_source(ctx, &adt, fn_name)?; + let (target, insert_offset) = get_method_target(ctx, &module, &impl_)?; + *adt_name = if impl_.is_none() { Some(adt.name(ctx.sema.db)) } else { None }; + Some((target, file, insert_offset)) +} + fn get_insert_offset(target: &GeneratedFunctionTarget) -> TextSize { match &target { GeneratedFunctionTarget::BehindItem(it) => it.text_range().end(), @@ -1634,6 +1649,33 @@ fn bar() ${0:-> _} { } #[test] + fn create_static_method_within_an_impl_with_self_syntax() { + check_assist( + generate_function, + r" +struct S; +impl S { + fn foo(&self) { + Self::bar$0(); + } +} +", + r" +struct S; +impl S { + fn foo(&self) { + Self::bar(); + } + + fn bar() ${0:-> _} { + todo!() + } +} +", + ) + } + + #[test] fn no_panic_on_invalid_global_path() { check_assist( generate_function, |
