aboutsummaryrefslogtreecommitdiff
path: root/crates/completion/src/presentation.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/completion/src/presentation.rs')
-rw-r--r--crates/completion/src/presentation.rs51
1 files changed, 33 insertions, 18 deletions
diff --git a/crates/completion/src/presentation.rs b/crates/completion/src/presentation.rs
index 0a0dc1ce5..2a19281cf 100644
--- a/crates/completion/src/presentation.rs
+++ b/crates/completion/src/presentation.rs
@@ -1,7 +1,7 @@
1//! This modules takes care of rendering various definitions as completion items. 1//! This modules takes care of rendering various definitions as completion items.
2//! It also handles scoring (sorting) completions. 2//! It also handles scoring (sorting) completions.
3 3
4use hir::{HasAttrs, HasSource, HirDisplay, ModPath, ScopeDef, StructKind, Type}; 4use hir::{HasAttrs, HasSource, HirDisplay, ModPath, Mutability, ScopeDef, StructKind, Type};
5use itertools::Itertools; 5use itertools::Itertools;
6use syntax::{ast::NameOwner, display::*}; 6use syntax::{ast::NameOwner, display::*};
7use test_utils::mark; 7use test_utils::mark;
@@ -107,9 +107,16 @@ impl Completions {
107 } 107 }
108 }; 108 };
109 109
110 let mut ref_match = None;
110 if let ScopeDef::Local(local) = resolution { 111 if let ScopeDef::Local(local) = resolution {
111 if let Some(score) = compute_score(ctx, &local.ty(ctx.db), &local_name) { 112 if let Some((active_name, active_type)) = ctx.active_name_and_type() {
112 completion_item = completion_item.set_score(score); 113 let ty = local.ty(ctx.db);
114 if let Some(score) =
115 compute_score_from_active(&active_type, &active_name, &ty, &local_name)
116 {
117 completion_item = completion_item.set_score(score);
118 }
119 ref_match = refed_type_matches(&active_type, &active_name, &ty, &local_name);
113 } 120 }
114 } 121 }
115 122
@@ -131,7 +138,7 @@ impl Completions {
131 } 138 }
132 } 139 }
133 140
134 completion_item.kind(kind).set_documentation(docs).add_to(self) 141 completion_item.kind(kind).set_documentation(docs).set_ref_match(ref_match).add_to(self)
135 } 142 }
136 143
137 pub(crate) fn add_macro( 144 pub(crate) fn add_macro(
@@ -342,25 +349,15 @@ impl Completions {
342 } 349 }
343} 350}
344 351
345pub(crate) fn compute_score( 352fn compute_score_from_active(
346 ctx: &CompletionContext, 353 active_type: &Type,
354 active_name: &str,
347 ty: &Type, 355 ty: &Type,
348 name: &str, 356 name: &str,
349) -> Option<CompletionScore> { 357) -> Option<CompletionScore> {
350 let (active_name, active_type) = if let Some(record_field) = &ctx.record_field_syntax {
351 mark::hit!(record_field_type_match);
352 let (struct_field, _local) = ctx.sema.resolve_record_field(record_field)?;
353 (struct_field.name(ctx.db).to_string(), struct_field.signature_ty(ctx.db))
354 } else if let Some(active_parameter) = &ctx.active_parameter {
355 mark::hit!(active_param_type_match);
356 (active_parameter.name.clone(), active_parameter.ty.clone())
357 } else {
358 return None;
359 };
360
361 // Compute score 358 // Compute score
362 // For the same type 359 // For the same type
363 if &active_type != ty { 360 if active_type != ty {
364 return None; 361 return None;
365 } 362 }
366 363
@@ -373,6 +370,24 @@ pub(crate) fn compute_score(
373 370
374 Some(res) 371 Some(res)
375} 372}
373fn refed_type_matches(
374 active_type: &Type,
375 active_name: &str,
376 ty: &Type,
377 name: &str,
378) -> Option<(Mutability, CompletionScore)> {
379 let derefed_active = active_type.remove_ref()?;
380 let score = compute_score_from_active(&derefed_active, &active_name, &ty, &name)?;
381 Some((
382 if active_type.is_mutable_reference() { Mutability::Mut } else { Mutability::Shared },
383 score,
384 ))
385}
386
387fn compute_score(ctx: &CompletionContext, ty: &Type, name: &str) -> Option<CompletionScore> {
388 let (active_name, active_type) = ctx.active_name_and_type()?;
389 compute_score_from_active(&active_type, &active_name, ty, name)
390}
376 391
377enum Params { 392enum Params {
378 Named(Vec<String>), 393 Named(Vec<String>),