@@ -4,7 +4,7 @@ use syntax::{
44 SyntaxKind :: { self , * } ,
55 SyntaxNode , SyntaxToken , T , WalkEvent ,
66 ast:: syntax_factory:: SyntaxFactory ,
7- syntax_editor:: { Position , SyntaxEditor } ,
7+ syntax_editor:: { Element , Position , SyntaxEditor } ,
88} ;
99
1010#[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
@@ -31,8 +31,8 @@ pub fn prettify_macro_expansion(
3131 let mut dollar_crate_replacements = Vec :: new ( ) ;
3232 let ( editor, syn) = SyntaxEditor :: new ( syn) ;
3333
34- let before = Position :: before ;
35- let after = Position :: after ;
34+ let before = before_non_wrap ;
35+ let after = after_non_wrap ;
3636
3737 let do_indent = |pos : fn ( _) -> Position , token : & SyntaxToken , indent| {
3838 ( pos ( token. clone ( ) ) , PrettifyWsKind :: Indent ( indent) )
@@ -56,9 +56,9 @@ pub fn prettify_macro_expansion(
5656 _ => false ,
5757 } ;
5858 if ( !is_last_child && is_non_last_newline) || is_always_newline {
59- mods. push ( ( Position :: after ( node. clone ( ) ) , PrettifyWsKind :: Indent ( indent) ) ) ;
59+ mods. push ( ( after_non_wrap ( node. clone ( ) ) , PrettifyWsKind :: Indent ( indent) ) ) ;
6060 if node. parent ( ) . is_some ( ) {
61- mods. push ( ( Position :: after ( node) , PrettifyWsKind :: Newline ) ) ;
61+ mods. push ( ( after_non_wrap ( node) , PrettifyWsKind :: Newline ) ) ;
6262 }
6363 }
6464 continue ;
@@ -176,6 +176,25 @@ pub fn prettify_macro_expansion(
176176 editor. finish ( ) . new_root ( ) . clone ( )
177177}
178178
179+ fn before_non_wrap ( elem : impl Element ) -> Position {
180+ let mut elem = elem. syntax_element ( ) ;
181+ while elem. prev_sibling_or_token ( ) . is_none ( )
182+ && let Some ( parent) = elem. parent ( )
183+ {
184+ elem = parent. into ( ) ;
185+ }
186+ Position :: before ( elem)
187+ }
188+ fn after_non_wrap ( elem : impl Element ) -> Position {
189+ let mut elem = elem. syntax_element ( ) ;
190+ while elem. next_sibling_or_token ( ) . is_none ( )
191+ && let Some ( parent) = elem. parent ( )
192+ {
193+ elem = parent. into ( ) ;
194+ }
195+ Position :: after ( elem)
196+ }
197+
179198fn is_text ( k : SyntaxKind ) -> bool {
180199 // Consider all keywords in all editions.
181200 k. is_any_identifier ( ) || k. is_literal ( ) || k == UNDERSCORE
@@ -187,17 +206,12 @@ mod tests {
187206 use expect_test:: { Expect , expect} ;
188207
189208 #[ expect( deprecated) ]
190- fn check_pretty ( #[ rust_analyzer:: rust_fixture] ra_fixture : & str , expect : Expect ) {
209+ fn pretty_input ( #[ rust_analyzer:: rust_fixture] ra_fixture : & str ) -> SyntaxNode {
191210 let ra_fixture = stdx:: trim_indent ( ra_fixture) ;
192211 let source_file = syntax:: ast:: SourceFile :: parse ( & ra_fixture, span:: Edition :: CURRENT ) ;
193212 let syn = remove_whitespaces ( & source_file. syntax_node ( ) ) ;
194213
195- let pretty = prettify_macro_expansion ( syn, & mut |_, _| None , |_| ( ) ) ;
196- let mut pretty = pretty. to_string ( ) ;
197- if pretty. contains ( '\n' ) {
198- pretty. push ( '\n' ) ;
199- }
200- expect. assert_eq ( & pretty) ;
214+ return prettify_macro_expansion ( syn, & mut |_, _| None , |_| ( ) ) ;
201215
202216 fn remove_whitespaces ( node : & SyntaxNode ) -> SyntaxNode {
203217 let ( editor, node) = SyntaxEditor :: new ( node. clone ( ) ) ;
@@ -211,6 +225,20 @@ mod tests {
211225 }
212226 }
213227
228+ fn check_pretty ( #[ rust_analyzer:: rust_fixture] ra_fixture : & str , expect : Expect ) {
229+ let pretty = pretty_input ( ra_fixture) ;
230+ let mut pretty = pretty. to_string ( ) ;
231+ if pretty. contains ( '\n' ) {
232+ pretty. push ( '\n' ) ;
233+ }
234+ expect. assert_eq ( & pretty) ;
235+ }
236+
237+ fn check_pretty_ast ( #[ rust_analyzer:: rust_fixture] ra_fixture : & str , expect : Expect ) {
238+ let pretty = pretty_input ( ra_fixture) ;
239+ expect. assert_eq ( & format ! ( "{pretty:#?}" ) ) ;
240+ }
241+
214242 #[ test]
215243 fn test_in_macro ( ) {
216244 check_pretty (
@@ -470,4 +498,41 @@ mod tests {
470498 "# ] ] ,
471499 ) ;
472500 }
501+
502+ #[ test]
503+ fn test_insert_outside_node ( ) {
504+ check_pretty_ast (
505+ r#"
506+ pub fn foo() -> i32 {}
507+ "# ,
508+ expect ! [ [ r#"
509+ SOURCE_FILE@0..22
510+ FN@0..22
511+ VISIBILITY@0..3
512+ PUB_KW@0..3 "pub"
513+ WHITESPACE@3..4 " "
514+ FN_KW@4..6 "fn"
515+ WHITESPACE@6..7 " "
516+ NAME@7..10
517+ IDENT@7..10 "foo"
518+ PARAM_LIST@10..12
519+ L_PAREN@10..11 "("
520+ R_PAREN@11..12 ")"
521+ WHITESPACE@12..13 " "
522+ RET_TYPE@13..19
523+ THIN_ARROW@13..15 "->"
524+ WHITESPACE@15..16 " "
525+ PATH_TYPE@16..19
526+ PATH@16..19
527+ PATH_SEGMENT@16..19
528+ NAME_REF@16..19
529+ IDENT@16..19 "i32"
530+ WHITESPACE@19..20 " "
531+ BLOCK_EXPR@20..22
532+ STMT_LIST@20..22
533+ L_CURLY@20..21 "{"
534+ R_CURLY@21..22 "}"
535+ "# ] ] ,
536+ ) ;
537+ }
473538}
0 commit comments