aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/algo.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src/algo.rs')
-rw-r--r--crates/ra_syntax/src/algo.rs36
1 files changed, 28 insertions, 8 deletions
diff --git a/crates/ra_syntax/src/algo.rs b/crates/ra_syntax/src/algo.rs
index 2a8dac757..664894d1f 100644
--- a/crates/ra_syntax/src/algo.rs
+++ b/crates/ra_syntax/src/algo.rs
@@ -266,6 +266,15 @@ impl<'a> SyntaxRewriter<'a> {
266 let replacement = Replacement::Single(with.clone().into()); 266 let replacement = Replacement::Single(with.clone().into());
267 self.replacements.insert(what, replacement); 267 self.replacements.insert(what, replacement);
268 } 268 }
269 pub fn replace_with_many<T: Clone + Into<SyntaxElement>>(
270 &mut self,
271 what: &T,
272 with: Vec<SyntaxElement>,
273 ) {
274 let what = what.clone().into();
275 let replacement = Replacement::Many(with);
276 self.replacements.insert(what, replacement);
277 }
269 pub fn replace_ast<T: AstNode>(&mut self, what: &T, with: &T) { 278 pub fn replace_ast<T: AstNode>(&mut self, what: &T, with: &T) {
270 self.replace(what.syntax(), with.syntax()) 279 self.replace(what.syntax(), with.syntax())
271 } 280 }
@@ -302,31 +311,41 @@ impl<'a> SyntaxRewriter<'a> {
302 311
303 fn rewrite_children(&self, node: &SyntaxNode) -> SyntaxNode { 312 fn rewrite_children(&self, node: &SyntaxNode) -> SyntaxNode {
304 // FIXME: this could be made much faster. 313 // FIXME: this could be made much faster.
305 let new_children = 314 let mut new_children = Vec::new();
306 node.children_with_tokens().flat_map(|it| self.rewrite_self(&it)).collect::<Vec<_>>(); 315 for child in node.children_with_tokens() {
316 self.rewrite_self(&mut new_children, &child);
317 }
307 with_children(node, new_children) 318 with_children(node, new_children)
308 } 319 }
309 320
310 fn rewrite_self( 321 fn rewrite_self(
311 &self, 322 &self,
323 acc: &mut Vec<NodeOrToken<rowan::GreenNode, rowan::GreenToken>>,
312 element: &SyntaxElement, 324 element: &SyntaxElement,
313 ) -> Option<NodeOrToken<rowan::GreenNode, rowan::GreenToken>> { 325 ) {
314 if let Some(replacement) = self.replacement(&element) { 326 if let Some(replacement) = self.replacement(&element) {
315 return match replacement { 327 match replacement {
316 Replacement::Single(NodeOrToken::Node(it)) => { 328 Replacement::Single(NodeOrToken::Node(it)) => {
317 Some(NodeOrToken::Node(it.green().clone())) 329 acc.push(NodeOrToken::Node(it.green().clone()))
318 } 330 }
319 Replacement::Single(NodeOrToken::Token(it)) => { 331 Replacement::Single(NodeOrToken::Token(it)) => {
320 Some(NodeOrToken::Token(it.green().clone())) 332 acc.push(NodeOrToken::Token(it.green().clone()))
321 } 333 }
322 Replacement::Delete => None, 334 Replacement::Many(replacements) => {
335 acc.extend(replacements.iter().map(|it| match it {
336 NodeOrToken::Node(it) => NodeOrToken::Node(it.green().clone()),
337 NodeOrToken::Token(it) => NodeOrToken::Token(it.green().clone()),
338 }))
339 }
340 Replacement::Delete => (),
323 }; 341 };
342 return;
324 } 343 }
325 let res = match element { 344 let res = match element {
326 NodeOrToken::Token(it) => NodeOrToken::Token(it.green().clone()), 345 NodeOrToken::Token(it) => NodeOrToken::Token(it.green().clone()),
327 NodeOrToken::Node(it) => NodeOrToken::Node(self.rewrite_children(it).green().clone()), 346 NodeOrToken::Node(it) => NodeOrToken::Node(self.rewrite_children(it).green().clone()),
328 }; 347 };
329 Some(res) 348 acc.push(res)
330 } 349 }
331} 350}
332 351
@@ -341,6 +360,7 @@ impl ops::AddAssign for SyntaxRewriter<'_> {
341enum Replacement { 360enum Replacement {
342 Delete, 361 Delete,
343 Single(SyntaxElement), 362 Single(SyntaxElement),
363 Many(Vec<SyntaxElement>),
344} 364}
345 365
346fn with_children( 366fn with_children(