1 use hir::{ItemInNs, ModuleDef};
3 assists::{AssistId, AssistKind},
4 imports::import_assets::item_for_path_search,
6 use syntax::{ast, AstNode};
9 assist_context::{AssistContext, Assists},
10 handlers::qualify_path::QualifyCandidate,
13 // Assist: qualify_method_call
15 // Replaces the method call with a qualified function call.
38 pub(crate) fn qualify_method_call(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
39 let name: ast::NameRef = ctx.find_node_at_offset()?;
40 let call = name.syntax().parent().and_then(ast::MethodCallExpr::cast)?;
42 let ident = name.ident_token()?;
44 let range = call.syntax().text_range();
45 let resolved_call = ctx.sema.resolve_method_call(&call)?;
47 let current_module = ctx.sema.scope(call.syntax())?.module();
48 let target_module_def = ModuleDef::from(resolved_call);
49 let item_in_ns = ItemInNs::from(target_module_def);
50 let receiver_path = current_module
51 .find_use_path(ctx.sema.db, item_for_path_search(ctx.sema.db, item_in_ns)?)?;
53 let qualify_candidate = QualifyCandidate::ImplMethod(ctx.sema.db, call, resolved_call);
56 AssistId("qualify_method_call", AssistKind::RefactorInline),
57 format!("Qualify `{}` method call", ident.text()),
60 qualify_candidate.qualify(
61 |replace_with: String| builder.replace(range, replace_with),
73 use crate::tests::{check_assist, check_assist_not_applicable};
105 fn struct_method_multi_params() {
111 fn foo(&self, p1: i32, p2: u32) {}
122 fn foo(&self, p1: i32, p2: u32) {}
127 Foo::foo(&foo, 9, 9u)
134 fn struct_method_consume() {
140 fn foo(self, p1: i32, p2: u32) {}
151 fn foo(self, p1: i32, p2: u32) {}
163 fn struct_method_exclusive() {
169 fn foo(&mut self, p1: i32, p2: u32) {}
180 fn foo(&mut self, p1: i32, p2: u32) {}
185 Foo::foo(&mut foo, 9, 9u)
192 fn struct_method_cross_crate() {
196 //- /main.rs crate:main deps:dep
198 let foo = dep::test_mod::Foo {};
201 //- /dep.rs crate:dep
205 pub fn foo(&mut self, p1: i32, p2: u32) {}
211 let foo = dep::test_mod::Foo {};
212 dep::test_mod::Foo::foo(&mut foo, 9, 9u)
219 fn struct_method_generic() {
253 pub trait TestTrait {
254 fn test_method(&self);
256 pub struct TestStruct {}
257 impl TestTrait for TestStruct {
258 fn test_method(&self) {}
265 let test_struct = test_mod::TestStruct {};
266 test_struct.test_meth$0od()
271 pub trait TestTrait {
272 fn test_method(&self);
274 pub struct TestStruct {}
275 impl TestTrait for TestStruct {
276 fn test_method(&self) {}
283 let test_struct = test_mod::TestStruct {};
284 TestStruct::test_method(&test_struct)
291 fn trait_method_multi_params() {
296 pub trait TestTrait {
297 fn test_method(&self, p1: i32, p2: u32);
299 pub struct TestStruct {}
300 impl TestTrait for TestStruct {
301 fn test_method(&self, p1: i32, p2: u32) {}
308 let test_struct = test_mod::TestStruct {};
309 test_struct.test_meth$0od(12, 32u)
314 pub trait TestTrait {
315 fn test_method(&self, p1: i32, p2: u32);
317 pub struct TestStruct {}
318 impl TestTrait for TestStruct {
319 fn test_method(&self, p1: i32, p2: u32) {}
326 let test_struct = test_mod::TestStruct {};
327 TestStruct::test_method(&test_struct, 12, 32u)
334 fn trait_method_consume() {
339 pub trait TestTrait {
340 fn test_method(self, p1: i32, p2: u32);
342 pub struct TestStruct {}
343 impl TestTrait for TestStruct {
344 fn test_method(self, p1: i32, p2: u32) {}
351 let test_struct = test_mod::TestStruct {};
352 test_struct.test_meth$0od(12, 32u)
357 pub trait TestTrait {
358 fn test_method(self, p1: i32, p2: u32);
360 pub struct TestStruct {}
361 impl TestTrait for TestStruct {
362 fn test_method(self, p1: i32, p2: u32) {}
369 let test_struct = test_mod::TestStruct {};
370 TestStruct::test_method(test_struct, 12, 32u)
377 fn trait_method_exclusive() {
382 pub trait TestTrait {
383 fn test_method(&mut self, p1: i32, p2: u32);
385 pub struct TestStruct {}
386 impl TestTrait for TestStruct {
387 fn test_method(&mut self, p1: i32, p2: u32);
394 let test_struct = test_mod::TestStruct {};
395 test_struct.test_meth$0od(12, 32u)
400 pub trait TestTrait {
401 fn test_method(&mut self, p1: i32, p2: u32);
403 pub struct TestStruct {}
404 impl TestTrait for TestStruct {
405 fn test_method(&mut self, p1: i32, p2: u32);
412 let test_struct = test_mod::TestStruct {};
413 TestStruct::test_method(&mut test_struct, 12, 32u)
420 fn trait_method_cross_crate() {
424 //- /main.rs crate:main deps:dep
426 let foo = dep::test_mod::Foo {};
429 //- /dep.rs crate:dep
433 pub fn foo(&mut self, p1: i32, p2: u32) {}
439 let foo = dep::test_mod::Foo {};
440 dep::test_mod::Foo::foo(&mut foo, 9, 9u)
447 fn trait_method_generic() {
452 pub trait TestTrait {
453 fn test_method<T>(&self);
455 pub struct TestStruct {}
456 impl TestTrait for TestStruct {
457 fn test_method<T>(&self) {}
464 let test_struct = TestStruct {};
465 test_struct.test_meth$0od::<()>()
470 pub trait TestTrait {
471 fn test_method<T>(&self);
473 pub struct TestStruct {}
474 impl TestTrait for TestStruct {
475 fn test_method<T>(&self) {}
482 let test_struct = TestStruct {};
483 TestStruct::test_method::<()>(&test_struct)
490 fn struct_method_over_stuct_instance() {
491 check_assist_not_applicable(
508 fn trait_method_over_stuct_instance() {
509 check_assist_not_applicable(
513 pub trait TestTrait {
514 fn test_method(&self);
516 pub struct TestStruct {}
517 impl TestTrait for TestStruct {
518 fn test_method(&self) {}
525 let test_struct = test_mod::TestStruct {};
526 tes$0t_struct.test_method()