aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion/src/render/function.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_completion/src/render/function.rs')
-rw-r--r--crates/ide_completion/src/render/function.rs66
1 files changed, 50 insertions, 16 deletions
diff --git a/crates/ide_completion/src/render/function.rs b/crates/ide_completion/src/render/function.rs
index 47e26a5d8..010303182 100644
--- a/crates/ide_completion/src/render/function.rs
+++ b/crates/ide_completion/src/render/function.rs
@@ -2,11 +2,15 @@
2 2
3use hir::{HasSource, HirDisplay, Type}; 3use hir::{HasSource, HirDisplay, Type};
4use ide_db::SymbolKind; 4use ide_db::SymbolKind;
5use itertools::Itertools;
5use syntax::ast::Fn; 6use syntax::ast::Fn;
6 7
7use crate::{ 8use crate::{
8 item::{CompletionItem, CompletionItemKind, CompletionKind, CompletionRelevance, ImportEdit}, 9 item::{CompletionItem, CompletionItemKind, CompletionKind, CompletionRelevance, ImportEdit},
9 render::{builder_ext::Params, RenderContext}, 10 render::{
11 builder_ext::Params, compute_exact_name_match, compute_exact_type_match, compute_ref_match,
12 RenderContext,
13 },
10}; 14};
11 15
12pub(crate) fn render_fn<'a>( 16pub(crate) fn render_fn<'a>(
@@ -52,30 +56,60 @@ impl<'a> FunctionRender<'a> {
52 self.ctx.is_deprecated(self.func) || self.ctx.is_deprecated_assoc_item(self.func), 56 self.ctx.is_deprecated(self.func) || self.ctx.is_deprecated_assoc_item(self.func),
53 ) 57 )
54 .detail(self.detail()) 58 .detail(self.detail())
55 .add_call_parens(self.ctx.completion, self.name, params) 59 .add_call_parens(self.ctx.completion, self.name.clone(), params)
56 .add_import(import_to_add); 60 .add_import(import_to_add);
57 61
58 let mut relevance = CompletionRelevance::default(); 62 let ret_type = self.func.ret_type(self.ctx.db());
59 if let Some(expected_type) = &self.ctx.completion.expected_type { 63 item.set_relevance(CompletionRelevance {
60 let ret_ty = self.func.ret_type(self.ctx.db()); 64 exact_type_match: compute_exact_type_match(self.ctx.completion, &ret_type),
65 exact_name_match: compute_exact_name_match(self.ctx.completion, self.name.clone()),
66 ..CompletionRelevance::default()
67 });
61 68
62 // We don't ever consider a function which returns unit type to be an 69 if let Some(ref_match) = compute_ref_match(self.ctx.completion, &ret_type) {
63 // exact type match, since nearly always this is not meaningful to the 70 item.ref_match(ref_match);
64 // user.
65 relevance.exact_type_match = &ret_ty == expected_type && !ret_ty.is_unit();
66 } 71 }
67 if let Some(expected_name) = &self.ctx.completion.expected_name {
68 relevance.exact_name_match =
69 expected_name == &self.func.name(self.ctx.db()).to_string();
70 }
71 item.set_relevance(relevance);
72 72
73 item.build() 73 item.build()
74 } 74 }
75 75
76 fn detail(&self) -> String { 76 fn detail(&self) -> String {
77 let ty = self.func.ret_type(self.ctx.db()); 77 let ret_ty = self.func.ret_type(self.ctx.db());
78 format!("-> {}", ty.display(self.ctx.db())) 78 let ret = if ret_ty.is_unit() {
79 // Omit the return type if it is the unit type
80 String::new()
81 } else {
82 format!(" {}", self.ty_display())
83 };
84
85 format!("fn({}){}", self.params_display(), ret)
86 }
87
88 fn params_display(&self) -> String {
89 if let Some(self_param) = self.func.self_param(self.ctx.db()) {
90 let params = self
91 .func
92 .assoc_fn_params(self.ctx.db())
93 .into_iter()
94 .skip(1) // skip the self param because we are manually handling that
95 .map(|p| p.ty().display(self.ctx.db()).to_string());
96
97 std::iter::once(self_param.display(self.ctx.db()).to_owned()).chain(params).join(", ")
98 } else {
99 let params = self
100 .func
101 .assoc_fn_params(self.ctx.db())
102 .into_iter()
103 .map(|p| p.ty().display(self.ctx.db()).to_string())
104 .join(", ");
105 params
106 }
107 }
108
109 fn ty_display(&self) -> String {
110 let ret_ty = self.func.ret_type(self.ctx.db());
111
112 format!("-> {}", ret_ty.display(self.ctx.db()))
79 } 113 }
80 114
81 fn add_arg(&self, arg: &str, ty: &Type) -> String { 115 fn add_arg(&self, arg: &str, ty: &Type) -> String {