From f51457a643b768794092f73add6dda4aecd400a1 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 14 Jan 2021 18:35:22 +0100 Subject: Group file source edits by FileId --- crates/ide_db/src/source_change.rs | 54 +++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 12 deletions(-) (limited to 'crates/ide_db') 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 @@ //! //! It can be viewed as a dual for `AnalysisChange`. +use std::{ + collections::hash_map::Entry, + iter::{self, FromIterator}, +}; + use base_db::{AnchoredPathBuf, FileId}; +use rustc_hash::FxHashMap; use text_edit::TextEdit; #[derive(Default, Debug, Clone)] pub struct SourceChange { - pub source_file_edits: Vec, + pub source_file_edits: SourceFileEdits, pub file_system_edits: Vec, pub is_snippet: bool, } @@ -17,27 +23,51 @@ impl SourceChange { /// Creates a new SourceChange with the given label /// from the edits. pub fn from_edits( - source_file_edits: Vec, + source_file_edits: SourceFileEdits, file_system_edits: Vec, ) -> Self { SourceChange { source_file_edits, file_system_edits, is_snippet: false } } } -#[derive(Debug, Clone)] -pub struct SourceFileEdit { - pub file_id: FileId, - pub edit: TextEdit, +#[derive(Default, Debug, Clone)] +pub struct SourceFileEdits { + pub edits: FxHashMap, +} + +impl SourceFileEdits { + pub fn from_text_edit(file_id: FileId, edit: TextEdit) -> Self { + SourceFileEdits { edits: FxHashMap::from_iter(iter::once((file_id, edit))) } + } + + pub fn len(&self) -> usize { + self.edits.len() + } + + pub fn is_empty(&self) -> bool { + self.edits.is_empty() + } + + pub fn insert(&mut self, file_id: FileId, edit: TextEdit) { + match self.edits.entry(file_id) { + Entry::Occupied(mut entry) => { + entry.get_mut().union(edit).expect("overlapping edits for same file"); + } + Entry::Vacant(entry) => { + entry.insert(edit); + } + } + } } -impl From for SourceChange { - fn from(edit: SourceFileEdit) -> SourceChange { - vec![edit].into() +impl Extend<(FileId, TextEdit)> for SourceFileEdits { + fn extend>(&mut self, iter: T) { + iter.into_iter().for_each(|(file_id, edit)| self.insert(file_id, edit)); } } -impl From> for SourceChange { - fn from(source_file_edits: Vec) -> SourceChange { +impl From for SourceChange { + fn from(source_file_edits: SourceFileEdits) -> SourceChange { SourceChange { source_file_edits, file_system_edits: Vec::new(), is_snippet: false } } } @@ -51,7 +81,7 @@ pub enum FileSystemEdit { impl From for SourceChange { fn from(edit: FileSystemEdit) -> SourceChange { SourceChange { - source_file_edits: Vec::new(), + source_file_edits: Default::default(), file_system_edits: vec![edit], is_snippet: false, } -- cgit v1.2.3 From d5095329a1c12e93653d8de4a93f0b4f5cad4c6e Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 14 Jan 2021 22:43:36 +0100 Subject: Phase out SourceFileEdits in favour of a plain HashMap --- crates/ide_db/src/source_change.rs | 50 +++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'crates/ide_db') diff --git a/crates/ide_db/src/source_change.rs b/crates/ide_db/src/source_change.rs index 516d7859a..b1f87731b 100644 --- a/crates/ide_db/src/source_change.rs +++ b/crates/ide_db/src/source_change.rs @@ -10,11 +10,12 @@ use std::{ use base_db::{AnchoredPathBuf, FileId}; use rustc_hash::FxHashMap; +use stdx::assert_never; use text_edit::TextEdit; #[derive(Default, Debug, Clone)] pub struct SourceChange { - pub source_file_edits: SourceFileEdits, + pub source_file_edits: FxHashMap, pub file_system_edits: Vec, pub is_snippet: bool, } @@ -23,51 +24,50 @@ impl SourceChange { /// Creates a new SourceChange with the given label /// from the edits. pub fn from_edits( - source_file_edits: SourceFileEdits, + source_file_edits: FxHashMap, file_system_edits: Vec, ) -> Self { SourceChange { source_file_edits, file_system_edits, is_snippet: false } } -} - -#[derive(Default, Debug, Clone)] -pub struct SourceFileEdits { - pub edits: FxHashMap, -} -impl SourceFileEdits { pub fn from_text_edit(file_id: FileId, edit: TextEdit) -> Self { - SourceFileEdits { edits: FxHashMap::from_iter(iter::once((file_id, edit))) } - } - - pub fn len(&self) -> usize { - self.edits.len() - } - - pub fn is_empty(&self) -> bool { - self.edits.is_empty() + SourceChange { + source_file_edits: FxHashMap::from_iter(iter::once((file_id, edit))), + ..Default::default() + } } - pub fn insert(&mut self, file_id: FileId, edit: TextEdit) { - match self.edits.entry(file_id) { + pub fn insert_source_edit(&mut self, file_id: FileId, edit: TextEdit) { + match self.source_file_edits.entry(file_id) { Entry::Occupied(mut entry) => { - entry.get_mut().union(edit).expect("overlapping edits for same file"); + assert_never!( + entry.get_mut().union(edit).is_err(), + "overlapping edits for same file" + ); } Entry::Vacant(entry) => { entry.insert(edit); } } } + + pub fn push_file_system_edit(&mut self, edit: FileSystemEdit) { + self.file_system_edits.push(edit); + } + + pub fn get_source_edit(&self, file_id: FileId) -> Option<&TextEdit> { + self.source_file_edits.get(&file_id) + } } -impl Extend<(FileId, TextEdit)> for SourceFileEdits { +impl Extend<(FileId, TextEdit)> for SourceChange { fn extend>(&mut self, iter: T) { - iter.into_iter().for_each(|(file_id, edit)| self.insert(file_id, edit)); + iter.into_iter().for_each(|(file_id, edit)| self.insert_source_edit(file_id, edit)); } } -impl From for SourceChange { - fn from(source_file_edits: SourceFileEdits) -> SourceChange { +impl From> for SourceChange { + fn from(source_file_edits: FxHashMap) -> SourceChange { SourceChange { source_file_edits, file_system_edits: Vec::new(), is_snippet: false } } } -- cgit v1.2.3