diff options
author | Kirill Bulatov <[email protected]> | 2020-03-31 21:39:46 +0100 |
---|---|---|
committer | Kirill Bulatov <[email protected]> | 2020-04-01 10:49:31 +0100 |
commit | d35b94352090c201f7e0cceae43035ee0e72df98 (patch) | |
tree | 7ac4cca1aa23aa005077cc1e1e1c8911ad69eadd /crates/ra_ide/src/completion.rs | |
parent | bc71631e75f42f7730084a307e4765c3df92791b (diff) |
Split draft
Diffstat (limited to 'crates/ra_ide/src/completion.rs')
-rw-r--r-- | crates/ra_ide/src/completion.rs | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/crates/ra_ide/src/completion.rs b/crates/ra_ide/src/completion.rs index b683572fb..67dfd6f2e 100644 --- a/crates/ra_ide/src/completion.rs +++ b/crates/ra_ide/src/completion.rs | |||
@@ -32,6 +32,12 @@ use crate::{ | |||
32 | pub use crate::completion::completion_item::{ | 32 | pub use crate::completion::completion_item::{ |
33 | CompletionItem, CompletionItemKind, InsertTextFormat, | 33 | CompletionItem, CompletionItemKind, InsertTextFormat, |
34 | }; | 34 | }; |
35 | use either::Either; | ||
36 | use hir::{StructField, Type}; | ||
37 | use ra_syntax::{ | ||
38 | ast::{self, NameOwner}, | ||
39 | SmolStr, | ||
40 | }; | ||
35 | 41 | ||
36 | #[derive(Clone, Debug, PartialEq, Eq)] | 42 | #[derive(Clone, Debug, PartialEq, Eq)] |
37 | pub struct CompletionConfig { | 43 | pub struct CompletionConfig { |
@@ -98,3 +104,57 @@ pub(crate) fn completions( | |||
98 | 104 | ||
99 | Some(acc) | 105 | Some(acc) |
100 | } | 106 | } |
107 | |||
108 | pub(crate) fn get_missing_fields( | ||
109 | ctx: &CompletionContext, | ||
110 | record: Either<&ast::RecordLit, &ast::RecordPat>, | ||
111 | ) -> Option<Vec<(StructField, Type)>> { | ||
112 | let (ty, variant) = match record { | ||
113 | Either::Left(record_lit) => ( | ||
114 | ctx.sema.type_of_expr(&record_lit.clone().into())?, | ||
115 | ctx.sema.resolve_record_literal(record_lit)?, | ||
116 | ), | ||
117 | Either::Right(record_pat) => ( | ||
118 | ctx.sema.type_of_pat(&record_pat.clone().into())?, | ||
119 | ctx.sema.resolve_record_pattern(record_pat)?, | ||
120 | ), | ||
121 | }; | ||
122 | |||
123 | let already_present_names = get_already_present_names(record); | ||
124 | Some( | ||
125 | ty.variant_fields(ctx.db, variant) | ||
126 | .into_iter() | ||
127 | .filter(|(field, _)| { | ||
128 | !already_present_names.contains(&SmolStr::from(field.name(ctx.db).to_string())) | ||
129 | }) | ||
130 | .collect(), | ||
131 | ) | ||
132 | } | ||
133 | |||
134 | fn get_already_present_names(record: Either<&ast::RecordLit, &ast::RecordPat>) -> Vec<SmolStr> { | ||
135 | // TODO kb have a single match | ||
136 | match record { | ||
137 | Either::Left(record_lit) => record_lit | ||
138 | .record_field_list() | ||
139 | .map(|field_list| field_list.fields()) | ||
140 | .map(|fields| { | ||
141 | fields | ||
142 | .into_iter() | ||
143 | .filter_map(|field| field.name_ref()) | ||
144 | .map(|name_ref| name_ref.text().clone()) | ||
145 | .collect() | ||
146 | }) | ||
147 | .unwrap_or_default(), | ||
148 | Either::Right(record_pat) => record_pat | ||
149 | .record_field_pat_list() | ||
150 | .map(|pat_list| pat_list.bind_pats()) | ||
151 | .map(|bind_pats| { | ||
152 | bind_pats | ||
153 | .into_iter() | ||
154 | .filter_map(|pat| pat.name()) | ||
155 | .map(|name| name.text().clone()) | ||
156 | .collect() | ||
157 | }) | ||
158 | .unwrap_or_default(), | ||
159 | } | ||
160 | } | ||