diff options
Diffstat (limited to 'crates/ide_db')
-rw-r--r-- | crates/ide_db/src/source_change.rs | 54 |
1 files changed, 42 insertions, 12 deletions
diff --git a/crates/ide_db/src/source_change.rs b/crates/ide_db/src/source_change.rs index 10c0abdac..516d7859a 100644 --- a/crates/ide_db/src/source_change.rs +++ b/crates/ide_db/src/source_change.rs | |||
@@ -3,12 +3,18 @@ | |||
3 | //! | 3 | //! |
4 | //! It can be viewed as a dual for `AnalysisChange`. | 4 | //! It can be viewed as a dual for `AnalysisChange`. |
5 | 5 | ||
6 | use std::{ | ||
7 | collections::hash_map::Entry, | ||
8 | iter::{self, FromIterator}, | ||
9 | }; | ||
10 | |||
6 | use base_db::{AnchoredPathBuf, FileId}; | 11 | use base_db::{AnchoredPathBuf, FileId}; |
12 | use rustc_hash::FxHashMap; | ||
7 | use text_edit::TextEdit; | 13 | use text_edit::TextEdit; |
8 | 14 | ||
9 | #[derive(Default, Debug, Clone)] | 15 | #[derive(Default, Debug, Clone)] |
10 | pub struct SourceChange { | 16 | pub struct SourceChange { |
11 | pub source_file_edits: Vec<SourceFileEdit>, | 17 | pub source_file_edits: SourceFileEdits, |
12 | pub file_system_edits: Vec<FileSystemEdit>, | 18 | pub file_system_edits: Vec<FileSystemEdit>, |
13 | pub is_snippet: bool, | 19 | pub is_snippet: bool, |
14 | } | 20 | } |
@@ -17,27 +23,51 @@ impl SourceChange { | |||
17 | /// Creates a new SourceChange with the given label | 23 | /// Creates a new SourceChange with the given label |
18 | /// from the edits. | 24 | /// from the edits. |
19 | pub fn from_edits( | 25 | pub fn from_edits( |
20 | source_file_edits: Vec<SourceFileEdit>, | 26 | source_file_edits: SourceFileEdits, |
21 | file_system_edits: Vec<FileSystemEdit>, | 27 | file_system_edits: Vec<FileSystemEdit>, |
22 | ) -> Self { | 28 | ) -> Self { |
23 | SourceChange { source_file_edits, file_system_edits, is_snippet: false } | 29 | SourceChange { source_file_edits, file_system_edits, is_snippet: false } |
24 | } | 30 | } |
25 | } | 31 | } |
26 | 32 | ||
27 | #[derive(Debug, Clone)] | 33 | #[derive(Default, Debug, Clone)] |
28 | pub struct SourceFileEdit { | 34 | pub struct SourceFileEdits { |
29 | pub file_id: FileId, | 35 | pub edits: FxHashMap<FileId, TextEdit>, |
30 | pub edit: TextEdit, | 36 | } |
37 | |||
38 | impl SourceFileEdits { | ||
39 | pub fn from_text_edit(file_id: FileId, edit: TextEdit) -> Self { | ||
40 | SourceFileEdits { edits: FxHashMap::from_iter(iter::once((file_id, edit))) } | ||
41 | } | ||
42 | |||
43 | pub fn len(&self) -> usize { | ||
44 | self.edits.len() | ||
45 | } | ||
46 | |||
47 | pub fn is_empty(&self) -> bool { | ||
48 | self.edits.is_empty() | ||
49 | } | ||
50 | |||
51 | pub fn insert(&mut self, file_id: FileId, edit: TextEdit) { | ||
52 | match self.edits.entry(file_id) { | ||
53 | Entry::Occupied(mut entry) => { | ||
54 | entry.get_mut().union(edit).expect("overlapping edits for same file"); | ||
55 | } | ||
56 | Entry::Vacant(entry) => { | ||
57 | entry.insert(edit); | ||
58 | } | ||
59 | } | ||
60 | } | ||
31 | } | 61 | } |
32 | 62 | ||
33 | impl From<SourceFileEdit> for SourceChange { | 63 | impl Extend<(FileId, TextEdit)> for SourceFileEdits { |
34 | fn from(edit: SourceFileEdit) -> SourceChange { | 64 | fn extend<T: IntoIterator<Item = (FileId, TextEdit)>>(&mut self, iter: T) { |
35 | vec![edit].into() | 65 | iter.into_iter().for_each(|(file_id, edit)| self.insert(file_id, edit)); |
36 | } | 66 | } |
37 | } | 67 | } |
38 | 68 | ||
39 | impl From<Vec<SourceFileEdit>> for SourceChange { | 69 | impl From<SourceFileEdits> for SourceChange { |
40 | fn from(source_file_edits: Vec<SourceFileEdit>) -> SourceChange { | 70 | fn from(source_file_edits: SourceFileEdits) -> SourceChange { |
41 | SourceChange { source_file_edits, file_system_edits: Vec::new(), is_snippet: false } | 71 | SourceChange { source_file_edits, file_system_edits: Vec::new(), is_snippet: false } |
42 | } | 72 | } |
43 | } | 73 | } |
@@ -51,7 +81,7 @@ pub enum FileSystemEdit { | |||
51 | impl From<FileSystemEdit> for SourceChange { | 81 | impl From<FileSystemEdit> for SourceChange { |
52 | fn from(edit: FileSystemEdit) -> SourceChange { | 82 | fn from(edit: FileSystemEdit) -> SourceChange { |
53 | SourceChange { | 83 | SourceChange { |
54 | source_file_edits: Vec::new(), | 84 | source_file_edits: Default::default(), |
55 | file_system_edits: vec![edit], | 85 | file_system_edits: vec![edit], |
56 | is_snippet: false, | 86 | is_snippet: false, |
57 | } | 87 | } |