11
11
use rewrite:: { Rewrite , RewriteContext } ;
12
12
use lists:: { write_list, itemize_list, ListFormatting , SeparatorTactic , ListTactic } ;
13
13
use string:: { StringFormat , rewrite_string} ;
14
- use utils:: span_after;
14
+ use utils:: { span_after, make_indent } ;
15
15
16
16
use syntax:: { ast, ptr} ;
17
17
use syntax:: codemap:: { Pos , Span , BytePos } ;
@@ -24,35 +24,37 @@ impl Rewrite for ast::Expr {
24
24
ast:: Expr_ :: ExprLit ( ref l) => {
25
25
match l. node {
26
26
ast:: Lit_ :: LitStr ( ref is, _) => {
27
- let result = rewrite_string_lit ( context, & is, l. span , width, offset) ;
28
- debug ! ( "string lit: `{:?}`" , result) ;
29
- return result;
27
+ rewrite_string_lit ( context, & is, l. span , width, offset)
30
28
}
31
- _ => { }
29
+ _ => context . codemap . span_to_snippet ( self . span ) . ok ( )
32
30
}
33
31
}
34
32
ast:: Expr_ :: ExprCall ( ref callee, ref args) => {
35
- return rewrite_call ( context, callee, args, self . span , width, offset) ;
33
+ rewrite_call ( context, callee, args, self . span , width, offset)
36
34
}
37
35
ast:: Expr_ :: ExprParen ( ref subexpr) => {
38
- return rewrite_paren ( context, subexpr, width, offset) ;
36
+ rewrite_paren ( context, subexpr, width, offset)
37
+ }
38
+ ast:: Expr_ :: ExprBinary ( ref op, ref lhs, ref rhs) => {
39
+ rewrite_binary_op ( context, op, lhs, rhs, width, offset)
40
+ }
41
+ ast:: Expr_ :: ExprUnary ( ref op, ref subexpr) => {
42
+ rewrite_unary_op ( context, op, subexpr, width, offset)
39
43
}
40
44
ast:: Expr_ :: ExprStruct ( ref path, ref fields, ref base) => {
41
- return rewrite_struct_lit ( context,
42
- path,
43
- fields,
44
- base. as_ref ( ) . map ( |e| & * * e) ,
45
- self . span ,
46
- width,
47
- offset) ;
45
+ rewrite_struct_lit ( context,
46
+ path,
47
+ fields,
48
+ base. as_ref ( ) . map ( |e| & * * e) ,
49
+ self . span ,
50
+ width,
51
+ offset)
48
52
}
49
53
ast:: Expr_ :: ExprTup ( ref items) => {
50
- return rewrite_tuple_lit ( context, items, self . span , width, offset) ;
54
+ rewrite_tuple_lit ( context, items, self . span , width, offset)
51
55
}
52
- _ => { }
56
+ _ => context . codemap . span_to_snippet ( self . span ) . ok ( )
53
57
}
54
-
55
- context. codemap . span_to_snippet ( self . span ) . ok ( )
56
58
}
57
59
}
58
60
@@ -235,7 +237,7 @@ fn rewrite_tuple_lit(context: &RewriteContext,
235
237
span : Span ,
236
238
width : usize ,
237
239
offset : usize )
238
- -> Option < String > {
240
+ -> Option < String > {
239
241
let indent = offset + 1 ;
240
242
241
243
let items = itemize_list ( context. codemap ,
@@ -272,3 +274,58 @@ fn rewrite_tuple_lit(context: &RewriteContext,
272
274
273
275
Some ( format ! ( "({})" , write_list( & items, & fmt) ) )
274
276
}
277
+
278
+ fn rewrite_binary_op ( context : & RewriteContext ,
279
+ op : & ast:: BinOp ,
280
+ lhs : & ast:: Expr ,
281
+ rhs : & ast:: Expr ,
282
+ width : usize ,
283
+ offset : usize )
284
+ -> Option < String > {
285
+ // FIXME: format comments between operands and operator
286
+
287
+ let operator_str = context. codemap . span_to_snippet ( op. span ) . unwrap ( ) ;
288
+
289
+ // 1 = space between lhs expr and operator
290
+ let mut result = try_opt ! ( lhs. rewrite( context, width - 1 - operator_str. len( ) , offset) ) ;
291
+
292
+ result. push ( ' ' ) ;
293
+ result. push_str ( & operator_str) ;
294
+
295
+ let remaining_width = match result. rfind ( '\n' ) {
296
+ Some ( idx) => ( context. config . max_width + idx) . checked_sub ( result. len ( ) ) . unwrap_or ( 0 ) ,
297
+ None => width. checked_sub ( result. len ( ) ) . unwrap_or ( 0 )
298
+ } ;
299
+
300
+ // Get "full width" rhs and see if it fits on the current line. This
301
+ // usually works fairly well since it tends to place operands of
302
+ // operations with high precendence close together.
303
+ let rhs_result = try_opt ! ( rhs. rewrite( context, width, offset) ) ;
304
+
305
+ if rhs_result. len ( ) > remaining_width {
306
+ result. push ( '\n' ) ;
307
+ result. push_str ( & make_indent ( offset) ) ;
308
+ } else {
309
+ result. push ( ' ' ) ;
310
+ } ;
311
+
312
+ result. push_str ( & rhs_result) ;
313
+ Some ( result)
314
+ }
315
+
316
+ fn rewrite_unary_op ( context : & RewriteContext ,
317
+ op : & ast:: UnOp ,
318
+ expr : & ast:: Expr ,
319
+ width : usize ,
320
+ offset : usize )
321
+ -> Option < String > {
322
+ // For some reason, an UnOp is not spanned like BinOp!
323
+ let operator_str = match * op {
324
+ ast:: UnOp :: UnUniq => "&" ,
325
+ ast:: UnOp :: UnDeref => "*" ,
326
+ ast:: UnOp :: UnNot => "!" ,
327
+ ast:: UnOp :: UnNeg => "-"
328
+ } ;
329
+
330
+ Some ( format ! ( "{}{}" , operator_str, try_opt!( expr. rewrite( context, width - 1 , offset) ) ) )
331
+ }
0 commit comments