aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion/src/render
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_completion/src/render')
-rw-r--r--crates/ide_completion/src/render/enum_variant.rs13
-rw-r--r--crates/ide_completion/src/render/function.rs66
-rw-r--r--crates/ide_completion/src/render/pattern.rs36
3 files changed, 80 insertions, 35 deletions
diff --git a/crates/ide_completion/src/render/enum_variant.rs b/crates/ide_completion/src/render/enum_variant.rs
index e8cfcc0c7..374247b05 100644
--- a/crates/ide_completion/src/render/enum_variant.rs
+++ b/crates/ide_completion/src/render/enum_variant.rs
@@ -6,7 +6,8 @@ use itertools::Itertools;
6 6
7use crate::{ 7use crate::{
8 item::{CompletionItem, CompletionKind, ImportEdit}, 8 item::{CompletionItem, CompletionKind, ImportEdit},
9 render::{builder_ext::Params, RenderContext}, 9 render::{builder_ext::Params, compute_exact_type_match, compute_ref_match, RenderContext},
10 CompletionRelevance,
10}; 11};
11 12
12pub(crate) fn render_variant<'a>( 13pub(crate) fn render_variant<'a>(
@@ -74,6 +75,16 @@ impl<'a> EnumRender<'a> {
74 item.lookup_by(self.short_qualified_name); 75 item.lookup_by(self.short_qualified_name);
75 } 76 }
76 77
78 let ty = self.variant.parent_enum(self.ctx.completion.db).ty(self.ctx.completion.db);
79 item.set_relevance(CompletionRelevance {
80 exact_type_match: compute_exact_type_match(self.ctx.completion, &ty),
81 ..CompletionRelevance::default()
82 });
83
84 if let Some(ref_match) = compute_ref_match(self.ctx.completion, &ty) {
85 item.ref_match(ref_match);
86 }
87
77 item.build() 88 item.build()
78 } 89 }
79 90
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 {
diff --git a/crates/ide_completion/src/render/pattern.rs b/crates/ide_completion/src/render/pattern.rs
index ca2926125..b4e80f424 100644
--- a/crates/ide_completion/src/render/pattern.rs
+++ b/crates/ide_completion/src/render/pattern.rs
@@ -6,24 +6,6 @@ use itertools::Itertools;
6 6
7use crate::{item::CompletionKind, render::RenderContext, CompletionItem, CompletionItemKind}; 7use crate::{item::CompletionKind, render::RenderContext, CompletionItem, CompletionItemKind};
8 8
9fn visible_fields(
10 ctx: &RenderContext<'_>,
11 fields: &[hir::Field],
12 item: impl HasAttrs,
13) -> Option<(Vec<hir::Field>, bool)> {
14 let module = ctx.completion.scope.module()?;
15 let n_fields = fields.len();
16 let fields = fields
17 .into_iter()
18 .filter(|field| field.is_visible_from(ctx.db(), module))
19 .copied()
20 .collect::<Vec<_>>();
21
22 let fields_omitted =
23 n_fields - fields.len() > 0 || item.attrs(ctx.db()).by_key("non_exhaustive").exists();
24 Some((fields, fields_omitted))
25}
26
27pub(crate) fn render_struct_pat( 9pub(crate) fn render_struct_pat(
28 ctx: RenderContext<'_>, 10 ctx: RenderContext<'_>,
29 strukt: hir::Struct, 11 strukt: hir::Struct,
@@ -148,3 +130,21 @@ fn render_tuple_as_pat(fields: &[hir::Field], name: &str, fields_omitted: bool)
148 name = name 130 name = name
149 ) 131 )
150} 132}
133
134fn visible_fields(
135 ctx: &RenderContext<'_>,
136 fields: &[hir::Field],
137 item: impl HasAttrs,
138) -> Option<(Vec<hir::Field>, bool)> {
139 let module = ctx.completion.scope.module()?;
140 let n_fields = fields.len();
141 let fields = fields
142 .into_iter()
143 .filter(|field| field.is_visible_from(ctx.db(), module))
144 .copied()
145 .collect::<Vec<_>>();
146
147 let fields_omitted =
148 n_fields - fields.len() > 0 || item.attrs(ctx.db()).by_key("non_exhaustive").exists();
149 Some((fields, fields_omitted))
150}