diff options
Diffstat (limited to 'crates/syntax/src')
-rw-r--r-- | crates/syntax/src/algo.rs | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/crates/syntax/src/algo.rs b/crates/syntax/src/algo.rs index 0baae2f57..065035fe6 100644 --- a/crates/syntax/src/algo.rs +++ b/crates/syntax/src/algo.rs | |||
@@ -292,7 +292,7 @@ fn _replace_children( | |||
292 | #[derive(Debug, PartialEq, Eq, Hash)] | 292 | #[derive(Debug, PartialEq, Eq, Hash)] |
293 | enum InsertPos { | 293 | enum InsertPos { |
294 | FirstChildOf(SyntaxNode), | 294 | FirstChildOf(SyntaxNode), |
295 | Before(SyntaxElement), | 295 | // Before(SyntaxElement), |
296 | After(SyntaxElement), | 296 | After(SyntaxElement), |
297 | } | 297 | } |
298 | 298 | ||
@@ -328,10 +328,15 @@ impl<'a> SyntaxRewriter<'a> { | |||
328 | before: &T, | 328 | before: &T, |
329 | what: &U, | 329 | what: &U, |
330 | ) { | 330 | ) { |
331 | self.insertions | 331 | let before = before.clone().into(); |
332 | .entry(InsertPos::Before(before.clone().into())) | 332 | let pos = match before.prev_sibling_or_token() { |
333 | .or_insert_with(Vec::new) | 333 | Some(sibling) => InsertPos::After(sibling), |
334 | .push(what.clone().into()); | 334 | None => match before.parent() { |
335 | Some(parent) => InsertPos::FirstChildOf(parent), | ||
336 | None => return, | ||
337 | }, | ||
338 | }; | ||
339 | self.insertions.entry(pos).or_insert_with(Vec::new).push(what.clone().into()); | ||
335 | } | 340 | } |
336 | pub fn insert_after<T: Clone + Into<SyntaxElement>, U: Clone + Into<SyntaxElement>>( | 341 | pub fn insert_after<T: Clone + Into<SyntaxElement>, U: Clone + Into<SyntaxElement>>( |
337 | &mut self, | 342 | &mut self, |
@@ -361,10 +366,15 @@ impl<'a> SyntaxRewriter<'a> { | |||
361 | before: &T, | 366 | before: &T, |
362 | what: U, | 367 | what: U, |
363 | ) { | 368 | ) { |
364 | self.insertions | 369 | let before = before.clone().into(); |
365 | .entry(InsertPos::Before(before.clone().into())) | 370 | let pos = match before.prev_sibling_or_token() { |
366 | .or_insert_with(Vec::new) | 371 | Some(sibling) => InsertPos::After(sibling), |
367 | .extend(what); | 372 | None => match before.parent() { |
373 | Some(parent) => InsertPos::FirstChildOf(parent), | ||
374 | None => return, | ||
375 | }, | ||
376 | }; | ||
377 | self.insertions.entry(pos).or_insert_with(Vec::new).extend(what); | ||
368 | } | 378 | } |
369 | pub fn insert_many_after< | 379 | pub fn insert_many_after< |
370 | T: Clone + Into<SyntaxElement>, | 380 | T: Clone + Into<SyntaxElement>, |
@@ -440,7 +450,7 @@ impl<'a> SyntaxRewriter<'a> { | |||
440 | .map(element_to_node_or_parent) | 450 | .map(element_to_node_or_parent) |
441 | .chain(self.insertions.keys().map(|pos| match pos { | 451 | .chain(self.insertions.keys().map(|pos| match pos { |
442 | InsertPos::FirstChildOf(it) => it.clone(), | 452 | InsertPos::FirstChildOf(it) => it.clone(), |
443 | InsertPos::Before(it) | InsertPos::After(it) => element_to_node_or_parent(it), | 453 | InsertPos::After(it) => element_to_node_or_parent(it), |
444 | })) | 454 | })) |
445 | // If we only have one replacement/insertion, we must return its parent node, since `rewrite` does | 455 | // If we only have one replacement/insertion, we must return its parent node, since `rewrite` does |
446 | // not replace the node passed to it. | 456 | // not replace the node passed to it. |
@@ -477,9 +487,6 @@ impl<'a> SyntaxRewriter<'a> { | |||
477 | acc: &mut Vec<NodeOrToken<rowan::GreenNode, rowan::GreenToken>>, | 487 | acc: &mut Vec<NodeOrToken<rowan::GreenNode, rowan::GreenToken>>, |
478 | element: &SyntaxElement, | 488 | element: &SyntaxElement, |
479 | ) { | 489 | ) { |
480 | if let Some(elements) = self.insertions(&InsertPos::Before(element.clone())) { | ||
481 | acc.extend(elements.map(element_to_green)); | ||
482 | } | ||
483 | if let Some(replacement) = self.replacement(&element) { | 490 | if let Some(replacement) = self.replacement(&element) { |
484 | match replacement { | 491 | match replacement { |
485 | Replacement::Single(element) => acc.push(element_to_green(element)), | 492 | Replacement::Single(element) => acc.push(element_to_green(element)), |