@@ -16,6 +16,13 @@ use crate::{
1616
1717use super :: * ;
1818
19+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
20+ pub ( super ) enum LineFormat {
21+ Oneline ,
22+ Newline ,
23+ Indentation ,
24+ }
25+
1926pub ( super ) fn print_body_hir (
2027 db : & dyn DefDatabase ,
2128 body : & Body ,
@@ -52,7 +59,14 @@ pub(super) fn print_body_hir(
5259 }
5360 } ;
5461
55- let mut p = Printer { db, body, buf : header, indent_level : 0 , needs_indent : false , edition } ;
62+ let mut p = Printer {
63+ db,
64+ body,
65+ buf : header,
66+ indent_level : 0 ,
67+ line_format : LineFormat :: Newline ,
68+ edition,
69+ } ;
5670 if let DefWithBodyId :: FunctionId ( it) = owner {
5771 p. buf . push ( '(' ) ;
5872 let function_data = & db. function_data ( it) ;
@@ -95,8 +109,14 @@ pub(super) fn print_expr_hir(
95109 expr : ExprId ,
96110 edition : Edition ,
97111) -> String {
98- let mut p =
99- Printer { db, body, buf : String :: new ( ) , indent_level : 0 , needs_indent : false , edition } ;
112+ let mut p = Printer {
113+ db,
114+ body,
115+ buf : String :: new ( ) ,
116+ indent_level : 0 ,
117+ line_format : LineFormat :: Newline ,
118+ edition,
119+ } ;
100120 p. print_expr ( expr) ;
101121 p. buf
102122}
@@ -109,10 +129,10 @@ macro_rules! w {
109129
110130macro_rules! wln {
111131 ( $dst: expr) => {
112- { let _ = writeln! ( $dst) ; }
132+ { $dst. newline ( ) ; }
113133 } ;
114134 ( $dst: expr, $( $arg: tt) * ) => {
115- { let _ = writeln !( $dst, $( $arg) * ) ; }
135+ { let _ = w !( $dst, $( $arg) * ) ; $dst . newline ( ) ; }
116136 } ;
117137}
118138
@@ -121,24 +141,30 @@ struct Printer<'a> {
121141 body : & ' a Body ,
122142 buf : String ,
123143 indent_level : usize ,
124- needs_indent : bool ,
144+ line_format : LineFormat ,
125145 edition : Edition ,
126146}
127147
128148impl Write for Printer < ' _ > {
129149 fn write_str ( & mut self , s : & str ) -> fmt:: Result {
130150 for line in s. split_inclusive ( '\n' ) {
131- if self . needs_indent {
151+ if matches ! ( self . line_format , LineFormat :: Indentation ) {
132152 match self . buf . chars ( ) . rev ( ) . find ( |ch| * ch != ' ' ) {
133153 Some ( '\n' ) | None => { }
134154 _ => self . buf . push ( '\n' ) ,
135155 }
136156 self . buf . push_str ( & " " . repeat ( self . indent_level ) ) ;
137- self . needs_indent = false ;
138157 }
139158
140159 self . buf . push_str ( line) ;
141- self . needs_indent = line. ends_with ( '\n' ) ;
160+
161+ if matches ! ( self . line_format, LineFormat :: Newline | LineFormat :: Indentation ) {
162+ self . line_format = if line. ends_with ( '\n' ) {
163+ LineFormat :: Indentation
164+ } else {
165+ LineFormat :: Newline
166+ } ;
167+ }
142168 }
143169
144170 Ok ( ( ) )
@@ -161,14 +187,28 @@ impl Printer<'_> {
161187 }
162188 }
163189
190+ // Add a newline if the current line is not empty.
191+ // If the current line is empty, add a space instead.
192+ //
193+ // Do not use [`writeln!()`] or [`wln!()`] here, which will result in
194+ // infinite recursive calls to this function.
164195 fn newline ( & mut self ) {
165- match self . buf . chars ( ) . rev ( ) . find_position ( |ch| * ch != ' ' ) {
166- Some ( ( _, '\n' ) ) | None => { }
167- Some ( ( idx, _) ) => {
168- if idx != 0 {
169- self . buf . drain ( self . buf . len ( ) - idx..) ;
196+ if matches ! ( self . line_format, LineFormat :: Oneline ) {
197+ match self . buf . chars ( ) . last ( ) {
198+ Some ( ' ' ) | None => { }
199+ Some ( _) => {
200+ w ! ( self , " " ) ;
201+ }
202+ }
203+ } else {
204+ match self . buf . chars ( ) . rev ( ) . find_position ( |ch| * ch != ' ' ) {
205+ Some ( ( _, '\n' ) ) | None => { }
206+ Some ( ( idx, _) ) => {
207+ if idx != 0 {
208+ self . buf . drain ( self . buf . len ( ) - idx..) ;
209+ }
210+ w ! ( self , "\n " ) ;
170211 }
171- writeln ! ( self ) . unwrap ( )
172212 }
173213 }
174214 }
0 commit comments