@@ -289,11 +289,19 @@ fn _replace_children(
289289 with_children ( parent, new_children)
290290}
291291
292+ #[ derive( Debug , PartialEq , Eq , Hash ) ]
293+ enum InsertPos {
294+ FirstChildOf ( SyntaxNode ) ,
295+ // Before(SyntaxElement),
296+ After ( SyntaxElement ) ,
297+ }
298+
292299#[ derive( Default ) ]
293300pub struct SyntaxRewriter < ' a > {
294301 f : Option < Box < dyn Fn ( & SyntaxElement ) -> Option < SyntaxElement > + ' a > > ,
295302 //FIXME: add debug_assertions that all elements are in fact from the same file.
296303 replacements : FxHashMap < SyntaxElement , Replacement > ,
304+ insertions : IndexMap < InsertPos , Vec < SyntaxElement > > ,
297305}
298306
299307impl fmt:: Debug for SyntaxRewriter < ' _ > {
@@ -304,13 +312,96 @@ impl fmt::Debug for SyntaxRewriter<'_> {
304312
305313impl < ' a > SyntaxRewriter < ' a > {
306314 pub fn from_fn ( f : impl Fn ( & SyntaxElement ) -> Option < SyntaxElement > + ' a ) -> SyntaxRewriter < ' a > {
307- SyntaxRewriter { f : Some ( Box :: new ( f) ) , replacements : FxHashMap :: default ( ) }
315+ SyntaxRewriter {
316+ f : Some ( Box :: new ( f) ) ,
317+ replacements : FxHashMap :: default ( ) ,
318+ insertions : IndexMap :: default ( ) ,
319+ }
308320 }
309321 pub fn delete < T : Clone + Into < SyntaxElement > > ( & mut self , what : & T ) {
310322 let what = what. clone ( ) . into ( ) ;
311323 let replacement = Replacement :: Delete ;
312324 self . replacements . insert ( what, replacement) ;
313325 }
326+ pub fn insert_before < T : Clone + Into < SyntaxElement > , U : Clone + Into < SyntaxElement > > (
327+ & mut self ,
328+ before : & T ,
329+ what : & U ,
330+ ) {
331+ let before = before. clone ( ) . into ( ) ;
332+ let pos = match before. prev_sibling_or_token ( ) {
333+ Some ( sibling) => InsertPos :: After ( sibling) ,
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 ( ) ) ;
340+ }
341+ pub fn insert_after < T : Clone + Into < SyntaxElement > , U : Clone + Into < SyntaxElement > > (
342+ & mut self ,
343+ after : & T ,
344+ what : & U ,
345+ ) {
346+ self . insertions
347+ . entry ( InsertPos :: After ( after. clone ( ) . into ( ) ) )
348+ . or_insert_with ( Vec :: new)
349+ . push ( what. clone ( ) . into ( ) ) ;
350+ }
351+ pub fn insert_as_first_child < T : Clone + Into < SyntaxNode > , U : Clone + Into < SyntaxElement > > (
352+ & mut self ,
353+ parent : & T ,
354+ what : & U ,
355+ ) {
356+ self . insertions
357+ . entry ( InsertPos :: FirstChildOf ( parent. clone ( ) . into ( ) ) )
358+ . or_insert_with ( Vec :: new)
359+ . push ( what. clone ( ) . into ( ) ) ;
360+ }
361+ pub fn insert_many_before <
362+ T : Clone + Into < SyntaxElement > ,
363+ U : IntoIterator < Item = SyntaxElement > ,
364+ > (
365+ & mut self ,
366+ before : & T ,
367+ what : U ,
368+ ) {
369+ let before = before. clone ( ) . into ( ) ;
370+ let pos = match before. prev_sibling_or_token ( ) {
371+ Some ( sibling) => InsertPos :: After ( sibling) ,
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) ;
378+ }
379+ pub fn insert_many_after <
380+ T : Clone + Into < SyntaxElement > ,
381+ U : IntoIterator < Item = SyntaxElement > ,
382+ > (
383+ & mut self ,
384+ after : & T ,
385+ what : U ,
386+ ) {
387+ self . insertions
388+ . entry ( InsertPos :: After ( after. clone ( ) . into ( ) ) )
389+ . or_insert_with ( Vec :: new)
390+ . extend ( what) ;
391+ }
392+ pub fn insert_many_as_first_children <
393+ T : Clone + Into < SyntaxNode > ,
394+ U : IntoIterator < Item = SyntaxElement > ,
395+ > (
396+ & mut self ,
397+ parent : & T ,
398+ what : U ,
399+ ) {
400+ self . insertions
401+ . entry ( InsertPos :: FirstChildOf ( parent. clone ( ) . into ( ) ) )
402+ . or_insert_with ( Vec :: new)
403+ . extend ( what)
404+ }
314405 pub fn replace < T : Clone + Into < SyntaxElement > > ( & mut self , what : & T , with : & T ) {
315406 let what = what. clone ( ) . into ( ) ;
316407 let replacement = Replacement :: Single ( with. clone ( ) . into ( ) ) ;
@@ -330,7 +421,7 @@ impl<'a> SyntaxRewriter<'a> {
330421 }
331422
332423 pub fn rewrite ( & self , node : & SyntaxNode ) -> SyntaxNode {
333- if self . f . is_none ( ) && self . replacements . is_empty ( ) {
424+ if self . f . is_none ( ) && self . replacements . is_empty ( ) && self . insertions . is_empty ( ) {
334425 return node. clone ( ) ;
335426 }
336427 self . rewrite_children ( node)
@@ -346,14 +437,22 @@ impl<'a> SyntaxRewriter<'a> {
346437 ///
347438 /// Returns `None` when there are no replacements.
348439 pub fn rewrite_root ( & self ) -> Option < SyntaxNode > {
440+ fn element_to_node_or_parent ( element : & SyntaxElement ) -> SyntaxNode {
441+ match element {
442+ SyntaxElement :: Node ( it) => it. clone ( ) ,
443+ SyntaxElement :: Token ( it) => it. parent ( ) ,
444+ }
445+ }
446+
349447 assert ! ( self . f. is_none( ) ) ;
350448 self . replacements
351449 . keys ( )
352- . map ( |element| match element {
353- SyntaxElement :: Node ( it) => it. clone ( ) ,
354- SyntaxElement :: Token ( it) => it. parent ( ) ,
355- } )
356- // If we only have one replacement, we must return its parent node, since `rewrite` does
450+ . map ( element_to_node_or_parent)
451+ . chain ( self . insertions . keys ( ) . map ( |pos| match pos {
452+ InsertPos :: FirstChildOf ( it) => it. clone ( ) ,
453+ InsertPos :: After ( it) => element_to_node_or_parent ( it) ,
454+ } ) )
455+ // If we only have one replacement/insertion, we must return its parent node, since `rewrite` does
357456 // not replace the node passed to it.
358457 . map ( |it| it. parent ( ) . unwrap_or ( it) )
359458 . fold1 ( |a, b| least_common_ancestor ( & a, & b) . unwrap ( ) )
@@ -367,9 +466,16 @@ impl<'a> SyntaxRewriter<'a> {
367466 self . replacements . get ( element) . cloned ( )
368467 }
369468
469+ fn insertions ( & self , pos : & InsertPos ) -> Option < impl Iterator < Item = SyntaxElement > + ' _ > {
470+ self . insertions . get ( pos) . map ( |insertions| insertions. iter ( ) . cloned ( ) )
471+ }
472+
370473 fn rewrite_children ( & self , node : & SyntaxNode ) -> SyntaxNode {
371474 // FIXME: this could be made much faster.
372475 let mut new_children = Vec :: new ( ) ;
476+ if let Some ( elements) = self . insertions ( & InsertPos :: FirstChildOf ( node. clone ( ) ) ) {
477+ new_children. extend ( elements. map ( element_to_green) ) ;
478+ }
373479 for child in node. children_with_tokens ( ) {
374480 self . rewrite_self ( & mut new_children, & child) ;
375481 }
@@ -383,34 +489,45 @@ impl<'a> SyntaxRewriter<'a> {
383489 ) {
384490 if let Some ( replacement) = self . replacement ( & element) {
385491 match replacement {
386- Replacement :: Single ( NodeOrToken :: Node ( it) ) => {
387- acc. push ( NodeOrToken :: Node ( it. green ( ) . clone ( ) ) )
388- }
389- Replacement :: Single ( NodeOrToken :: Token ( it) ) => {
390- acc. push ( NodeOrToken :: Token ( it. green ( ) . clone ( ) ) )
391- }
492+ Replacement :: Single ( element) => acc. push ( element_to_green ( element) ) ,
392493 Replacement :: Many ( replacements) => {
393- acc. extend ( replacements. iter ( ) . map ( |it| match it {
394- NodeOrToken :: Node ( it) => NodeOrToken :: Node ( it. green ( ) . clone ( ) ) ,
395- NodeOrToken :: Token ( it) => NodeOrToken :: Token ( it. green ( ) . clone ( ) ) ,
396- } ) )
494+ acc. extend ( replacements. into_iter ( ) . map ( element_to_green) )
397495 }
398496 Replacement :: Delete => ( ) ,
399497 } ;
400- return ;
498+ } else {
499+ match element {
500+ NodeOrToken :: Token ( it) => acc. push ( NodeOrToken :: Token ( it. green ( ) . clone ( ) ) ) ,
501+ NodeOrToken :: Node ( it) => {
502+ acc. push ( NodeOrToken :: Node ( self . rewrite_children ( it) . green ( ) . clone ( ) ) ) ;
503+ }
504+ }
505+ }
506+ if let Some ( elements) = self . insertions ( & InsertPos :: After ( element. clone ( ) ) ) {
507+ acc. extend ( elements. map ( element_to_green) ) ;
401508 }
402- let res = match element {
403- NodeOrToken :: Token ( it) => NodeOrToken :: Token ( it. green ( ) . clone ( ) ) ,
404- NodeOrToken :: Node ( it) => NodeOrToken :: Node ( self . rewrite_children ( it) . green ( ) . clone ( ) ) ,
405- } ;
406- acc. push ( res)
509+ }
510+ }
511+
512+ fn element_to_green ( element : SyntaxElement ) -> NodeOrToken < rowan:: GreenNode , rowan:: GreenToken > {
513+ match element {
514+ NodeOrToken :: Node ( it) => NodeOrToken :: Node ( it. green ( ) . clone ( ) ) ,
515+ NodeOrToken :: Token ( it) => NodeOrToken :: Token ( it. green ( ) . clone ( ) ) ,
407516 }
408517}
409518
410519impl ops:: AddAssign for SyntaxRewriter < ' _ > {
411520 fn add_assign ( & mut self , rhs : SyntaxRewriter ) {
412521 assert ! ( rhs. f. is_none( ) ) ;
413- self . replacements . extend ( rhs. replacements )
522+ self . replacements . extend ( rhs. replacements ) ;
523+ for ( pos, insertions) in rhs. insertions . into_iter ( ) {
524+ match self . insertions . entry ( pos) {
525+ indexmap:: map:: Entry :: Occupied ( mut occupied) => {
526+ occupied. get_mut ( ) . extend ( insertions)
527+ }
528+ indexmap:: map:: Entry :: Vacant ( vacant) => drop ( vacant. insert ( insertions) ) ,
529+ }
530+ }
414531 }
415532}
416533
0 commit comments