aboutsummaryrefslogtreecommitdiff
path: root/crates/completion/src/render/pattern.rs
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2020-12-22 18:00:38 +0000
committerLukas Wirth <[email protected]>2020-12-22 18:00:38 +0000
commit83121efcd577124a992dc8bd304690b36bda2931 (patch)
tree7c936ea2d9ceb39192046ac5cc504a52e6dbcf79 /crates/completion/src/render/pattern.rs
parent2cd2947bf8cb7abfb06ceb00804447def899d37d (diff)
Reduce some more code duplication
Diffstat (limited to 'crates/completion/src/render/pattern.rs')
-rw-r--r--crates/completion/src/render/pattern.rs80
1 files changed, 41 insertions, 39 deletions
diff --git a/crates/completion/src/render/pattern.rs b/crates/completion/src/render/pattern.rs
index 073d50a11..a3b6a3cac 100644
--- a/crates/completion/src/render/pattern.rs
+++ b/crates/completion/src/render/pattern.rs
@@ -8,6 +8,24 @@ use crate::{
8 CompletionItemKind, 8 CompletionItemKind,
9}; 9};
10 10
11fn 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
11pub(crate) fn render_struct_pat( 29pub(crate) fn render_struct_pat(
12 ctx: RenderContext<'_>, 30 ctx: RenderContext<'_>,
13 strukt: hir::Struct, 31 strukt: hir::Struct,
@@ -15,35 +33,18 @@ pub(crate) fn render_struct_pat(
15) -> Option<CompletionItem> { 33) -> Option<CompletionItem> {
16 let _p = profile::span("render_struct_pat"); 34 let _p = profile::span("render_struct_pat");
17 35
18 let module = ctx.completion.scope.module()?;
19 let fields = strukt.fields(ctx.db()); 36 let fields = strukt.fields(ctx.db());
20 let n_fields = fields.len(); 37 let (visible_fields, fields_omitted) = visible_fields(&ctx, &fields, strukt)?;
21 let fields = fields
22 .into_iter()
23 .filter(|field| field.is_visible_from(ctx.db(), module))
24 .collect::<Vec<_>>();
25 38
26 if fields.is_empty() { 39 if visible_fields.is_empty() {
27 // Matching a struct without matching its fields is pointless, unlike matching a Variant without its fields 40 // Matching a struct without matching its fields is pointless, unlike matching a Variant without its fields
28 return None; 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 let name = local_name.unwrap_or_else(|| strukt.name(ctx.db())).to_string(); 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) 47 Some(build_completion(ctx, name, pat, strukt))
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} 48}
48 49
49pub(crate) fn render_variant_pat( 50pub(crate) fn render_variant_pat(
@@ -53,31 +54,32 @@ pub(crate) fn render_variant_pat(
53) -> Option<CompletionItem> { 54) -> Option<CompletionItem> {
54 let _p = profile::span("render_variant_pat"); 55 let _p = profile::span("render_variant_pat");
55 56
56 let module = ctx.completion.scope.module()?;
57 let fields = variant.fields(ctx.db()); 57 let fields = variant.fields(ctx.db());
58 let n_fields = fields.len(); 58 let (visible_fields, fields_omitted) = visible_fields(&ctx, &fields, variant)?;
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();
66 59
67 let name = local_name.unwrap_or_else(|| variant.name(ctx.db())).to_string(); 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
66fn 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 .kind(CompletionItemKind::Binding) 73 .kind(CompletionItemKind::Binding)
72 .set_documentation(ctx.docs(variant)) 74 .set_documentation(ctx.docs(item))
73 .set_deprecated(ctx.is_deprecated(variant)) 75 .set_deprecated(ctx.is_deprecated(item))
74 .detail(&pat); 76 .detail(&pat);
75 if let Some(snippet_cap) = ctx.snippet_cap() { 77 let completion = if let Some(snippet_cap) = ctx.snippet_cap() {
76 completion = completion.insert_snippet(snippet_cap, pat); 78 completion.insert_snippet(snippet_cap, pat)
77 } else { 79 } else {
78 completion = completion.insert_text(pat); 80 completion.insert_text(pat)
79 } 81 };
80 Some(completion.build()) 82 completion.build()
81} 83}
82 84
83fn render_pat( 85fn render_pat(