@@ -20,8 +20,8 @@ use ide_db::{
20
20
use syntax:: TextRange ;
21
21
22
22
use crate :: {
23
- item:: ImportEdit , CompletionContext , CompletionItem , CompletionItemKind , CompletionKind ,
24
- CompletionScore ,
23
+ item:: { ImportEdit , Relevance } ,
24
+ CompletionContext , CompletionItem , CompletionItemKind , CompletionKind ,
25
25
} ;
26
26
27
27
use crate :: render:: { enum_variant:: render_variant, function:: render_fn, macro_:: render_macro} ;
@@ -117,7 +117,7 @@ impl<'a> RenderContext<'a> {
117
117
node. docs ( self . db ( ) )
118
118
}
119
119
120
- fn active_name_and_type ( & self ) -> Option < ( String , Type ) > {
120
+ fn expected_name_and_type ( & self ) -> Option < ( String , Type ) > {
121
121
if let Some ( record_field) = & self . completion . record_field_syntax {
122
122
cov_mark:: hit!( record_field_type_match) ;
123
123
let ( struct_field, _local) = self . completion . sema . resolve_record_field ( record_field) ?;
@@ -155,8 +155,8 @@ impl<'a> Render<'a> {
155
155
. set_documentation ( field. docs ( self . ctx . db ( ) ) )
156
156
. set_deprecated ( is_deprecated) ;
157
157
158
- if let Some ( score ) = compute_score ( & self . ctx , & ty, & name. to_string ( ) ) {
159
- item = item. set_score ( score ) ;
158
+ if let Some ( relevance ) = compute_relevance ( & self . ctx , & ty, & name. to_string ( ) ) {
159
+ item = item. set_relevance ( relevance ) ;
160
160
}
161
161
162
162
item. build ( )
@@ -247,18 +247,15 @@ impl<'a> Render<'a> {
247
247
} ;
248
248
249
249
if let ScopeDef :: Local ( local) = resolution {
250
- if let Some ( ( active_name, active_type) ) = self . ctx . active_name_and_type ( ) {
251
- let ty = local. ty ( self . ctx . db ( ) ) ;
252
- if let Some ( score) =
253
- compute_score_from_active ( & active_type, & active_name, & ty, & local_name)
254
- {
255
- item = item. set_score ( score) ;
256
- }
257
-
258
- if let Some ( ty_without_ref) = active_type. remove_ref ( ) {
250
+ let ty = local. ty ( self . ctx . db ( ) ) ;
251
+ if let Some ( relevance) = compute_relevance ( & self . ctx , & ty, & local_name) {
252
+ item = item. set_relevance ( relevance)
253
+ }
254
+ if let Some ( ( _expected_name, expected_type) ) = self . ctx . expected_name_and_type ( ) {
255
+ if let Some ( ty_without_ref) = expected_type. remove_ref ( ) {
259
256
if ty_without_ref == ty {
260
257
cov_mark:: hit!( suggest_ref) ;
261
- let mutability = if active_type . is_mutable_reference ( ) {
258
+ let mutability = if expected_type . is_mutable_reference ( ) {
262
259
Mutability :: Mut
263
260
} else {
264
261
Mutability :: Shared
@@ -326,33 +323,14 @@ impl<'a> Render<'a> {
326
323
}
327
324
}
328
325
329
- fn compute_score_from_active (
330
- active_type : & Type ,
331
- active_name : & str ,
332
- ty : & Type ,
333
- name : & str ,
334
- ) -> Option < CompletionScore > {
335
- // Compute score
336
- // For the same type
337
- if active_type != ty {
338
- return None ;
339
- }
340
-
341
- let mut res = CompletionScore :: TypeMatch ;
342
-
343
- // If same type + same name then go top position
344
- if active_name == name {
345
- res = CompletionScore :: TypeAndNameMatch
346
- }
347
-
326
+ fn compute_relevance ( ctx : & RenderContext , ty : & Type , name : & str ) -> Option < Relevance > {
327
+ let ( expected_name, expected_type) = ctx. expected_name_and_type ( ) ?;
328
+ let mut res = Relevance :: default ( ) ;
329
+ res. exact_type_match = ty == & expected_type;
330
+ res. exact_name_match = name == & expected_name;
348
331
Some ( res)
349
332
}
350
333
351
- fn compute_score ( ctx : & RenderContext , ty : & Type , name : & str ) -> Option < CompletionScore > {
352
- let ( active_name, active_type) = ctx. active_name_and_type ( ) ?;
353
- compute_score_from_active ( & active_type, & active_name, ty, name)
354
- }
355
-
356
334
#[ cfg( test) ]
357
335
mod tests {
358
336
use std:: cmp:: Reverse ;
@@ -361,32 +339,33 @@ mod tests {
361
339
362
340
use crate :: {
363
341
test_utils:: { check_edit, do_completion, get_all_items, TEST_CONFIG } ,
364
- CompletionKind , CompletionScore ,
342
+ CompletionKind , Relevance ,
365
343
} ;
366
344
367
345
fn check ( ra_fixture : & str , expect : Expect ) {
368
346
let actual = do_completion ( ra_fixture, CompletionKind :: Reference ) ;
369
347
expect. assert_debug_eq ( & actual) ;
370
348
}
371
349
372
- fn check_scores ( ra_fixture : & str , expect : Expect ) {
373
- fn display_score ( score : Option < CompletionScore > ) -> & ' static str {
374
- match score {
375
- Some ( CompletionScore :: TypeMatch ) => "[type]" ,
376
- Some ( CompletionScore :: TypeAndNameMatch ) => "[type+name]" ,
377
- None => "[]" . into ( ) ,
350
+ fn check_relevance ( ra_fixture : & str , expect : Expect ) {
351
+ fn display_relevance ( relevance : Relevance ) -> & ' static str {
352
+ match relevance {
353
+ Relevance { exact_type_match : true , exact_name_match : true } => "[type+name]" ,
354
+ Relevance { exact_type_match : true , exact_name_match : false } => "[type]" ,
355
+ Relevance { exact_type_match : false , exact_name_match : true } => "[name]" ,
356
+ Relevance { exact_type_match : false , exact_name_match : false } => "[]" ,
378
357
}
379
358
}
380
359
381
360
let mut completions = get_all_items ( TEST_CONFIG , ra_fixture) ;
382
- completions. sort_by_key ( |it| ( Reverse ( it. score ( ) ) , it. label ( ) . to_string ( ) ) ) ;
361
+ completions. sort_by_key ( |it| ( Reverse ( it. relevance ( ) ) , it. label ( ) . to_string ( ) ) ) ;
383
362
let actual = completions
384
363
. into_iter ( )
385
364
. filter ( |it| it. completion_kind == CompletionKind :: Reference )
386
365
. map ( |it| {
387
366
let tag = it. kind ( ) . unwrap ( ) . tag ( ) ;
388
- let score = display_score ( it. score ( ) ) ;
389
- format ! ( "{} {} {}\n " , tag, it. label( ) , score )
367
+ let relevance = display_relevance ( it. relevance ( ) ) ;
368
+ format ! ( "{} {} {}\n " , tag, it. label( ) , relevance )
390
369
} )
391
370
. collect :: < String > ( ) ;
392
371
expect. assert_eq ( & actual) ;
@@ -849,9 +828,9 @@ fn foo(xs: Vec<i128>)
849
828
}
850
829
851
830
#[ test]
852
- fn active_param_score ( ) {
831
+ fn active_param_relevance ( ) {
853
832
cov_mark:: check!( active_param_type_match) ;
854
- check_scores (
833
+ check_relevance (
855
834
r#"
856
835
struct S { foo: i64, bar: u32, baz: u32 }
857
836
fn test(bar: u32) { }
@@ -866,9 +845,9 @@ fn foo(s: S) { test(s.$0) }
866
845
}
867
846
868
847
#[ test]
869
- fn record_field_scores ( ) {
848
+ fn record_field_relevances ( ) {
870
849
cov_mark:: check!( record_field_type_match) ;
871
- check_scores (
850
+ check_relevance (
872
851
r#"
873
852
struct A { foo: i64, bar: u32, baz: u32 }
874
853
struct B { x: (), y: f32, bar: u32 }
@@ -883,8 +862,8 @@ fn foo(a: A) { B { bar: a.$0 }; }
883
862
}
884
863
885
864
#[ test]
886
- fn record_field_and_call_scores ( ) {
887
- check_scores (
865
+ fn record_field_and_call_relevances ( ) {
866
+ check_relevance (
888
867
r#"
889
868
struct A { foo: i64, bar: u32, baz: u32 }
890
869
struct B { x: (), y: f32, bar: u32 }
@@ -897,7 +876,7 @@ fn foo(a: A) { B { bar: f(a.$0) }; }
897
876
fd baz []
898
877
"# ] ] ,
899
878
) ;
900
- check_scores (
879
+ check_relevance (
901
880
r#"
902
881
struct A { foo: i64, bar: u32, baz: u32 }
903
882
struct B { x: (), y: f32, bar: u32 }
@@ -914,7 +893,7 @@ fn foo(a: A) { f(B { bar: a.$0 }); }
914
893
915
894
#[ test]
916
895
fn prioritize_exact_ref_match ( ) {
917
- check_scores (
896
+ check_relevance (
918
897
r#"
919
898
struct WorldSnapshot { _f: () };
920
899
fn go(world: &WorldSnapshot) { go(w$0) }
@@ -929,7 +908,7 @@ fn go(world: &WorldSnapshot) { go(w$0) }
929
908
930
909
#[ test]
931
910
fn too_many_arguments ( ) {
932
- check_scores (
911
+ check_relevance (
933
912
r#"
934
913
struct Foo;
935
914
fn f(foo: &Foo) { f(foo, w$0) }
@@ -997,6 +976,10 @@ fn main() {
997
976
Local,
998
977
),
999
978
detail: "S",
979
+ relevance: Relevance {
980
+ exact_name_match: true,
981
+ exact_type_match: false,
982
+ },
1000
983
ref_match: "&mut ",
1001
984
},
1002
985
]
0 commit comments