aboutsummaryrefslogtreecommitdiff
path: root/crates/completion/src/render
diff options
context:
space:
mode:
Diffstat (limited to 'crates/completion/src/render')
-rw-r--r--crates/completion/src/render/builder_ext.rs5
-rw-r--r--crates/completion/src/render/function.rs69
2 files changed, 55 insertions, 19 deletions
diff --git a/crates/completion/src/render/builder_ext.rs b/crates/completion/src/render/builder_ext.rs
index 37b0d0459..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),
@@ -24,7 +25,7 @@ impl Params {
24} 25}
25 26
26impl Builder { 27impl Builder {
27 pub(super) fn should_add_parems(&self, ctx: &CompletionContext) -> bool { 28 fn should_add_parens(&self, ctx: &CompletionContext) -> bool {
28 if !ctx.config.add_call_parenthesis { 29 if !ctx.config.add_call_parenthesis {
29 return false; 30 return false;
30 } 31 }
@@ -58,7 +59,7 @@ impl Builder {
58 name: String, 59 name: String,
59 params: Params, 60 params: Params,
60 ) -> Builder { 61 ) -> Builder {
61 if !self.should_add_parems(ctx) { 62 if !self.should_add_parens(ctx) {
62 return self; 63 return self;
63 } 64 }
64 65
diff --git a/crates/completion/src/render/function.rs b/crates/completion/src/render/function.rs
index 542383d7e..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},
@@ -22,7 +23,7 @@ pub(crate) fn render_fn<'a>(
22struct FunctionRender<'a> { 23struct FunctionRender<'a> {
23 ctx: RenderContext<'a>, 24 ctx: RenderContext<'a>,
24 name: String, 25 name: String,
25 fn_: hir::Function, 26 func: hir::Function,
26 ast_node: Fn, 27 ast_node: Fn,
27} 28}
28 29
@@ -35,15 +36,15 @@ impl<'a> FunctionRender<'a> {
35 let name = local_name.unwrap_or_else(|| fn_.name(ctx.db()).to_string()); 36 let name = local_name.unwrap_or_else(|| fn_.name(ctx.db()).to_string());
36 let ast_node = fn_.source(ctx.db()).value; 37 let ast_node = fn_.source(ctx.db()).value;
37 38
38 FunctionRender { ctx, name, fn_, ast_node } 39 FunctionRender { ctx, name, func: fn_, ast_node }
39 } 40 }
40 41
41 fn render(self, import_to_add: Option<ImportToAdd>) -> CompletionItem { 42 fn render(self, import_to_add: Option<ImportToAdd>) -> CompletionItem {
42 let params = self.params(); 43 let params = self.params();
43 CompletionItem::new(CompletionKind::Reference, self.ctx.source_range(), self.name.clone()) 44 CompletionItem::new(CompletionKind::Reference, self.ctx.source_range(), self.name.clone())
44 .kind(self.kind()) 45 .kind(self.kind())
45 .set_documentation(self.ctx.docs(self.fn_)) 46 .set_documentation(self.ctx.docs(self.func))
46 .set_deprecated(self.ctx.is_deprecated(self.fn_)) 47 .set_deprecated(self.ctx.is_deprecated(self.func))
47 .detail(self.detail()) 48 .detail(self.detail())
48 .add_call_parens(self.ctx.completion, self.name, params) 49 .add_call_parens(self.ctx.completion, self.name, params)
49 .add_import(import_to_add) 50 .add_import(import_to_add)
@@ -67,27 +68,39 @@ impl<'a> FunctionRender<'a> {
67 } 68 }
68 69
69 fn params(&self) -> Params { 70 fn params(&self) -> Params {
70 let params_ty = self.fn_.params(self.ctx.db()); 71 let ast_params = match self.ast_node.param_list() {
71 let params = self 72 Some(it) => it,
72 .ast_node 73 None => return Params::Named(Vec::new()),
73 .param_list() 74 };
75
76 let mut params_pats = Vec::new();
77 let params_ty = if self.ctx.completion.dot_receiver.is_some() {
78 self.func.method_params(self.ctx.db()).unwrap_or_default()
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 }
84 self.func.assoc_fn_params(self.ctx.db())
85 };
86 params_pats
87 .extend(ast_params.params().into_iter().map(|it| it.pat().map(|it| it.to_string())));
88
89 let params = params_pats
74 .into_iter() 90 .into_iter()
75 .flat_map(|it| it.params())
76 .zip(params_ty) 91 .zip(params_ty)
77 .flat_map(|(it, param_ty)| { 92 .flat_map(|(pat, param_ty)| {
78 if let Some(pat) = it.pat() { 93 let pat = pat?;
79 let name = pat.to_string(); 94 let name = pat.to_string();
80 let arg = name.trim_start_matches("mut ").trim_start_matches('_'); 95 let arg = name.trim_start_matches("mut ").trim_start_matches('_');
81 return Some(self.add_arg(arg, param_ty.ty())); 96 Some(self.add_arg(arg, param_ty.ty()))
82 }
83 None
84 }) 97 })
85 .collect(); 98 .collect();
86 Params::Named(params) 99 Params::Named(params)
87 } 100 }
88 101
89 fn kind(&self) -> CompletionItemKind { 102 fn kind(&self) -> CompletionItemKind {
90 if self.fn_.self_param(self.ctx.db()).is_some() { 103 if self.func.self_param(self.ctx.db()).is_some() {
91 CompletionItemKind::Method 104 CompletionItemKind::Method
92 } else { 105 } else {
93 CompletionItemKind::Function 106 CompletionItemKind::Function
@@ -173,6 +186,28 @@ fn bar(s: &S) {
173 } 186 }
174 187
175 #[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]
176 fn suppress_arg_snippets() { 211 fn suppress_arg_snippets() {
177 mark::check!(suppress_arg_snippets); 212 mark::check!(suppress_arg_snippets);
178 check_edit_with_config( 213 check_edit_with_config(