Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/ide-assists/src/handlers/generate_derive.rs11
-rw-r--r--crates/ide-db/src/source_change.rs106
2 files changed, 16 insertions, 101 deletions
diff --git a/crates/ide-assists/src/handlers/generate_derive.rs b/crates/ide-assists/src/handlers/generate_derive.rs
index f293e956bc..ba6bb5c70b 100644
--- a/crates/ide-assists/src/handlers/generate_derive.rs
+++ b/crates/ide-assists/src/handlers/generate_derive.rs
@@ -42,9 +42,9 @@ pub(crate) fn generate_derive(acc: &mut Assists, ctx: &AssistContext<'_, '_>) ->
};
acc.add(AssistId::generate("generate_derive"), "Add `#[derive]`", target, |edit| {
+ let editor = edit.make_editor(nominal.syntax());
match derive_attr {
None => {
- let editor = edit.make_editor(nominal.syntax());
let make = editor.make();
let derive =
make.attr_outer(make.meta_token_tree(
@@ -79,16 +79,15 @@ pub(crate) fn generate_derive(acc: &mut Assists, ctx: &AssistContext<'_, '_>) ->
let tabstop_before = edit.make_tabstop_before(cap);
editor.add_annotation(delimiter, tabstop_before);
- edit.add_file_edits(ctx.vfs_file_id(), editor);
}
Some(_) => {
+ let delimiter = delimiter.expect("Right delim token could not be found.");
+ let tabstop_before = edit.make_tabstop_before(cap);
// Just move the cursor.
- edit.add_tabstop_before_token(
- cap,
- delimiter.expect("Right delim token could not be found."),
- );
+ editor.add_annotation(delimiter, tabstop_before);
}
};
+ edit.add_file_edits(ctx.vfs_file_id(), editor);
})
}
diff --git a/crates/ide-db/src/source_change.rs b/crates/ide-db/src/source_change.rs
index 540b0ee99d..58f459003e 100644
--- a/crates/ide-db/src/source_change.rs
+++ b/crates/ide-db/src/source_change.rs
@@ -15,7 +15,7 @@ use rustc_hash::FxHashMap;
use span::FileId;
use stdx::never;
use syntax::{
- AstNode, SyntaxElement, SyntaxNode, SyntaxToken, TextRange, TextSize,
+ AstNode, SyntaxNode, TextRange, TextSize,
syntax_editor::{SyntaxAnnotation, SyntaxEditor},
};
@@ -68,7 +68,7 @@ impl SourceChange {
/// Inserts a [`TextEdit`] and potentially a [`SnippetEdit`] for the given [`FileId`].
/// This properly handles merging existing edits for a file if some already exist.
- pub fn insert_source_and_snippet_edit(
+ fn insert_source_and_snippet_edit(
&mut self,
file_id: impl Into<FileId>,
edit: TextEdit,
@@ -105,7 +105,7 @@ impl SourceChange {
pub fn merge(mut self, other: SourceChange) -> SourceChange {
self.extend(other.source_file_edits);
- self.extend(other.file_system_edits);
+ self.file_system_edits.extend(other.file_system_edits);
self.is_snippet |= other.is_snippet;
self
}
@@ -128,25 +128,6 @@ impl Extend<(FileId, (TextEdit, Option<SnippetEdit>))> for SourceChange {
}
}
-impl Extend<FileSystemEdit> for SourceChange {
- fn extend<T: IntoIterator<Item = FileSystemEdit>>(&mut self, iter: T) {
- iter.into_iter().for_each(|edit| self.push_file_system_edit(edit));
- }
-}
-
-impl From<IntMap<FileId, TextEdit>> for SourceChange {
- fn from(source_file_edits: IntMap<FileId, TextEdit>) -> SourceChange {
- let source_file_edits =
- source_file_edits.into_iter().map(|(file_id, edit)| (file_id, (edit, None))).collect();
- SourceChange {
- source_file_edits,
- file_system_edits: Vec::new(),
- is_snippet: false,
- ..SourceChange::default()
- }
- }
-}
-
impl FromIterator<(FileId, TextEdit)> for SourceChange {
fn from_iter<T: IntoIterator<Item = (FileId, TextEdit)>>(iter: T) -> Self {
let mut this = SourceChange::default();
@@ -222,24 +203,15 @@ impl SnippetEdit {
}
pub struct SourceChangeBuilder {
- pub edit: TextEditBuilder,
+ edit: TextEditBuilder,
pub file_id: FileId,
pub source_change: SourceChange,
pub command: Option<Command>,
/// Keeps track of all edits performed on each file
- pub file_editors: FxHashMap<FileId, SyntaxEditor>,
+ file_editors: FxHashMap<FileId, SyntaxEditor>,
/// Keeps track of which annotations correspond to which snippets
- pub snippet_annotations: Vec<(AnnotationSnippet, SyntaxAnnotation)>,
-
- /// Keeps track of where to place snippets
- pub snippet_builder: Option<SnippetBuilder>,
-}
-
-#[derive(Default)]
-pub struct SnippetBuilder {
- /// Where to place snippets at
- places: Vec<PlaceSnippet>,
+ snippet_annotations: Vec<(AnnotationSnippet, SyntaxAnnotation)>,
}
impl SourceChangeBuilder {
@@ -251,7 +223,6 @@ impl SourceChangeBuilder {
command: None,
file_editors: FxHashMap::default(),
snippet_annotations: vec![],
- snippet_builder: None,
}
}
@@ -329,15 +300,9 @@ impl SourceChangeBuilder {
}
// Apply mutable edits
- let snippet_edit = self.snippet_builder.take().map(|builder| {
- SnippetEdit::new(
- builder.places.into_iter().flat_map(PlaceSnippet::finalize_position).collect(),
- )
- });
-
let edit = mem::take(&mut self.edit).finish();
- if !edit.is_empty() || snippet_edit.is_some() {
- self.source_change.insert_source_and_snippet_edit(self.file_id, edit, snippet_edit);
+ if !edit.is_empty() {
+ self.source_change.insert_source_edit(self.file_id, edit);
}
}
@@ -375,36 +340,6 @@ impl SourceChangeBuilder {
self.command = Some(Command::Rename);
}
- /// Adds a tabstop snippet to place the cursor before `node`
- pub fn add_tabstop_before(&mut self, _cap: SnippetCap, node: impl AstNode) {
- assert!(node.syntax().parent().is_some());
- self.add_snippet(PlaceSnippet::Before(node.syntax().clone().into()));
- }
-
- /// Adds a tabstop snippet to place the cursor before `token`
- pub fn add_tabstop_before_token(&mut self, _cap: SnippetCap, token: SyntaxToken) {
- assert!(token.parent().is_some());
- self.add_snippet(PlaceSnippet::Before(token.into()));
- }
-
- /// Adds a tabstop snippet to place the cursor after `token`
- pub fn add_tabstop_after_token(&mut self, _cap: SnippetCap, token: SyntaxToken) {
- assert!(token.parent().is_some());
- self.add_snippet(PlaceSnippet::After(token.into()));
- }
-
- /// Adds a snippet to move the cursor selected over `node`
- pub fn add_placeholder_snippet(&mut self, _cap: SnippetCap, node: impl AstNode) {
- assert!(node.syntax().parent().is_some());
- self.add_snippet(PlaceSnippet::Over(node.syntax().clone().into()))
- }
-
- fn add_snippet(&mut self, snippet: PlaceSnippet) {
- let snippet_builder = self.snippet_builder.get_or_insert(SnippetBuilder { places: vec![] });
- snippet_builder.places.push(snippet);
- self.source_change.is_snippet = true;
- }
-
fn add_snippet_annotation(&mut self, kind: AnnotationSnippet) -> SyntaxAnnotation {
let annotation = SyntaxAnnotation::default();
self.snippet_annotations.push((kind, annotation));
@@ -425,7 +360,7 @@ impl SourceChangeBuilder {
.is_err()
);
- mem::take(&mut self.source_change)
+ self.source_change
}
}
@@ -461,30 +396,11 @@ pub enum Snippet {
PlaceholderGroup(Vec<TextRange>),
}
-pub enum AnnotationSnippet {
+enum AnnotationSnippet {
/// Place a tabstop before an element
Before,
- /// Place a tabstop before an element
+ /// Place a tabstop after an element
After,
/// Place a placeholder snippet in place of the element(s)
Over,
}
-
-enum PlaceSnippet {
- /// Place a tabstop before an element
- Before(SyntaxElement),
- /// Place a tabstop before an element
- After(SyntaxElement),
- /// Place a placeholder snippet in place of the element
- Over(SyntaxElement),
-}
-
-impl PlaceSnippet {
- fn finalize_position(self) -> Vec<Snippet> {
- match self {
- PlaceSnippet::Before(it) => vec![Snippet::Tabstop(it.text_range().start())],
- PlaceSnippet::After(it) => vec![Snippet::Tabstop(it.text_range().end())],
- PlaceSnippet::Over(it) => vec![Snippet::Placeholder(it.text_range())],
- }
- }
-}