aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-09-28 18:09:57 +0100
committerAleksey Kladov <[email protected]>2019-09-28 18:10:53 +0100
commit0840ec038b2822a424acf238d8db5af569f99a21 (patch)
treec40067afaffe2c7c1b974af668c078bc6d3b3341 /crates/ra_assists
parent5dbbfda34ae423229487595fd0ae9e727ae42906 (diff)
migrate add impl items to the new editing API
Diffstat (limited to 'crates/ra_assists')
-rw-r--r--crates/ra_assists/src/assist_ctx.rs8
-rw-r--r--crates/ra_assists/src/assists/add_missing_impl_members.rs15
-rw-r--r--crates/ra_assists/src/ast_editor.rs69
3 files changed, 15 insertions, 77 deletions
diff --git a/crates/ra_assists/src/assist_ctx.rs b/crates/ra_assists/src/assist_ctx.rs
index c45262efa..cbe12e908 100644
--- a/crates/ra_assists/src/assist_ctx.rs
+++ b/crates/ra_assists/src/assist_ctx.rs
@@ -2,7 +2,7 @@ use hir::db::HirDatabase;
2use ra_db::FileRange; 2use ra_db::FileRange;
3use ra_fmt::{leading_indent, reindent}; 3use ra_fmt::{leading_indent, reindent};
4use ra_syntax::{ 4use ra_syntax::{
5 algo::{find_covering_element, find_node_at_offset}, 5 algo::{self, find_covering_element, find_node_at_offset},
6 AstNode, SourceFile, SyntaxElement, SyntaxNode, SyntaxToken, TextRange, TextUnit, 6 AstNode, SourceFile, SyntaxElement, SyntaxNode, SyntaxToken, TextRange, TextUnit,
7 TokenAtOffset, 7 TokenAtOffset,
8}; 8};
@@ -177,6 +177,12 @@ impl AssistBuilder {
177 &mut self.edit 177 &mut self.edit
178 } 178 }
179 179
180 pub(crate) fn replace_ast<N: AstNode>(&mut self, old: N, new: N) {
181 for (from, to) in algo::diff(old.syntax(), new.syntax()) {
182 self.edit.replace(from.text_range(), to.to_string())
183 }
184 }
185
180 fn build(self) -> AssistAction { 186 fn build(self) -> AssistAction {
181 AssistAction { 187 AssistAction {
182 edit: self.edit.finish(), 188 edit: self.edit.finish(),
diff --git a/crates/ra_assists/src/assists/add_missing_impl_members.rs b/crates/ra_assists/src/assists/add_missing_impl_members.rs
index 3fce4a5b7..c2e3eb06b 100644
--- a/crates/ra_assists/src/assists/add_missing_impl_members.rs
+++ b/crates/ra_assists/src/assists/add_missing_impl_members.rs
@@ -4,7 +4,7 @@ use ra_syntax::{
4 SmolStr, 4 SmolStr,
5}; 5};
6 6
7use crate::{ast_editor::AstEditor, Assist, AssistCtx, AssistId}; 7use crate::{Assist, AssistCtx, AssistId};
8 8
9#[derive(PartialEq)] 9#[derive(PartialEq)]
10enum AddMissingImplMembersMode { 10enum AddMissingImplMembersMode {
@@ -79,14 +79,13 @@ fn add_missing_impl_members_inner(
79 ast::ImplItem::FnDef(def) => edit::strip_attrs_and_docs(add_body(def).into()), 79 ast::ImplItem::FnDef(def) => edit::strip_attrs_and_docs(add_body(def).into()),
80 _ => edit::strip_attrs_and_docs(it), 80 _ => edit::strip_attrs_and_docs(it),
81 }); 81 });
82 let mut ast_editor = AstEditor::new(impl_item_list); 82 let new_impl_item_list = impl_item_list.append_items(items);
83 83 let cursor_position = {
84 ast_editor.append_items(items); 84 let first_new_item = new_impl_item_list.impl_items().nth(n_existing_items).unwrap();
85 85 first_new_item.syntax().text_range().start()
86 let first_new_item = ast_editor.ast().impl_items().nth(n_existing_items).unwrap(); 86 };
87 let cursor_position = first_new_item.syntax().text_range().start();
88 ast_editor.into_text_edit(edit.text_edit_builder());
89 87
88 edit.replace_ast(impl_item_list, new_impl_item_list);
90 edit.set_cursor(cursor_position); 89 edit.set_cursor(cursor_position);
91 }); 90 });
92 91
diff --git a/crates/ra_assists/src/ast_editor.rs b/crates/ra_assists/src/ast_editor.rs
index 60b8923e1..262e2fcf4 100644
--- a/crates/ra_assists/src/ast_editor.rs
+++ b/crates/ra_assists/src/ast_editor.rs
@@ -7,9 +7,7 @@ use ra_fmt::leading_indent;
7use ra_syntax::{ 7use ra_syntax::{
8 algo, 8 algo,
9 ast::{self, make::tokens, TypeBoundsOwner}, 9 ast::{self, make::tokens, TypeBoundsOwner},
10 AstNode, Direction, InsertPosition, SyntaxElement, 10 AstNode, Direction, InsertPosition, SyntaxElement, T,
11 SyntaxKind::*,
12 T,
13}; 11};
14use ra_text_edit::TextEditBuilder; 12use ra_text_edit::TextEditBuilder;
15 13
@@ -67,38 +65,6 @@ impl<N: AstNode> AstEditor<N> {
67 let new_syntax = algo::replace_children(self.ast().syntax(), to_delete, &mut to_insert); 65 let new_syntax = algo::replace_children(self.ast().syntax(), to_delete, &mut to_insert);
68 N::cast(new_syntax).unwrap() 66 N::cast(new_syntax).unwrap()
69 } 67 }
70
71 fn do_make_multiline(&mut self) {
72 let l_curly =
73 match self.ast().syntax().children_with_tokens().find(|it| it.kind() == T!['{']) {
74 Some(it) => it,
75 None => return,
76 };
77 let sibling = match l_curly.next_sibling_or_token() {
78 Some(it) => it,
79 None => return,
80 };
81 let existing_ws = match sibling.as_token() {
82 None => None,
83 Some(tok) if tok.kind() != WHITESPACE => None,
84 Some(ws) => {
85 if ws.text().contains('\n') {
86 return;
87 }
88 Some(ws.clone())
89 }
90 };
91
92 let indent = leading_indent(self.ast().syntax()).unwrap_or("".into());
93 let ws = tokens::WsBuilder::new(&format!("\n{}", indent));
94 let to_insert = iter::once(ws.ws().into());
95 self.ast = match existing_ws {
96 None => self.insert_children(InsertPosition::After(l_curly), to_insert),
97 Some(ws) => {
98 self.replace_children(RangeInclusive::new(ws.clone().into(), ws.into()), to_insert)
99 }
100 };
101 }
102} 68}
103 69
104impl AstEditor<ast::RecordFieldList> { 70impl AstEditor<ast::RecordFieldList> {
@@ -179,39 +145,6 @@ impl AstEditor<ast::RecordFieldList> {
179 } 145 }
180} 146}
181 147
182impl AstEditor<ast::ItemList> {
183 pub fn append_items(&mut self, items: impl Iterator<Item = ast::ImplItem>) {
184 if !self.ast().syntax().text().contains_char('\n') {
185 self.do_make_multiline();
186 }
187 items.for_each(|it| self.append_item(it));
188 }
189
190 pub fn append_item(&mut self, item: ast::ImplItem) {
191 let (indent, position) = match self.ast().impl_items().last() {
192 Some(it) => (
193 leading_indent(it.syntax()).unwrap_or_default().to_string(),
194 InsertPosition::After(it.syntax().clone().into()),
195 ),
196 None => match self.l_curly() {
197 Some(it) => (
198 " ".to_string() + &leading_indent(self.ast().syntax()).unwrap_or_default(),
199 InsertPosition::After(it),
200 ),
201 None => return,
202 },
203 };
204 let ws = tokens::WsBuilder::new(&format!("\n{}", indent));
205 let to_insert: ArrayVec<[SyntaxElement; 2]> =
206 [ws.ws().into(), item.syntax().clone().into()].into();
207 self.ast = self.insert_children(position, to_insert.into_iter());
208 }
209
210 fn l_curly(&self) -> Option<SyntaxElement> {
211 self.ast().syntax().children_with_tokens().find(|it| it.kind() == T!['{'])
212 }
213}
214
215impl AstEditor<ast::TypeParam> { 148impl AstEditor<ast::TypeParam> {
216 pub fn remove_bounds(&mut self) -> &mut Self { 149 pub fn remove_bounds(&mut self) -> &mut Self {
217 let colon = match self.ast.colon_token() { 150 let colon = match self.ast.colon_token() {