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