Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-completion/src/render/function.rs')
| -rw-r--r-- | crates/ide-completion/src/render/function.rs | 59 |
1 files changed, 52 insertions, 7 deletions
diff --git a/crates/ide-completion/src/render/function.rs b/crates/ide-completion/src/render/function.rs index 27186a2b7f..32075baef5 100644 --- a/crates/ide-completion/src/render/function.rs +++ b/crates/ide-completion/src/render/function.rs @@ -8,8 +8,13 @@ use syntax::{format_smolstr, AstNode, SmolStr}; use crate::{ context::{CompletionContext, DotAccess, DotAccessKind, PathCompletionCtx, PathKind}, - item::{Builder, CompletionItem, CompletionItemKind, CompletionRelevance}, - render::{compute_exact_name_match, compute_ref_match, compute_type_match, RenderContext}, + item::{ + Builder, CompletionItem, CompletionItemKind, CompletionRelevance, CompletionRelevanceFn, + CompletionRelevanceReturnType, + }, + render::{ + compute_exact_name_match, compute_ref_match, compute_type_match, match_types, RenderContext, + }, CallableSnippets, }; @@ -99,13 +104,20 @@ fn render( .filter(|_| !has_call_parens) .and_then(|cap| Some((cap, params(ctx.completion, func, &func_kind, has_dot_receiver)?))); + let type_match = if has_call_parens || complete_call_parens.is_some() { + compute_type_match(completion, &ret_type) + } else { + compute_type_match(completion, &func.ty(db)) + }; + + let function = assoc_item + .and_then(|assoc_item| assoc_item.implementing_ty(db)) + .and_then(|self_type| compute_function_match(db, &ctx, self_type, func, &ret_type)); + item.set_relevance(CompletionRelevance { - type_match: if has_call_parens || complete_call_parens.is_some() { - compute_type_match(completion, &ret_type) - } else { - compute_type_match(completion, &func.ty(db)) - }, + type_match, exact_name_match: compute_exact_name_match(completion, &call), + function, is_op_method, is_item_from_notable_trait, ..ctx.completion_relevance() @@ -156,6 +168,39 @@ fn render( item } +fn compute_function_match( + db: &dyn HirDatabase, + ctx: &RenderContext<'_>, + self_type: hir::Type, + func: hir::Function, + func_return_type: &hir::Type, +) -> Option<CompletionRelevanceFn> { + let has_args = func.num_params(db) > 0; + let has_self_arg = func.self_param(db).is_some(); + + let return_type = if match_types(ctx.completion, &self_type, &func_return_type).is_some() { + // fn([..]) -> Self + CompletionRelevanceReturnType::DirectConstructor + } else if func_return_type + .type_arguments() + .any(|ret_type_arg| match_types(ctx.completion, &self_type, &ret_type_arg).is_some()) + { + // fn([..]) -> Result<Self, E> OR Wrapped<Foo, Self> + CompletionRelevanceReturnType::Constructor + } else if func_return_type + .as_adt() + .and_then(|adt| adt.name(db).as_str().map(|name| name.ends_with("Builder"))) + .unwrap_or(false) + { + // fn([..]) -> [..]Builder + CompletionRelevanceReturnType::Builder + } else { + CompletionRelevanceReturnType::Other + }; + + Some(CompletionRelevanceFn { return_type, has_args, has_self_arg }) +} + pub(super) fn add_call_parens<'b>( builder: &'b mut Builder, ctx: &CompletionContext<'_>, |