@@ -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,12 +109,38 @@ 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
}
103
123
124
+ pub ( super ) fn print_pat_hir (
125
+ db : & dyn DefDatabase ,
126
+ body : & Body ,
127
+ _owner : DefWithBodyId ,
128
+ pat : PatId ,
129
+ oneline : bool ,
130
+ edition : Edition ,
131
+ ) -> String {
132
+ let mut p = Printer {
133
+ db,
134
+ body,
135
+ buf : String :: new ( ) ,
136
+ indent_level : 0 ,
137
+ line_format : if oneline { LineFormat :: Oneline } else { LineFormat :: Newline } ,
138
+ edition,
139
+ } ;
140
+ p. print_pat ( pat) ;
141
+ p. buf
142
+ }
143
+
104
144
macro_rules! w {
105
145
( $dst: expr, $( $arg: tt) * ) => {
106
146
{ let _ = write!( $dst, $( $arg) * ) ; }
@@ -109,10 +149,10 @@ macro_rules! w {
109
149
110
150
macro_rules! wln {
111
151
( $dst: expr) => {
112
- { let _ = writeln! ( $dst) ; }
152
+ { $dst. newline ( ) ; }
113
153
} ;
114
154
( $dst: expr, $( $arg: tt) * ) => {
115
- { let _ = writeln !( $dst, $( $arg) * ) ; }
155
+ { let _ = w !( $dst, $( $arg) * ) ; $dst . newline ( ) ; }
116
156
} ;
117
157
}
118
158
@@ -121,24 +161,30 @@ struct Printer<'a> {
121
161
body : & ' a Body ,
122
162
buf : String ,
123
163
indent_level : usize ,
124
- needs_indent : bool ,
164
+ line_format : LineFormat ,
125
165
edition : Edition ,
126
166
}
127
167
128
168
impl Write for Printer < ' _ > {
129
169
fn write_str ( & mut self , s : & str ) -> fmt:: Result {
130
170
for line in s. split_inclusive ( '\n' ) {
131
- if self . needs_indent {
171
+ if matches ! ( self . line_format , LineFormat :: Indentation ) {
132
172
match self . buf . chars ( ) . rev ( ) . find ( |ch| * ch != ' ' ) {
133
173
Some ( '\n' ) | None => { }
134
174
_ => self . buf . push ( '\n' ) ,
135
175
}
136
176
self . buf . push_str ( & " " . repeat ( self . indent_level ) ) ;
137
- self . needs_indent = false ;
138
177
}
139
178
140
179
self . buf . push_str ( line) ;
141
- self . needs_indent = line. ends_with ( '\n' ) ;
180
+
181
+ if matches ! ( self . line_format, LineFormat :: Newline | LineFormat :: Indentation ) {
182
+ self . line_format = if line. ends_with ( '\n' ) {
183
+ LineFormat :: Indentation
184
+ } else {
185
+ LineFormat :: Newline
186
+ } ;
187
+ }
142
188
}
143
189
144
190
Ok ( ( ) )
@@ -161,14 +207,28 @@ impl Printer<'_> {
161
207
}
162
208
}
163
209
210
+ // Add a newline if the current line is not empty.
211
+ // If the current line is empty, add a space instead.
212
+ //
213
+ // Do not use [`writeln!()`] or [`wln!()`] here, which will result in
214
+ // infinite recursive calls to this function.
164
215
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..) ;
216
+ if matches ! ( self . line_format, LineFormat :: Oneline ) {
217
+ match self . buf . chars ( ) . last ( ) {
218
+ Some ( ' ' ) | None => { }
219
+ Some ( _) => {
220
+ w ! ( self , " " ) ;
221
+ }
222
+ }
223
+ } else {
224
+ match self . buf . chars ( ) . rev ( ) . find_position ( |ch| * ch != ' ' ) {
225
+ Some ( ( _, '\n' ) ) | None => { }
226
+ Some ( ( idx, _) ) => {
227
+ if idx != 0 {
228
+ self . buf . drain ( self . buf . len ( ) - idx..) ;
229
+ }
230
+ w ! ( self , "\n " ) ;
170
231
}
171
- writeln ! ( self ) . unwrap ( )
172
232
}
173
233
}
174
234
}
@@ -539,12 +599,14 @@ impl Printer<'_> {
539
599
w ! ( self , ")" ) ;
540
600
}
541
601
Pat :: Or ( pats) => {
602
+ w ! ( self , "(" ) ;
542
603
for ( i, pat) in pats. iter ( ) . enumerate ( ) {
543
604
if i != 0 {
544
605
w ! ( self , " | " ) ;
545
606
}
546
607
self . print_pat ( * pat) ;
547
608
}
609
+ w ! ( self , ")" ) ;
548
610
}
549
611
Pat :: Record { path, args, ellipsis } => {
550
612
match path {
@@ -554,12 +616,37 @@ impl Printer<'_> {
554
616
555
617
w ! ( self , " {{" ) ;
556
618
let edition = self . edition ;
619
+ let oneline = matches ! ( self . line_format, LineFormat :: Oneline ) ;
557
620
self . indented ( |p| {
558
- for arg in args. iter ( ) {
559
- w ! ( p, "{}: " , arg. name. display( self . db. upcast( ) , edition) ) ;
560
- p. print_pat ( arg. pat ) ;
561
- wln ! ( p, "," ) ;
621
+ for ( idx, arg) in args. iter ( ) . enumerate ( ) {
622
+ let field_name = arg. name . display ( self . db . upcast ( ) , edition) . to_string ( ) ;
623
+
624
+ let mut same_name = false ;
625
+ if let Pat :: Bind { id, subpat : None } = & self . body [ arg. pat ] {
626
+ if let Binding { name, mode : BindingAnnotation :: Unannotated , .. } =
627
+ & self . body . bindings [ * id]
628
+ {
629
+ if name. as_str ( ) == field_name {
630
+ same_name = true ;
631
+ }
632
+ }
633
+ }
634
+
635
+ w ! ( p, "{}" , field_name) ;
636
+
637
+ if !same_name {
638
+ w ! ( p, ": " ) ;
639
+ p. print_pat ( arg. pat ) ;
640
+ }
641
+
642
+ // Do not print the extra comma if the line format is oneline
643
+ if oneline && idx == args. len ( ) - 1 {
644
+ w ! ( p, " " ) ;
645
+ } else {
646
+ wln ! ( p, "," ) ;
647
+ }
562
648
}
649
+
563
650
if * ellipsis {
564
651
wln ! ( p, ".." ) ;
565
652
}
0 commit comments