diff options
Diffstat (limited to 'crates/ra_assists')
-rw-r--r-- | crates/ra_assists/src/assist_ctx.rs | 4 | ||||
-rw-r--r-- | crates/ra_assists/src/ast_editor.rs | 101 |
2 files changed, 5 insertions, 100 deletions
diff --git a/crates/ra_assists/src/assist_ctx.rs b/crates/ra_assists/src/assist_ctx.rs index cbe12e908..5f564be0b 100644 --- a/crates/ra_assists/src/assist_ctx.rs +++ b/crates/ra_assists/src/assist_ctx.rs | |||
@@ -178,9 +178,7 @@ impl AssistBuilder { | |||
178 | } | 178 | } |
179 | 179 | ||
180 | pub(crate) fn replace_ast<N: AstNode>(&mut self, old: N, new: N) { | 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()) { | 181 | algo::diff(old.syntax(), new.syntax()).into_text_edit(&mut self.edit) |
182 | self.edit.replace(from.text_range(), to.to_string()) | ||
183 | } | ||
184 | } | 182 | } |
185 | 183 | ||
186 | fn build(self) -> AssistAction { | 184 | fn build(self) -> AssistAction { |
diff --git a/crates/ra_assists/src/ast_editor.rs b/crates/ra_assists/src/ast_editor.rs index 262e2fcf4..54849b7b0 100644 --- a/crates/ra_assists/src/ast_editor.rs +++ b/crates/ra_assists/src/ast_editor.rs | |||
@@ -1,15 +1,12 @@ | |||
1 | use std::{iter, ops::RangeInclusive}; | 1 | use std::{iter, ops::RangeInclusive}; |
2 | 2 | ||
3 | use arrayvec::ArrayVec; | ||
4 | use rustc_hash::FxHashMap; | ||
5 | |||
6 | use ra_fmt::leading_indent; | ||
7 | use ra_syntax::{ | 3 | use ra_syntax::{ |
8 | algo, | 4 | algo, |
9 | ast::{self, make::tokens, TypeBoundsOwner}, | 5 | ast::{self, TypeBoundsOwner}, |
10 | AstNode, Direction, InsertPosition, SyntaxElement, T, | 6 | AstNode, SyntaxElement, |
11 | }; | 7 | }; |
12 | use ra_text_edit::TextEditBuilder; | 8 | use ra_text_edit::TextEditBuilder; |
9 | use rustc_hash::FxHashMap; | ||
13 | 10 | ||
14 | pub struct AstEditor<N: AstNode> { | 11 | pub struct AstEditor<N: AstNode> { |
15 | original_ast: N, | 12 | original_ast: N, |
@@ -25,9 +22,7 @@ impl<N: AstNode> AstEditor<N> { | |||
25 | } | 22 | } |
26 | 23 | ||
27 | pub fn into_text_edit(self, builder: &mut TextEditBuilder) { | 24 | pub fn into_text_edit(self, builder: &mut TextEditBuilder) { |
28 | for (from, to) in algo::diff(&self.original_ast.syntax(), self.ast().syntax()) { | 25 | algo::diff(&self.original_ast.syntax(), self.ast().syntax()).into_text_edit(builder) |
29 | builder.replace(from.text_range(), to.to_string()) | ||
30 | } | ||
31 | } | 26 | } |
32 | 27 | ||
33 | pub fn ast(&self) -> &N { | 28 | pub fn ast(&self) -> &N { |
@@ -47,16 +42,6 @@ impl<N: AstNode> AstEditor<N> { | |||
47 | } | 42 | } |
48 | 43 | ||
49 | #[must_use] | 44 | #[must_use] |
50 | fn insert_children( | ||
51 | &self, | ||
52 | position: InsertPosition<SyntaxElement>, | ||
53 | mut to_insert: impl Iterator<Item = SyntaxElement>, | ||
54 | ) -> N { | ||
55 | let new_syntax = algo::insert_children(self.ast().syntax(), position, &mut to_insert); | ||
56 | N::cast(new_syntax).unwrap() | ||
57 | } | ||
58 | |||
59 | #[must_use] | ||
60 | fn replace_children( | 45 | fn replace_children( |
61 | &self, | 46 | &self, |
62 | to_delete: RangeInclusive<SyntaxElement>, | 47 | to_delete: RangeInclusive<SyntaxElement>, |
@@ -67,84 +52,6 @@ impl<N: AstNode> AstEditor<N> { | |||
67 | } | 52 | } |
68 | } | 53 | } |
69 | 54 | ||
70 | impl AstEditor<ast::RecordFieldList> { | ||
71 | pub fn append_field(&mut self, field: &ast::RecordField) { | ||
72 | self.insert_field(InsertPosition::Last, field) | ||
73 | } | ||
74 | |||
75 | pub fn insert_field( | ||
76 | &mut self, | ||
77 | position: InsertPosition<&'_ ast::RecordField>, | ||
78 | field: &ast::RecordField, | ||
79 | ) { | ||
80 | let is_multiline = self.ast().syntax().text().contains_char('\n'); | ||
81 | let ws; | ||
82 | let space = if is_multiline { | ||
83 | ws = tokens::WsBuilder::new(&format!( | ||
84 | "\n{} ", | ||
85 | leading_indent(self.ast().syntax()).unwrap_or("".into()) | ||
86 | )); | ||
87 | ws.ws() | ||
88 | } else { | ||
89 | tokens::single_space() | ||
90 | }; | ||
91 | |||
92 | let mut to_insert: ArrayVec<[SyntaxElement; 4]> = ArrayVec::new(); | ||
93 | to_insert.push(space.into()); | ||
94 | to_insert.push(field.syntax().clone().into()); | ||
95 | to_insert.push(tokens::comma().into()); | ||
96 | |||
97 | macro_rules! after_l_curly { | ||
98 | () => {{ | ||
99 | let anchor = match self.l_curly() { | ||
100 | Some(it) => it, | ||
101 | None => return, | ||
102 | }; | ||
103 | InsertPosition::After(anchor) | ||
104 | }}; | ||
105 | } | ||
106 | |||
107 | macro_rules! after_field { | ||
108 | ($anchor:expr) => { | ||
109 | if let Some(comma) = $anchor | ||
110 | .syntax() | ||
111 | .siblings_with_tokens(Direction::Next) | ||
112 | .find(|it| it.kind() == T![,]) | ||
113 | { | ||
114 | InsertPosition::After(comma) | ||
115 | } else { | ||
116 | to_insert.insert(0, tokens::comma().into()); | ||
117 | InsertPosition::After($anchor.syntax().clone().into()) | ||
118 | } | ||
119 | }; | ||
120 | }; | ||
121 | |||
122 | let position = match position { | ||
123 | InsertPosition::First => after_l_curly!(), | ||
124 | InsertPosition::Last => { | ||
125 | if !is_multiline { | ||
126 | // don't insert comma before curly | ||
127 | to_insert.pop(); | ||
128 | } | ||
129 | match self.ast().fields().last() { | ||
130 | Some(it) => after_field!(it), | ||
131 | None => after_l_curly!(), | ||
132 | } | ||
133 | } | ||
134 | InsertPosition::Before(anchor) => { | ||
135 | InsertPosition::Before(anchor.syntax().clone().into()) | ||
136 | } | ||
137 | InsertPosition::After(anchor) => after_field!(anchor), | ||
138 | }; | ||
139 | |||
140 | self.ast = self.insert_children(position, to_insert.iter().cloned()); | ||
141 | } | ||
142 | |||
143 | fn l_curly(&self) -> Option<SyntaxElement> { | ||
144 | self.ast().syntax().children_with_tokens().find(|it| it.kind() == T!['{']) | ||
145 | } | ||
146 | } | ||
147 | |||
148 | impl AstEditor<ast::TypeParam> { | 55 | impl AstEditor<ast::TypeParam> { |
149 | pub fn remove_bounds(&mut self) -> &mut Self { | 56 | pub fn remove_bounds(&mut self) -> &mut Self { |
150 | let colon = match self.ast.colon_token() { | 57 | let colon = match self.ast.colon_token() { |