@@ -8,42 +8,43 @@ use crate::{
8
8
CompletionItemKind ,
9
9
} ;
10
10
11
+ fn visible_fields (
12
+ ctx : & RenderContext < ' _ > ,
13
+ fields : & [ hir:: Field ] ,
14
+ item : impl HasAttrs ,
15
+ ) -> Option < ( Vec < hir:: Field > , bool ) > {
16
+ let module = ctx. completion . scope . module ( ) ?;
17
+ let n_fields = fields. len ( ) ;
18
+ let fields = fields
19
+ . into_iter ( )
20
+ . filter ( |field| field. is_visible_from ( ctx. db ( ) , module) )
21
+ . copied ( )
22
+ . collect :: < Vec < _ > > ( ) ;
23
+
24
+ let fields_omitted =
25
+ n_fields - fields. len ( ) > 0 || item. attrs ( ctx. db ( ) ) . by_key ( "non_exhaustive" ) . exists ( ) ;
26
+ Some ( ( fields, fields_omitted) )
27
+ }
28
+
11
29
pub ( crate ) fn render_struct_pat (
12
30
ctx : RenderContext < ' _ > ,
13
31
strukt : hir:: Struct ,
14
32
local_name : Option < Name > ,
15
33
) -> Option < CompletionItem > {
16
34
let _p = profile:: span ( "render_struct_pat" ) ;
17
35
18
- let module = ctx. completion . scope . module ( ) ?;
19
36
let fields = strukt. fields ( ctx. db ( ) ) ;
20
- let n_fields = fields. len ( ) ;
21
- let fields = fields
22
- . into_iter ( )
23
- . filter ( |field| field. is_visible_from ( ctx. db ( ) , module) )
24
- . collect :: < Vec < _ > > ( ) ;
37
+ let ( visible_fields, fields_omitted) = visible_fields ( & ctx, & fields, strukt) ?;
25
38
26
- if fields . is_empty ( ) {
39
+ if visible_fields . is_empty ( ) {
27
40
// Matching a struct without matching its fields is pointless, unlike matching a Variant without its fields
28
41
return None ;
29
42
}
30
- let fields_omitted =
31
- n_fields - fields. len ( ) > 0 || strukt. attrs ( ctx. db ( ) ) . by_key ( "non_exhaustive" ) . exists ( ) ;
32
43
33
44
let name = local_name. unwrap_or_else ( || strukt. name ( ctx. db ( ) ) ) . to_string ( ) ;
34
- let pat = render_pat ( & ctx, & name, strukt. kind ( ctx. db ( ) ) , & fields , fields_omitted) ?;
45
+ let pat = render_pat ( & ctx, & name, strukt. kind ( ctx. db ( ) ) , & visible_fields , fields_omitted) ?;
35
46
36
- let mut completion = CompletionItem :: new ( CompletionKind :: Snippet , ctx. source_range ( ) , name)
37
- . kind ( CompletionItemKind :: Binding )
38
- . set_documentation ( ctx. docs ( strukt) )
39
- . set_deprecated ( ctx. is_deprecated ( strukt) )
40
- . detail ( & pat) ;
41
- if let Some ( snippet_cap) = ctx. snippet_cap ( ) {
42
- completion = completion. insert_snippet ( snippet_cap, pat) ;
43
- } else {
44
- completion = completion. insert_text ( pat) ;
45
- }
46
- Some ( completion. build ( ) )
47
+ Some ( build_completion ( ctx, name, pat, strukt) )
47
48
}
48
49
49
50
pub ( crate ) fn render_variant_pat (
@@ -53,31 +54,32 @@ pub(crate) fn render_variant_pat(
53
54
) -> Option < CompletionItem > {
54
55
let _p = profile:: span ( "render_variant_pat" ) ;
55
56
56
- let module = ctx. completion . scope . module ( ) ?;
57
57
let fields = variant. fields ( ctx. db ( ) ) ;
58
- let n_fields = fields. len ( ) ;
59
- let fields = fields
60
- . into_iter ( )
61
- . filter ( |field| field. is_visible_from ( ctx. db ( ) , module) )
62
- . collect :: < Vec < _ > > ( ) ;
63
-
64
- let fields_omitted =
65
- n_fields - fields. len ( ) > 0 || variant. attrs ( ctx. db ( ) ) . by_key ( "non_exhaustive" ) . exists ( ) ;
58
+ let ( visible_fields, fields_omitted) = visible_fields ( & ctx, & fields, variant) ?;
66
59
67
60
let name = local_name. unwrap_or_else ( || variant. name ( ctx. db ( ) ) ) . to_string ( ) ;
68
- let pat = render_pat ( & ctx, & name, variant. kind ( ctx. db ( ) ) , & fields , fields_omitted) ?;
61
+ let pat = render_pat ( & ctx, & name, variant. kind ( ctx. db ( ) ) , & visible_fields , fields_omitted) ?;
69
62
70
- let mut completion = CompletionItem :: new ( CompletionKind :: Snippet , ctx. source_range ( ) , name)
63
+ Some ( build_completion ( ctx, name, pat, variant) )
64
+ }
65
+
66
+ fn build_completion (
67
+ ctx : RenderContext < ' _ > ,
68
+ name : String ,
69
+ pat : String ,
70
+ item : impl HasAttrs + Copy ,
71
+ ) -> CompletionItem {
72
+ let completion = CompletionItem :: new ( CompletionKind :: Snippet , ctx. source_range ( ) , name)
71
73
. kind ( CompletionItemKind :: Binding )
72
- . set_documentation ( ctx. docs ( variant ) )
73
- . set_deprecated ( ctx. is_deprecated ( variant ) )
74
+ . set_documentation ( ctx. docs ( item ) )
75
+ . set_deprecated ( ctx. is_deprecated ( item ) )
74
76
. detail ( & pat) ;
75
- if let Some ( snippet_cap) = ctx. snippet_cap ( ) {
76
- completion = completion . insert_snippet ( snippet_cap, pat) ;
77
+ let completion = if let Some ( snippet_cap) = ctx. snippet_cap ( ) {
78
+ completion. insert_snippet ( snippet_cap, pat)
77
79
} else {
78
- completion = completion . insert_text ( pat) ;
79
- }
80
- Some ( completion. build ( ) )
80
+ completion. insert_text ( pat)
81
+ } ;
82
+ completion. build ( )
81
83
}
82
84
83
85
fn render_pat (
0 commit comments