@@ -14,9 +14,9 @@ use syntax::{
1414 edit_in_place:: { AttrsOwnerEdit , Indent , Removable } ,
1515 make, HasArgList , HasAttrs , HasGenericParams , HasName , HasTypeBounds , Whitespace ,
1616 } ,
17- ted, AstNode , AstToken , Direction , SourceFile ,
17+ ted, AstNode , AstToken , Direction , NodeOrToken , SourceFile ,
1818 SyntaxKind :: * ,
19- SyntaxNode , TextRange , TextSize , T ,
19+ SyntaxNode , SyntaxToken , TextRange , TextSize , T ,
2020} ;
2121
2222use crate :: assist_context:: { AssistContext , SourceChangeBuilder } ;
@@ -916,3 +916,46 @@ pub(crate) fn replace_record_field_expr(
916916 edit. replace ( file_range. range , initializer. syntax ( ) . text ( ) ) ;
917917 }
918918}
919+
920+ /// Creates a token tree list from a syntax node, creating the needed delimited sub token trees.
921+ /// Assumes that the input syntax node is a valid syntax tree.
922+ pub ( crate ) fn tt_from_syntax ( node : SyntaxNode ) -> Vec < NodeOrToken < ast:: TokenTree , SyntaxToken > > {
923+ let mut tt_stack = vec ! [ ( None , vec![ ] ) ] ;
924+
925+ for element in node. descendants_with_tokens ( ) {
926+ let NodeOrToken :: Token ( token) = element else { continue } ;
927+
928+ match token. kind ( ) {
929+ T ! [ '(' ] | T ! [ '{' ] | T ! [ '[' ] => {
930+ // Found an opening delimeter, start a new sub token tree
931+ tt_stack. push ( ( Some ( token. kind ( ) ) , vec ! [ ] ) ) ;
932+ }
933+ T ! [ ')' ] | T ! [ '}' ] | T ! [ ']' ] => {
934+ // Closing a subtree
935+ let ( delimiter, tt) = tt_stack. pop ( ) . expect ( "unbalanced delimeters" ) ;
936+ let ( _, parent_tt) = tt_stack
937+ . last_mut ( )
938+ . expect ( "parent token tree was closed before it was completed" ) ;
939+ let closing_delimiter = delimiter. map ( |it| match it {
940+ T ! [ '(' ] => T ! [ ')' ] ,
941+ T ! [ '{' ] => T ! [ '}' ] ,
942+ T ! [ '[' ] => T ! [ ']' ] ,
943+ _ => unreachable ! ( ) ,
944+ } ) ;
945+ stdx:: always!(
946+ closing_delimiter == Some ( token. kind( ) ) ,
947+ "mismatched opening and closing delimiters"
948+ ) ;
949+
950+ let sub_tt = make:: token_tree ( delimiter. expect ( "unbalanced delimiters" ) , tt) ;
951+ parent_tt. push ( NodeOrToken :: Node ( sub_tt) ) ;
952+ }
953+ _ => {
954+ let ( _, current_tt) = tt_stack. last_mut ( ) . expect ( "unmatched delimiters" ) ;
955+ current_tt. push ( NodeOrToken :: Token ( token) )
956+ }
957+ }
958+ }
959+
960+ tt_stack. pop ( ) . expect ( "parent token tree was closed before it was completed" ) . 1
961+ }
0 commit comments