@@ -16,6 +16,13 @@ use crate::{
16
16
17
17
use super :: * ;
18
18
19
+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
20
+ pub ( super ) enum LineFormat {
21
+ Oneline ,
22
+ Newline ,
23
+ Indentation ,
24
+ }
25
+
19
26
pub ( super ) fn print_body_hir (
20
27
db : & dyn DefDatabase ,
21
28
body : & Body ,
@@ -52,7 +59,14 @@ pub(super) fn print_body_hir(
52
59
}
53
60
} ;
54
61
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
+ } ;
56
70
if let DefWithBodyId :: FunctionId ( it) = owner {
57
71
p. buf . push ( '(' ) ;
58
72
let function_data = & db. function_data ( it) ;
@@ -95,8 +109,14 @@ pub(super) fn print_expr_hir(
95
109
expr : ExprId ,
96
110
edition : Edition ,
97
111
) -> 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
+ } ;
100
120
p. print_expr ( expr) ;
101
121
p. buf
102
122
}
@@ -109,10 +129,10 @@ macro_rules! w {
109
129
110
130
macro_rules! wln {
111
131
( $dst: expr) => {
112
- { let _ = writeln! ( $dst) ; }
132
+ { $dst. newline ( ) ; }
113
133
} ;
114
134
( $dst: expr, $( $arg: tt) * ) => {
115
- { let _ = writeln !( $dst, $( $arg) * ) ; }
135
+ { let _ = w !( $dst, $( $arg) * ) ; $dst . newline ( ) ; }
116
136
} ;
117
137
}
118
138
@@ -121,24 +141,30 @@ struct Printer<'a> {
121
141
body : & ' a Body ,
122
142
buf : String ,
123
143
indent_level : usize ,
124
- needs_indent : bool ,
144
+ line_format : LineFormat ,
125
145
edition : Edition ,
126
146
}
127
147
128
148
impl Write for Printer < ' _ > {
129
149
fn write_str ( & mut self , s : & str ) -> fmt:: Result {
130
150
for line in s. split_inclusive ( '\n' ) {
131
- if self . needs_indent {
151
+ if matches ! ( self . line_format , LineFormat :: Indentation ) {
132
152
match self . buf . chars ( ) . rev ( ) . find ( |ch| * ch != ' ' ) {
133
153
Some ( '\n' ) | None => { }
134
154
_ => self . buf . push ( '\n' ) ,
135
155
}
136
156
self . buf . push_str ( & " " . repeat ( self . indent_level ) ) ;
137
- self . needs_indent = false ;
138
157
}
139
158
140
159
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
+ }
142
168
}
143
169
144
170
Ok ( ( ) )
@@ -161,14 +187,28 @@ impl Printer<'_> {
161
187
}
162
188
}
163
189
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.
164
195
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 " ) ;
170
211
}
171
- writeln ! ( self ) . unwrap ( )
172
212
}
173
213
}
174
214
}
0 commit comments