aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src/assist_context.rs
diff options
context:
space:
mode:
authorMikhail Rakhmanov <[email protected]>2020-05-22 21:28:30 +0100
committerMikhail Rakhmanov <[email protected]>2020-05-22 21:28:30 +0100
commit5cd4eb6dd6d8c733077a6aeea5d2cc0812ded096 (patch)
treedffc23552eb6e77c50966fa155ed8a56b418c5f0 /crates/ra_assists/src/assist_context.rs
parentd4daca9f02ec46be1beef79e9ed647a3a24e2434 (diff)
Add preliminary implementation of extract struct from enum variant
Diffstat (limited to 'crates/ra_assists/src/assist_context.rs')
-rw-r--r--crates/ra_assists/src/assist_context.rs62
1 files changed, 61 insertions, 1 deletions
diff --git a/crates/ra_assists/src/assist_context.rs b/crates/ra_assists/src/assist_context.rs
index 5b1a4680b..6291c68de 100644
--- a/crates/ra_assists/src/assist_context.rs
+++ b/crates/ra_assists/src/assist_context.rs
@@ -2,7 +2,7 @@
2 2
3use algo::find_covering_element; 3use algo::find_covering_element;
4use hir::Semantics; 4use hir::Semantics;
5use ra_db::{FileId, FileRange}; 5use ra_db::{FileId, FileRange, FilePosition};
6use ra_fmt::{leading_indent, reindent}; 6use ra_fmt::{leading_indent, reindent};
7use ra_ide_db::{ 7use ra_ide_db::{
8 source_change::{SourceChange, SourceFileEdit}, 8 source_change::{SourceChange, SourceFileEdit},
@@ -19,6 +19,7 @@ use crate::{
19 assist_config::{AssistConfig, SnippetCap}, 19 assist_config::{AssistConfig, SnippetCap},
20 Assist, AssistId, GroupLabel, ResolvedAssist, 20 Assist, AssistId, GroupLabel, ResolvedAssist,
21}; 21};
22use rustc_hash::FxHashMap;
22 23
23/// `AssistContext` allows to apply an assist or check if it could be applied. 24/// `AssistContext` allows to apply an assist or check if it could be applied.
24/// 25///
@@ -138,6 +139,16 @@ impl Assists {
138 let label = Assist::new(id, label.into(), None, target); 139 let label = Assist::new(id, label.into(), None, target);
139 self.add_impl(label, f) 140 self.add_impl(label, f)
140 } 141 }
142 pub(crate) fn add_in_multiple_files(
143 &mut self,
144 id: AssistId,
145 label: impl Into<String>,
146 target: TextRange,
147 f: impl FnOnce(&mut AssistDirector),
148 ) -> Option<()> {
149 let label = Assist::new(id, label.into(), None, target);
150 self.add_impl_multiple_files(label, f)
151 }
141 pub(crate) fn add_group( 152 pub(crate) fn add_group(
142 &mut self, 153 &mut self,
143 group: &GroupLabel, 154 group: &GroupLabel,
@@ -162,6 +173,27 @@ impl Assists {
162 Some(()) 173 Some(())
163 } 174 }
164 175
176 fn add_impl_multiple_files(&mut self, label: Assist, f: impl FnOnce(&mut AssistDirector)) -> Option<()> {
177 let change_label = label.label.clone();
178 if !self.resolve {
179 return None
180 }
181 let mut director = AssistDirector::new(change_label.clone());
182 f(&mut director);
183 let changes = director.finish();
184 let file_edits: Vec<SourceFileEdit> = changes.into_iter()
185 .map(|mut change| change.source_file_edits.pop().unwrap()).collect();
186
187 let source_change = SourceChange {
188 source_file_edits: file_edits,
189 file_system_edits: vec![],
190 is_snippet: false,
191 };
192
193 self.buf.push((label, Some(source_change)));
194 Some(())
195 }
196
165 fn finish(mut self) -> Vec<(Assist, Option<SourceChange>)> { 197 fn finish(mut self) -> Vec<(Assist, Option<SourceChange>)> {
166 self.buf.sort_by_key(|(label, _edit)| label.target.len()); 198 self.buf.sort_by_key(|(label, _edit)| label.target.len());
167 self.buf 199 self.buf
@@ -255,3 +287,31 @@ impl AssistBuilder {
255 res 287 res
256 } 288 }
257} 289}
290
291pub(crate) struct AssistDirector {
292 source_changes: Vec<SourceChange>,
293 builders: FxHashMap<FileId, AssistBuilder>,
294 change_label: String
295}
296
297impl AssistDirector {
298 fn new(change_label: String) -> AssistDirector {
299 AssistDirector {
300 source_changes: vec![],
301 builders: FxHashMap::default(),
302 change_label
303 }
304 }
305
306 pub(crate) fn perform(&mut self, file_id: FileId, f: impl FnOnce(&mut AssistBuilder)) {
307 let mut builder = self.builders.entry(file_id).or_insert(AssistBuilder::new(file_id));
308 f(&mut builder);
309 }
310
311 fn finish(mut self) -> Vec<SourceChange> {
312 for (file_id, builder) in self.builders.into_iter().collect::<Vec<(FileId, AssistBuilder)>>() {
313 self.source_changes.push(builder.finish());
314 }
315 self.source_changes
316 }
317}