19
19
// List-like invocations with parentheses will be formatted as function calls,
20
20
// and those with brackets will be formatted as array literals.
21
21
22
+ use std:: iter:: repeat;
23
+
22
24
use syntax:: ast;
23
25
use syntax:: codemap:: BytePos ;
24
26
use syntax:: parse:: new_parser_from_tts;
@@ -27,7 +29,7 @@ use syntax::symbol;
27
29
use syntax:: tokenstream:: TokenStream ;
28
30
use syntax:: util:: ThinVec ;
29
31
30
- use Shape ;
32
+ use { Indent , Shape } ;
31
33
use codemap:: SpanUtils ;
32
34
use comment:: { contains_comment, FindUncommented } ;
33
35
use expr:: { rewrite_array, rewrite_call_inner} ;
@@ -116,14 +118,14 @@ pub fn rewrite_macro(
116
118
Ok ( expr) => {
117
119
// Recovered errors.
118
120
if context. parse_session . span_diagnostic . has_errors ( ) {
119
- return Some ( context. snippet ( mac. span ) ) ;
121
+ return indent_macro_snippet ( & context. snippet ( mac. span ) , shape . indent ) ;
120
122
}
121
123
122
124
expr
123
125
}
124
126
Err ( mut e) => {
125
127
e. cancel ( ) ;
126
- return Some ( context. snippet ( mac. span ) ) ;
128
+ return indent_macro_snippet ( & context. snippet ( mac. span ) , shape . indent ) ;
127
129
}
128
130
} ;
129
131
@@ -242,7 +244,7 @@ pub fn rewrite_macro(
242
244
}
243
245
MacroStyle :: Braces => {
244
246
// Skip macro invocations with braces, for now.
245
- None
247
+ indent_macro_snippet ( & context . snippet ( mac . span ) , shape . indent )
246
248
}
247
249
}
248
250
}
@@ -280,3 +282,58 @@ fn macro_style(mac: &ast::Mac, context: &RewriteContext) -> MacroStyle {
280
282
MacroStyle :: Braces
281
283
}
282
284
}
285
+
286
+ /// Indent each line according to the specified `indent`.
287
+ /// e.g.
288
+ /// ```rust
289
+ /// foo!{
290
+ /// x,
291
+ /// y,
292
+ /// foo(
293
+ /// a,
294
+ /// b,
295
+ /// c,
296
+ /// ),
297
+ /// }
298
+ /// ```
299
+ /// will become
300
+ /// ```rust
301
+ /// foo!{
302
+ /// x,
303
+ /// y,
304
+ /// foo(
305
+ /// a,
306
+ /// b,
307
+ /// c,
308
+ // ),
309
+ /// }
310
+ /// ```
311
+ fn indent_macro_snippet ( macro_str : & str , indent : Indent ) -> Option < String > {
312
+ let min_prefix_space_width =
313
+ try_opt ! ( macro_str. lines( ) . skip( 1 ) . map( get_prefix_space_width) . min( ) ) ;
314
+
315
+ let mut lines = macro_str. lines ( ) ;
316
+ let first_line = try_opt ! ( lines. next( ) ) ;
317
+
318
+ Some (
319
+ String :: from ( first_line) + "\n " +
320
+ & lines
321
+ . map ( |line| {
322
+ let new_indent_width = indent. width ( ) +
323
+ get_prefix_space_width ( line)
324
+ . checked_sub ( min_prefix_space_width)
325
+ . unwrap_or ( 0 ) ;
326
+ repeat_white_space ( new_indent_width) + line. trim ( )
327
+ } )
328
+ . collect :: < Vec < _ > > ( )
329
+ . join ( "\n " ) ,
330
+ )
331
+ }
332
+
333
+ fn get_prefix_space_width ( s : & str ) -> usize {
334
+ s. chars ( ) . position ( |c| c != ' ' ) . unwrap_or ( 0 )
335
+ }
336
+
337
+ fn repeat_white_space ( ws_count : usize ) -> String {
338
+ repeat ( " " ) . take ( ws_count) . collect :: < String > ( )
339
+ }
0 commit comments