From db8bcf132c901cc9b9f993b17b1e648f55c35e78 Mon Sep 17 00:00:00 2001
From: Josh Mcguigan <joshmcg88@gmail.com>
Date: Fri, 12 Mar 2021 15:06:17 -0800
Subject: implement function completion scoring

---
 crates/ide_completion/src/render.rs          | 60 ++++++++++++++++++++++++++++
 crates/ide_completion/src/render/function.rs | 17 +++++++-
 2 files changed, 76 insertions(+), 1 deletion(-)

(limited to 'crates')

diff --git a/crates/ide_completion/src/render.rs b/crates/ide_completion/src/render.rs
index 670563e50..2514dda7c 100644
--- a/crates/ide_completion/src/render.rs
+++ b/crates/ide_completion/src/render.rs
@@ -927,6 +927,66 @@ fn f(foo: &Foo) { f(foo, w$0) }
         );
     }
 
+    #[test]
+    fn score_fn_type_and_name_match() {
+        check_relevance(
+            r#"
+struct A { bar: u8 }
+fn baz() -> u8 { 0 }
+fn bar() -> u8 { 0 }
+fn f() { A { bar: b$0 }; }
+"#,
+            expect![[r#"
+                fn baz() [type]
+                st A []
+                fn bar() [type+name]
+                fn f() []
+            "#]],
+        );
+    }
+
+    #[test]
+    fn score_method_type_and_name_match() {
+        check_relevance(
+            r#"
+fn baz(aaa: u32){}
+struct Foo;
+impl Foo {
+fn aaa(&self) -> u32 { 0 }
+fn bbb(&self) -> u32 { 0 }
+fn ccc(&self) -> u64 { 0 }
+}
+fn f() {
+    baz(Foo.$0
+}
+"#,
+            expect![[r#"
+                me aaa() [type+name]
+                me bbb() [type]
+                me ccc() []
+            "#]],
+        );
+    }
+
+    #[test]
+    fn score_method_name_match_only() {
+        check_relevance(
+            r#"
+fn baz(aaa: u32){}
+struct Foo;
+impl Foo {
+fn aaa(&self) -> u64 { 0 }
+}
+fn f() {
+    baz(Foo.$0
+}
+"#,
+            expect![[r#"
+                me aaa() [name]
+            "#]],
+        );
+    }
+
     #[test]
     fn suggest_ref_mut() {
         cov_mark::check!(suggest_ref);
diff --git a/crates/ide_completion/src/render/function.rs b/crates/ide_completion/src/render/function.rs
index f4dabe3d1..47e26a5d8 100644
--- a/crates/ide_completion/src/render/function.rs
+++ b/crates/ide_completion/src/render/function.rs
@@ -5,7 +5,7 @@ use ide_db::SymbolKind;
 use syntax::ast::Fn;
 
 use crate::{
-    item::{CompletionItem, CompletionItemKind, CompletionKind, ImportEdit},
+    item::{CompletionItem, CompletionItemKind, CompletionKind, CompletionRelevance, ImportEdit},
     render::{builder_ext::Params, RenderContext},
 };
 
@@ -55,6 +55,21 @@ impl<'a> FunctionRender<'a> {
             .add_call_parens(self.ctx.completion, self.name, params)
             .add_import(import_to_add);
 
+        let mut relevance = CompletionRelevance::default();
+        if let Some(expected_type) = &self.ctx.completion.expected_type {
+            let ret_ty = self.func.ret_type(self.ctx.db());
+
+            // We don't ever consider a function which returns unit type to be an
+            // exact type match, since nearly always this is not meaningful to the
+            // user.
+            relevance.exact_type_match = &ret_ty == expected_type && !ret_ty.is_unit();
+        }
+        if let Some(expected_name) = &self.ctx.completion.expected_name {
+            relevance.exact_name_match =
+                expected_name == &self.func.name(self.ctx.db()).to_string();
+        }
+        item.set_relevance(relevance);
+
         item.build()
     }
 
-- 
cgit v1.2.3