diff options
author | Aleksey Kladov <[email protected]> | 2021-02-17 14:53:31 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2021-02-17 14:53:31 +0000 |
commit | 3db64a400c78bbd2708e67ddc07df1001fff3f29 (patch) | |
tree | 5386aab9c452981be09bc3e4362643a34e6e3617 /crates/completion/src/render/pattern.rs | |
parent | 6334ce866ab095215381c4b72692b20a84d26e96 (diff) |
rename completion -> ide_completion
We don't have completion-related PRs in flight, so lets do it
Diffstat (limited to 'crates/completion/src/render/pattern.rs')
-rw-r--r-- | crates/completion/src/render/pattern.rs | 150 |
1 files changed, 0 insertions, 150 deletions
diff --git a/crates/completion/src/render/pattern.rs b/crates/completion/src/render/pattern.rs deleted file mode 100644 index 465dfe00c..000000000 --- a/crates/completion/src/render/pattern.rs +++ /dev/null | |||
@@ -1,150 +0,0 @@ | |||
1 | //! Renderer for patterns. | ||
2 | |||
3 | use hir::{db::HirDatabase, HasAttrs, HasVisibility, Name, StructKind}; | ||
4 | use ide_db::helpers::SnippetCap; | ||
5 | use itertools::Itertools; | ||
6 | |||
7 | use crate::{item::CompletionKind, render::RenderContext, CompletionItem, CompletionItemKind}; | ||
8 | |||
9 | fn visible_fields( | ||
10 | ctx: &RenderContext<'_>, | ||
11 | fields: &[hir::Field], | ||
12 | item: impl HasAttrs, | ||
13 | ) -> Option<(Vec<hir::Field>, bool)> { | ||
14 | let module = ctx.completion.scope.module()?; | ||
15 | let n_fields = fields.len(); | ||
16 | let fields = fields | ||
17 | .into_iter() | ||
18 | .filter(|field| field.is_visible_from(ctx.db(), module)) | ||
19 | .copied() | ||
20 | .collect::<Vec<_>>(); | ||
21 | |||
22 | let fields_omitted = | ||
23 | n_fields - fields.len() > 0 || item.attrs(ctx.db()).by_key("non_exhaustive").exists(); | ||
24 | Some((fields, fields_omitted)) | ||
25 | } | ||
26 | |||
27 | pub(crate) fn render_struct_pat( | ||
28 | ctx: RenderContext<'_>, | ||
29 | strukt: hir::Struct, | ||
30 | local_name: Option<Name>, | ||
31 | ) -> Option<CompletionItem> { | ||
32 | let _p = profile::span("render_struct_pat"); | ||
33 | |||
34 | let fields = strukt.fields(ctx.db()); | ||
35 | let (visible_fields, fields_omitted) = visible_fields(&ctx, &fields, strukt)?; | ||
36 | |||
37 | if visible_fields.is_empty() { | ||
38 | // Matching a struct without matching its fields is pointless, unlike matching a Variant without its fields | ||
39 | return None; | ||
40 | } | ||
41 | |||
42 | let name = local_name.unwrap_or_else(|| strukt.name(ctx.db())).to_string(); | ||
43 | let pat = render_pat(&ctx, &name, strukt.kind(ctx.db()), &visible_fields, fields_omitted)?; | ||
44 | |||
45 | Some(build_completion(ctx, name, pat, strukt)) | ||
46 | } | ||
47 | |||
48 | pub(crate) fn render_variant_pat( | ||
49 | ctx: RenderContext<'_>, | ||
50 | variant: hir::Variant, | ||
51 | local_name: Option<Name>, | ||
52 | path: Option<hir::ModPath>, | ||
53 | ) -> Option<CompletionItem> { | ||
54 | let _p = profile::span("render_variant_pat"); | ||
55 | |||
56 | let fields = variant.fields(ctx.db()); | ||
57 | let (visible_fields, fields_omitted) = visible_fields(&ctx, &fields, variant)?; | ||
58 | |||
59 | let name = match &path { | ||
60 | Some(path) => path.to_string(), | ||
61 | None => local_name.unwrap_or_else(|| variant.name(ctx.db())).to_string(), | ||
62 | }; | ||
63 | let pat = render_pat(&ctx, &name, variant.kind(ctx.db()), &visible_fields, fields_omitted)?; | ||
64 | |||
65 | Some(build_completion(ctx, name, pat, variant)) | ||
66 | } | ||
67 | |||
68 | fn build_completion( | ||
69 | ctx: RenderContext<'_>, | ||
70 | name: String, | ||
71 | pat: String, | ||
72 | item: impl HasAttrs + Copy, | ||
73 | ) -> CompletionItem { | ||
74 | let completion = CompletionItem::new(CompletionKind::Snippet, ctx.source_range(), name) | ||
75 | .kind(CompletionItemKind::Binding) | ||
76 | .set_documentation(ctx.docs(item)) | ||
77 | .set_deprecated(ctx.is_deprecated(item)) | ||
78 | .detail(&pat); | ||
79 | let completion = if let Some(snippet_cap) = ctx.snippet_cap() { | ||
80 | completion.insert_snippet(snippet_cap, pat) | ||
81 | } else { | ||
82 | completion.insert_text(pat) | ||
83 | }; | ||
84 | completion.build() | ||
85 | } | ||
86 | |||
87 | fn render_pat( | ||
88 | ctx: &RenderContext<'_>, | ||
89 | name: &str, | ||
90 | kind: StructKind, | ||
91 | fields: &[hir::Field], | ||
92 | fields_omitted: bool, | ||
93 | ) -> Option<String> { | ||
94 | let mut pat = match kind { | ||
95 | StructKind::Tuple if ctx.snippet_cap().is_some() => { | ||
96 | render_tuple_as_pat(&fields, &name, fields_omitted) | ||
97 | } | ||
98 | StructKind::Record => { | ||
99 | render_record_as_pat(ctx.db(), ctx.snippet_cap(), &fields, &name, fields_omitted) | ||
100 | } | ||
101 | _ => return None, | ||
102 | }; | ||
103 | |||
104 | if ctx.completion.is_param { | ||
105 | pat.push(':'); | ||
106 | pat.push(' '); | ||
107 | pat.push_str(&name); | ||
108 | } | ||
109 | if ctx.snippet_cap().is_some() { | ||
110 | pat.push_str("$0"); | ||
111 | } | ||
112 | Some(pat) | ||
113 | } | ||
114 | |||
115 | fn render_record_as_pat( | ||
116 | db: &dyn HirDatabase, | ||
117 | snippet_cap: Option<SnippetCap>, | ||
118 | fields: &[hir::Field], | ||
119 | name: &str, | ||
120 | fields_omitted: bool, | ||
121 | ) -> String { | ||
122 | let fields = fields.iter(); | ||
123 | if snippet_cap.is_some() { | ||
124 | format!( | ||
125 | "{name} {{ {}{} }}", | ||
126 | fields | ||
127 | .enumerate() | ||
128 | .map(|(idx, field)| format!("{}${}", field.name(db), idx + 1)) | ||
129 | .format(", "), | ||
130 | if fields_omitted { ", .." } else { "" }, | ||
131 | name = name | ||
132 | ) | ||
133 | } else { | ||
134 | format!( | ||
135 | "{name} {{ {}{} }}", | ||
136 | fields.map(|field| field.name(db)).format(", "), | ||
137 | if fields_omitted { ", .." } else { "" }, | ||
138 | name = name | ||
139 | ) | ||
140 | } | ||
141 | } | ||
142 | |||
143 | fn render_tuple_as_pat(fields: &[hir::Field], name: &str, fields_omitted: bool) -> String { | ||
144 | format!( | ||
145 | "{name}({}{})", | ||
146 | fields.iter().enumerate().map(|(idx, _)| format!("${}", idx + 1)).format(", "), | ||
147 | if fields_omitted { ", .." } else { "" }, | ||
148 | name = name | ||
149 | ) | ||
150 | } | ||