diff options
Diffstat (limited to 'crates/completion/src/presentation.rs')
-rw-r--r-- | crates/completion/src/presentation.rs | 51 |
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 | ||
4 | use hir::{HasAttrs, HasSource, HirDisplay, ModPath, ScopeDef, StructKind, Type}; | 4 | use hir::{HasAttrs, HasSource, HirDisplay, ModPath, Mutability, ScopeDef, StructKind, Type}; |
5 | use itertools::Itertools; | 5 | use itertools::Itertools; |
6 | use syntax::{ast::NameOwner, display::*}; | 6 | use syntax::{ast::NameOwner, display::*}; |
7 | use test_utils::mark; | 7 | use 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 | ||
345 | pub(crate) fn compute_score( | 352 | fn 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 | } |
373 | fn 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 | |||
387 | fn 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 | ||
377 | enum Params { | 392 | enum Params { |
378 | Named(Vec<String>), | 393 | Named(Vec<String>), |