aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion/src/render.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_completion/src/render.rs')
-rw-r--r--crates/ide_completion/src/render.rs45
1 files changed, 25 insertions, 20 deletions
diff --git a/crates/ide_completion/src/render.rs b/crates/ide_completion/src/render.rs
index eddaaa6f3..0a6ac8804 100644
--- a/crates/ide_completion/src/render.rs
+++ b/crates/ide_completion/src/render.rs
@@ -13,9 +13,11 @@ mod builder_ext;
13use hir::{ 13use hir::{
14 AsAssocItem, Documentation, HasAttrs, HirDisplay, ModuleDef, Mutability, ScopeDef, Type, 14 AsAssocItem, Documentation, HasAttrs, HirDisplay, ModuleDef, Mutability, ScopeDef, Type,
15}; 15};
16use ide_db::{helpers::SnippetCap, RootDatabase, SymbolKind}; 16use ide_db::{
17 helpers::{item_name, SnippetCap},
18 RootDatabase, SymbolKind,
19};
17use syntax::TextRange; 20use syntax::TextRange;
18use test_utils::mark;
19 21
20use crate::{ 22use crate::{
21 item::ImportEdit, CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, 23 item::ImportEdit, CompletionContext, CompletionItem, CompletionItemKind, CompletionKind,
@@ -51,18 +53,20 @@ pub(crate) fn render_resolution<'a>(
51pub(crate) fn render_resolution_with_import<'a>( 53pub(crate) fn render_resolution_with_import<'a>(
52 ctx: RenderContext<'a>, 54 ctx: RenderContext<'a>,
53 import_edit: ImportEdit, 55 import_edit: ImportEdit,
54 resolution: &ScopeDef,
55) -> Option<CompletionItem> { 56) -> Option<CompletionItem> {
57 let resolution = ScopeDef::from(import_edit.import.original_item);
56 let local_name = match resolution { 58 let local_name = match resolution {
57 ScopeDef::ModuleDef(ModuleDef::Function(f)) => f.name(ctx.completion.db).to_string(), 59 ScopeDef::ModuleDef(ModuleDef::Function(f)) => f.name(ctx.completion.db).to_string(),
58 ScopeDef::ModuleDef(ModuleDef::Const(c)) => c.name(ctx.completion.db)?.to_string(), 60 ScopeDef::ModuleDef(ModuleDef::Const(c)) => c.name(ctx.completion.db)?.to_string(),
59 ScopeDef::ModuleDef(ModuleDef::TypeAlias(t)) => t.name(ctx.completion.db).to_string(), 61 ScopeDef::ModuleDef(ModuleDef::TypeAlias(t)) => t.name(ctx.completion.db).to_string(),
60 _ => import_edit.import_path.segments().last()?.to_string(), 62 _ => item_name(ctx.db(), import_edit.import.original_item)?.to_string(),
61 }; 63 };
62 Render::new(ctx).render_resolution(local_name, Some(import_edit), resolution).map(|mut item| { 64 Render::new(ctx).render_resolution(local_name, Some(import_edit), &resolution).map(
63 item.completion_kind = CompletionKind::Magic; 65 |mut item| {
64 item 66 item.completion_kind = CompletionKind::Magic;
65 }) 67 item
68 },
69 )
66} 70}
67 71
68/// Interface for data and methods required for items rendering. 72/// Interface for data and methods required for items rendering.
@@ -115,11 +119,11 @@ impl<'a> RenderContext<'a> {
115 119
116 fn active_name_and_type(&self) -> Option<(String, Type)> { 120 fn active_name_and_type(&self) -> Option<(String, Type)> {
117 if let Some(record_field) = &self.completion.record_field_syntax { 121 if let Some(record_field) = &self.completion.record_field_syntax {
118 mark::hit!(record_field_type_match); 122 cov_mark::hit!(record_field_type_match);
119 let (struct_field, _local) = self.completion.sema.resolve_record_field(record_field)?; 123 let (struct_field, _local) = self.completion.sema.resolve_record_field(record_field)?;
120 Some((struct_field.name(self.db()).to_string(), struct_field.signature_ty(self.db()))) 124 Some((struct_field.name(self.db()).to_string(), struct_field.signature_ty(self.db())))
121 } else if let Some(active_parameter) = &self.completion.active_parameter { 125 } else if let Some(active_parameter) = &self.completion.active_parameter {
122 mark::hit!(active_param_type_match); 126 cov_mark::hit!(active_param_type_match);
123 Some((active_parameter.name.clone(), active_parameter.ty.clone())) 127 Some((active_parameter.name.clone(), active_parameter.ty.clone()))
124 } else { 128 } else {
125 None 129 None
@@ -242,7 +246,6 @@ impl<'a> Render<'a> {
242 } 246 }
243 }; 247 };
244 248
245 let mut ref_match = None;
246 if let ScopeDef::Local(local) = resolution { 249 if let ScopeDef::Local(local) = resolution {
247 if let Some((active_name, active_type)) = self.ctx.active_name_and_type() { 250 if let Some((active_name, active_type)) = self.ctx.active_name_and_type() {
248 let ty = local.ty(self.ctx.db()); 251 let ty = local.ty(self.ctx.db());
@@ -251,7 +254,11 @@ impl<'a> Render<'a> {
251 { 254 {
252 item = item.set_score(score); 255 item = item.set_score(score);
253 } 256 }
254 ref_match = refed_type_matches(&active_type, &active_name, &ty, &local_name); 257 if let Some(ref_match) =
258 refed_type_matches(&active_type, &active_name, &ty, &local_name)
259 {
260 item = item.ref_match(ref_match);
261 }
255 } 262 }
256 } 263 }
257 264
@@ -269,7 +276,7 @@ impl<'a> Render<'a> {
269 _ => false, 276 _ => false,
270 }; 277 };
271 if has_non_default_type_params { 278 if has_non_default_type_params {
272 mark::hit!(inserts_angle_brackets_for_generics); 279 cov_mark::hit!(inserts_angle_brackets_for_generics);
273 item = item 280 item = item
274 .lookup_by(local_name.clone()) 281 .lookup_by(local_name.clone())
275 .label(format!("{}<…>", local_name)) 282 .label(format!("{}<…>", local_name))
@@ -281,7 +288,6 @@ impl<'a> Render<'a> {
281 Some( 288 Some(
282 item.kind(kind) 289 item.kind(kind)
283 .add_import(import_to_add) 290 .add_import(import_to_add)
284 .set_ref_match(ref_match)
285 .set_documentation(self.docs(resolution)) 291 .set_documentation(self.docs(resolution))
286 .set_deprecated(self.is_deprecated(resolution)) 292 .set_deprecated(self.is_deprecated(resolution))
287 .build(), 293 .build(),
@@ -358,7 +364,6 @@ mod tests {
358 use std::cmp::Reverse; 364 use std::cmp::Reverse;
359 365
360 use expect_test::{expect, Expect}; 366 use expect_test::{expect, Expect};
361 use test_utils::mark;
362 367
363 use crate::{ 368 use crate::{
364 test_utils::{check_edit, do_completion, get_all_items, TEST_CONFIG}, 369 test_utils::{check_edit, do_completion, get_all_items, TEST_CONFIG},
@@ -734,7 +739,7 @@ fn foo(s: S) { s.$0 }
734 739
735 #[test] 740 #[test]
736 fn no_call_parens_if_fn_ptr_needed() { 741 fn no_call_parens_if_fn_ptr_needed() {
737 mark::check!(no_call_parens_if_fn_ptr_needed); 742 cov_mark::check!(no_call_parens_if_fn_ptr_needed);
738 check_edit( 743 check_edit(
739 "foo", 744 "foo",
740 r#" 745 r#"
@@ -758,7 +763,7 @@ fn main() -> ManualVtable {
758 763
759 #[test] 764 #[test]
760 fn no_parens_in_use_item() { 765 fn no_parens_in_use_item() {
761 mark::check!(no_parens_in_use_item); 766 cov_mark::check!(no_parens_in_use_item);
762 check_edit( 767 check_edit(
763 "foo", 768 "foo",
764 r#" 769 r#"
@@ -802,7 +807,7 @@ fn f(foo: &Foo) { foo.foo(); }
802 807
803 #[test] 808 #[test]
804 fn inserts_angle_brackets_for_generics() { 809 fn inserts_angle_brackets_for_generics() {
805 mark::check!(inserts_angle_brackets_for_generics); 810 cov_mark::check!(inserts_angle_brackets_for_generics);
806 check_edit( 811 check_edit(
807 "Vec", 812 "Vec",
808 r#" 813 r#"
@@ -851,7 +856,7 @@ fn foo(xs: Vec<i128>)
851 856
852 #[test] 857 #[test]
853 fn active_param_score() { 858 fn active_param_score() {
854 mark::check!(active_param_type_match); 859 cov_mark::check!(active_param_type_match);
855 check_scores( 860 check_scores(
856 r#" 861 r#"
857struct S { foo: i64, bar: u32, baz: u32 } 862struct S { foo: i64, bar: u32, baz: u32 }
@@ -868,7 +873,7 @@ fn foo(s: S) { test(s.$0) }
868 873
869 #[test] 874 #[test]
870 fn record_field_scores() { 875 fn record_field_scores() {
871 mark::check!(record_field_type_match); 876 cov_mark::check!(record_field_type_match);
872 check_scores( 877 check_scores(
873 r#" 878 r#"
874struct A { foo: i64, bar: u32, baz: u32 } 879struct A { foo: i64, bar: u32, baz: u32 }