aboutsummaryrefslogtreecommitdiff
path: root/crates/completion/src/render
diff options
context:
space:
mode:
Diffstat (limited to 'crates/completion/src/render')
-rw-r--r--crates/completion/src/render/builder_ext.rs1
-rw-r--r--crates/completion/src/render/enum_variant.rs45
-rw-r--r--crates/completion/src/render/pattern.rs80
3 files changed, 41 insertions, 85 deletions
diff --git a/crates/completion/src/render/builder_ext.rs b/crates/completion/src/render/builder_ext.rs
index ce8718bd5..d053a988b 100644
--- a/crates/completion/src/render/builder_ext.rs
+++ b/crates/completion/src/render/builder_ext.rs
@@ -34,7 +34,6 @@ impl Builder {
34 return false; 34 return false;
35 } 35 }
36 if ctx.is_pattern_call { 36 if ctx.is_pattern_call {
37 mark::hit!(dont_duplicate_pattern_parens);
38 return false; 37 return false;
39 } 38 }
40 if ctx.is_call { 39 if ctx.is_call {
diff --git a/crates/completion/src/render/enum_variant.rs b/crates/completion/src/render/enum_variant.rs
index 7176fd9b3..732e139ec 100644
--- a/crates/completion/src/render/enum_variant.rs
+++ b/crates/completion/src/render/enum_variant.rs
@@ -126,50 +126,5 @@ fn main() -> Option<i32> {
126} 126}
127"#, 127"#,
128 ); 128 );
129 check_edit(
130 "Some",
131 r#"
132enum Option<T> { Some(T), None }
133use Option::*;
134fn main(value: Option<i32>) {
135 match value {
136 Som<|>
137 }
138}
139"#,
140 r#"
141enum Option<T> { Some(T), None }
142use Option::*;
143fn main(value: Option<i32>) {
144 match value {
145 Some($0)
146 }
147}
148"#,
149 );
150 }
151
152 #[test]
153 fn dont_duplicate_pattern_parens() {
154 mark::check!(dont_duplicate_pattern_parens);
155 check_edit(
156 "Var",
157 r#"
158enum E { Var(i32) }
159fn main() {
160 match E::Var(92) {
161 E::<|>(92) => (),
162 }
163}
164"#,
165 r#"
166enum E { Var(i32) }
167fn main() {
168 match E::Var(92) {
169 E::Var(92) => (),
170 }
171}
172"#,
173 );
174 } 129 }
175} 130}
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(