aboutsummaryrefslogtreecommitdiff
path: root/crates/completion
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-12-01 11:23:00 +0000
committerAleksey Kladov <[email protected]>2020-12-01 11:28:50 +0000
commit9d94ffad44f2b250e498f162cd498aed62877c8e (patch)
tree0a08b79f8fb8f5da53e5d700d827d325cd326178 /crates/completion
parent02955661a0e8b39fd0b887b245f0e1284ea8f504 (diff)
Place cursor correctly when completing assoc fns with self
Diffstat (limited to 'crates/completion')
-rw-r--r--crates/completion/src/completions/qualified_path.rs40
-rw-r--r--crates/completion/src/render/builder_ext.rs1
-rw-r--r--crates/completion/src/render/function.rs53
3 files changed, 63 insertions, 31 deletions
diff --git a/crates/completion/src/completions/qualified_path.rs b/crates/completion/src/completions/qualified_path.rs
index d9387054d..bc23bea3f 100644
--- a/crates/completion/src/completions/qualified_path.rs
+++ b/crates/completion/src/completions/qualified_path.rs
@@ -353,10 +353,10 @@ impl S {
353fn foo() { let _ = S::<|> } 353fn foo() { let _ = S::<|> }
354"#, 354"#,
355 expect![[r#" 355 expect![[r#"
356 ct C const C: i32 = 42; 356 ct C const C: i32 = 42;
357 ta T type T = i32; 357 ta T type T = i32;
358 fn a() fn a() 358 fn a() fn a()
359 me b() fn b(&self) 359 me b() fn b(&self)
360 "#]], 360 "#]],
361 ); 361 );
362 } 362 }
@@ -503,14 +503,14 @@ trait Sub: Super {
503fn foo<T: Sub>() { T::<|> } 503fn foo<T: Sub>() { T::<|> }
504"#, 504"#,
505 expect![[r#" 505 expect![[r#"
506 ct C2 const C2: (); 506 ct C2 const C2: ();
507 ct CONST const CONST: u8; 507 ct CONST const CONST: u8;
508 ta SubTy type SubTy; 508 ta SubTy type SubTy;
509 ta Ty type Ty; 509 ta Ty type Ty;
510 fn func() fn func() 510 fn func() fn func()
511 me method() fn method(&self) 511 me method() fn method(&self)
512 fn subfunc() fn subfunc() 512 fn subfunc() fn subfunc()
513 me submethod() fn submethod(&self) 513 me submethod() fn submethod(&self)
514 "#]], 514 "#]],
515 ); 515 );
516 } 516 }
@@ -543,14 +543,14 @@ impl<T> Sub for Wrap<T> {
543} 543}
544"#, 544"#,
545 expect![[r#" 545 expect![[r#"
546 ct C2 const C2: () = (); 546 ct C2 const C2: () = ();
547 ct CONST const CONST: u8 = 0; 547 ct CONST const CONST: u8 = 0;
548 ta SubTy type SubTy; 548 ta SubTy type SubTy;
549 ta Ty type Ty; 549 ta Ty type Ty;
550 fn func() fn func() 550 fn func() fn func()
551 me method() fn method(&self) 551 me method() fn method(&self)
552 fn subfunc() fn subfunc() 552 fn subfunc() fn subfunc()
553 me submethod() fn submethod(&self) 553 me submethod() fn submethod(&self)
554 "#]], 554 "#]],
555 ); 555 );
556 } 556 }
diff --git a/crates/completion/src/render/builder_ext.rs b/crates/completion/src/render/builder_ext.rs
index 79599de4b..ce8718bd5 100644
--- a/crates/completion/src/render/builder_ext.rs
+++ b/crates/completion/src/render/builder_ext.rs
@@ -5,6 +5,7 @@ use test_utils::mark;
5 5
6use crate::{item::Builder, CompletionContext}; 6use crate::{item::Builder, CompletionContext};
7 7
8#[derive(Debug)]
8pub(super) enum Params { 9pub(super) enum Params {
9 Named(Vec<String>), 10 Named(Vec<String>),
10 Anonymous(usize), 11 Anonymous(usize),
diff --git a/crates/completion/src/render/function.rs b/crates/completion/src/render/function.rs
index 09d9f85bc..00e3eb203 100644
--- a/crates/completion/src/render/function.rs
+++ b/crates/completion/src/render/function.rs
@@ -2,6 +2,7 @@
2 2
3use hir::{HasSource, Type}; 3use hir::{HasSource, Type};
4use syntax::{ast::Fn, display::function_declaration}; 4use syntax::{ast::Fn, display::function_declaration};
5use test_utils::mark;
5 6
6use crate::{ 7use crate::{
7 item::{CompletionItem, CompletionItemKind, CompletionKind, ImportToAdd}, 8 item::{CompletionItem, CompletionItemKind, CompletionKind, ImportToAdd},
@@ -67,24 +68,32 @@ impl<'a> FunctionRender<'a> {
67 } 68 }
68 69
69 fn params(&self) -> Params { 70 fn params(&self) -> Params {
71 let ast_params = match self.ast_node.param_list() {
72 Some(it) => it,
73 None => return Params::Named(Vec::new()),
74 };
75
76 let mut params_pats = Vec::new();
70 let params_ty = if self.ctx.completion.dot_receiver.is_some() { 77 let params_ty = if self.ctx.completion.dot_receiver.is_some() {
71 self.func.method_params(self.ctx.db()).unwrap_or_default() 78 self.func.method_params(self.ctx.db()).unwrap_or_default()
72 } else { 79 } else {
80 if let Some(s) = ast_params.self_param() {
81 mark::hit!(parens_for_method_call_as_assoc_fn);
82 params_pats.push(Some(s.to_string()));
83 }
73 self.func.assoc_fn_params(self.ctx.db()) 84 self.func.assoc_fn_params(self.ctx.db())
74 }; 85 };
75 let params = self 86 params_pats
76 .ast_node 87 .extend(ast_params.params().into_iter().map(|it| it.pat().map(|it| it.to_string())));
77 .param_list() 88
89 let params = params_pats
78 .into_iter() 90 .into_iter()
79 .flat_map(|it| it.params())
80 .zip(params_ty) 91 .zip(params_ty)
81 .flat_map(|(it, param_ty)| { 92 .flat_map(|(pat, param_ty)| {
82 if let Some(pat) = it.pat() { 93 let pat = pat?;
83 let name = pat.to_string(); 94 let name = pat.to_string();
84 let arg = name.trim_start_matches("mut ").trim_start_matches('_'); 95 let arg = name.trim_start_matches("mut ").trim_start_matches('_');
85 return Some(self.add_arg(arg, param_ty.ty())); 96 Some(self.add_arg(arg, param_ty.ty()))
86 }
87 None
88 }) 97 })
89 .collect(); 98 .collect();
90 Params::Named(params) 99 Params::Named(params)
@@ -177,6 +186,28 @@ fn bar(s: &S) {
177 } 186 }
178 187
179 #[test] 188 #[test]
189 fn parens_for_method_call_as_assoc_fn() {
190 mark::check!(parens_for_method_call_as_assoc_fn);
191 check_edit(
192 "foo",
193 r#"
194struct S;
195impl S {
196 fn foo(&self) {}
197}
198fn main() { S::f<|> }
199"#,
200 r#"
201struct S;
202impl S {
203 fn foo(&self) {}
204}
205fn main() { S::foo(${1:&self})$0 }
206"#,
207 );
208 }
209
210 #[test]
180 fn suppress_arg_snippets() { 211 fn suppress_arg_snippets() {
181 mark::check!(suppress_arg_snippets); 212 mark::check!(suppress_arg_snippets);
182 check_edit_with_config( 213 check_edit_with_config(