From 90c62bcee9d1950d0e4b642fc2bd3ae5374e40cb Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 14 May 2020 15:15:52 +0200 Subject: Prioritize locals with correct types --- crates/ra_ide/src/completion/presentation.rs | 58 ++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 4 deletions(-) (limited to 'crates/ra_ide/src/completion/presentation.rs') diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs index 2edb130cf..077cf9647 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs @@ -17,12 +17,11 @@ use crate::{ impl Completions { pub(crate) fn add_field(&mut self, ctx: &CompletionContext, field: hir::Field, ty: &Type) { let is_deprecated = is_deprecated(field, ctx.db); - let ty = ty.display(ctx.db).to_string(); let name = field.name(ctx.db); let mut completion_item = CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.to_string()) .kind(CompletionItemKind::Field) - .detail(ty.clone()) + .detail(ty.display(ctx.db).to_string()) .set_documentation(field.docs(ctx.db)) .set_deprecated(is_deprecated); @@ -107,6 +106,12 @@ impl Completions { } }; + if let ScopeDef::Local(local) = resolution { + if let Some(score) = compute_score(ctx, &local.ty(ctx.db), &local_name) { + completion_item = completion_item.set_score(score); + } + } + // Add `<>` for generic types if ctx.is_path_type && !ctx.has_type_args && ctx.config.add_call_parenthesis { if let Some(cap) = ctx.config.snippet_cap { @@ -319,10 +324,11 @@ impl Completions { pub(crate) fn compute_score( ctx: &CompletionContext, - // FIXME: this definitely should be a `Type` - ty: &str, + ty: &Type, name: &str, ) -> Option { + // FIXME: this should not fall back to string equality. + let ty = &ty.display(ctx.db).to_string(); let (active_name, active_type) = if let Some(record_field) = &ctx.record_field_syntax { tested_by!(test_struct_field_completion_in_record_lit); let (struct_field, _local) = ctx.sema.resolve_record_field(record_field)?; @@ -1405,4 +1411,48 @@ mod tests { "### ); } + + #[test] + fn prioritize_exact_ref_match() { + assert_debug_snapshot!( + do_reference_completion( + r" + struct WorldSnapshot { _f: () }; + fn go(world: &WorldSnapshot) { + go(w<|>) + } + ", + ), + @r###" + [ + CompletionItem { + label: "WorldSnapshot", + source_range: 132..133, + delete: 132..133, + insert: "WorldSnapshot", + kind: Struct, + }, + CompletionItem { + label: "go(…)", + source_range: 132..133, + delete: 132..133, + insert: "go(${1:world})$0", + kind: Function, + lookup: "go", + detail: "fn go(world: &WorldSnapshot)", + trigger_call_info: true, + }, + CompletionItem { + label: "world", + source_range: 132..133, + delete: 132..133, + insert: "world", + kind: Binding, + detail: "&WorldSnapshot", + score: TypeAndNameMatch, + }, + ] + "### + ); + } } -- cgit v1.2.3 From ecac5d7de2192873c24b7b06d4964d188d8abe6a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 May 2020 12:59:20 +0200 Subject: Switch to new magic marks --- crates/ra_ide/src/completion/presentation.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'crates/ra_ide/src/completion/presentation.rs') diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs index 077cf9647..440ffa31d 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs @@ -3,7 +3,7 @@ use hir::{Docs, HasAttrs, HasSource, HirDisplay, ModPath, ScopeDef, StructKind, Type}; use ra_syntax::ast::NameOwner; use stdx::SepBy; -use test_utils::tested_by; +use test_utils::mark; use crate::{ completion::{ @@ -121,7 +121,7 @@ impl Completions { _ => false, }; if has_non_default_type_params { - tested_by!(inserts_angle_brackets_for_generics); + mark::hit!(inserts_angle_brackets_for_generics); completion_item = completion_item .lookup_by(local_name.clone()) .label(format!("{}<…>", local_name)) @@ -176,7 +176,7 @@ impl Completions { } None if needs_bang => builder.insert_text(format!("{}!", name)), _ => { - tested_by!(dont_insert_macro_call_parens_unncessary); + mark::hit!(dont_insert_macro_call_parens_unncessary); builder.insert_text(name) } }; @@ -330,14 +330,14 @@ pub(crate) fn compute_score( // FIXME: this should not fall back to string equality. let ty = &ty.display(ctx.db).to_string(); let (active_name, active_type) = if let Some(record_field) = &ctx.record_field_syntax { - tested_by!(test_struct_field_completion_in_record_lit); + mark::hit!(test_struct_field_completion_in_record_lit); let (struct_field, _local) = ctx.sema.resolve_record_field(record_field)?; ( struct_field.name(ctx.db).to_string(), struct_field.signature_ty(ctx.db).display(ctx.db).to_string(), ) } else if let Some(active_parameter) = &ctx.active_parameter { - tested_by!(test_struct_field_completion_in_func_call); + mark::hit!(test_struct_field_completion_in_func_call); (active_parameter.name.clone(), active_parameter.ty.clone()) } else { return None; @@ -398,7 +398,7 @@ impl Builder { None => return self, }; // If not an import, add parenthesis automatically. - tested_by!(inserts_parens_for_function_calls); + mark::hit!(inserts_parens_for_function_calls); let (snippet, label) = if params.is_empty() { (format!("{}()$0", name), format!("{}()", name)) @@ -457,7 +457,7 @@ fn guess_macro_braces(macro_name: &str, docs: &str) -> (&'static str, &'static s #[cfg(test)] mod tests { use insta::assert_debug_snapshot; - use test_utils::covers; + use test_utils::mark; use crate::completion::{ test_utils::{do_completion, do_completion_with_options}, @@ -607,7 +607,7 @@ mod tests { #[test] fn inserts_parens_for_function_calls() { - covers!(inserts_parens_for_function_calls); + mark::check!(inserts_parens_for_function_calls); assert_debug_snapshot!( do_reference_completion( r" @@ -992,7 +992,7 @@ mod tests { #[test] fn inserts_angle_brackets_for_generics() { - covers!(inserts_angle_brackets_for_generics); + mark::check!(inserts_angle_brackets_for_generics); assert_debug_snapshot!( do_reference_completion( r" @@ -1115,7 +1115,7 @@ mod tests { #[test] fn dont_insert_macro_call_parens_unncessary() { - covers!(dont_insert_macro_call_parens_unncessary); + mark::check!(dont_insert_macro_call_parens_unncessary); assert_debug_snapshot!( do_reference_completion( r" @@ -1181,7 +1181,7 @@ mod tests { #[test] fn test_struct_field_completion_in_func_call() { - covers!(test_struct_field_completion_in_func_call); + mark::check!(test_struct_field_completion_in_func_call); assert_debug_snapshot!( do_reference_completion( r" @@ -1271,7 +1271,7 @@ mod tests { #[test] fn test_struct_field_completion_in_record_lit() { - covers!(test_struct_field_completion_in_record_lit); + mark::check!(test_struct_field_completion_in_record_lit); assert_debug_snapshot!( do_reference_completion( r" -- cgit v1.2.3