diff options
Diffstat (limited to 'crates/ide_completion/src/render/function.rs')
-rw-r--r-- | crates/ide_completion/src/render/function.rs | 66 |
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 | ||
3 | use hir::{HasSource, HirDisplay, Type}; | 3 | use hir::{HasSource, HirDisplay, Type}; |
4 | use ide_db::SymbolKind; | 4 | use ide_db::SymbolKind; |
5 | use itertools::Itertools; | ||
5 | use syntax::ast::Fn; | 6 | use syntax::ast::Fn; |
6 | 7 | ||
7 | use crate::{ | 8 | use 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 | ||
12 | pub(crate) fn render_fn<'a>( | 16 | pub(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 { |