@@ -33,6 +33,7 @@ use syntax::util::ThinVec;
33
33
use codemap:: SpanUtils ;
34
34
use comment:: { contains_comment, remove_trailing_white_spaces, FindUncommented } ;
35
35
use expr:: { rewrite_array, rewrite_call_inner} ;
36
+ use lists:: { itemize_list, write_list, DefinitiveListTactic , ListFormatting , SeparatorPlace , SeparatorTactic } ;
36
37
use rewrite:: { Rewrite , RewriteContext } ;
37
38
use shape:: { Indent , Shape } ;
38
39
use utils:: { format_visibility, mk_sp} ;
@@ -283,6 +284,7 @@ pub fn rewrite_macro(
283
284
284
285
pub fn rewrite_macro_def (
285
286
context : & RewriteContext ,
287
+ shape : Shape ,
286
288
indent : Indent ,
287
289
def : & ast:: MacroDef ,
288
290
ident : ast:: Ident ,
@@ -317,98 +319,129 @@ pub fn rewrite_macro_def(
317
319
318
320
let mac_indent_str = mac_indent. to_string ( context. config ) ;
319
321
320
- for branch in parsed_def. branches {
321
- // Only attempt to format function-like macros.
322
- if branch. args_paren_kind != DelimToken :: Paren {
323
- // FIXME(#1539): implement for non-sugared macros.
324
- return snippet;
325
- }
322
+ let branch_items = itemize_list (
323
+ context. codemap ,
324
+ parsed_def. branches . iter ( ) ,
325
+ "" ,
326
+ "" ,
327
+ |branch| branch. args_span . lo ( ) ,
328
+ |branch| branch. body . hi ( ) ,
329
+ |branch| {
330
+ let mut result = String :: new ( ) ;
331
+
332
+ // Only attempt to format function-like macros.
333
+ if branch. args_paren_kind != DelimToken :: Paren {
334
+ // FIXME(#1539): implement for non-sugared macros.
335
+ return None ;
336
+ }
326
337
327
- let args = format_macro_args ( branch. args ) ?;
338
+ let args = format_macro_args ( branch. args . clone ( ) ) ?;
328
339
329
- if multi_branch_style {
330
- result += "\n " ;
331
- result += & mac_indent_str;
332
- result += & args;
333
- result += " =>" ;
334
- } else {
335
- result += & args;
336
- }
340
+ if multi_branch_style {
341
+ result += "\n " ;
342
+ result += & mac_indent_str;
343
+ result += & args;
344
+ result += " =>" ;
345
+ } else {
346
+ result += & args;
347
+ }
337
348
338
- // The macro body is the most interesting part. It might end up as various
339
- // AST nodes, but also has special variables (e.g, `$foo`) which can't be
340
- // parsed as regular Rust code (and note that these can be escaped using
341
- // `$$`). We'll try and format like an AST node, but we'll substitute
342
- // variables for new names with the same length first.
349
+ // The macro body is the most interesting part. It might end up as various
350
+ // AST nodes, but also has special variables (e.g, `$foo`) which can't be
351
+ // parsed as regular Rust code (and note that these can be escaped using
352
+ // `$$`). We'll try and format like an AST node, but we'll substitute
353
+ // variables for new names with the same length first.
343
354
344
- let old_body = context. snippet ( branch. body ) . trim ( ) ;
345
- let ( body_str, substs) = replace_names ( old_body) ;
355
+ let old_body = context. snippet ( branch. body ) . trim ( ) ;
356
+ let ( body_str, substs) = replace_names ( old_body) ;
346
357
347
- let mut config = context. config . clone ( ) ;
348
- config. set ( ) . hide_parse_errors ( true ) ;
358
+ let mut config = context. config . clone ( ) ;
359
+ config. set ( ) . hide_parse_errors ( true ) ;
349
360
350
- result += " {" ;
361
+ result += " {" ;
351
362
352
- let has_block_body = old_body. starts_with ( "{" ) ;
363
+ let has_block_body = old_body. starts_with ( '{' ) ;
353
364
354
- let body_indent = if has_block_body {
355
- mac_indent
356
- } else {
357
- // We'll hack the indent below, take this into account when formatting,
358
- let body_indent = mac_indent. block_indent ( & config) ;
359
- let new_width = config. max_width ( ) - body_indent. width ( ) ;
360
- config. set ( ) . max_width ( new_width) ;
361
- body_indent
362
- } ;
365
+ let body_indent = if has_block_body {
366
+ mac_indent
367
+ } else {
368
+ // We'll hack the indent below, take this into account when formatting,
369
+ let body_indent = mac_indent. block_indent ( & config) ;
370
+ let new_width = config. max_width ( ) - body_indent. width ( ) ;
371
+ config. set ( ) . max_width ( new_width) ;
372
+ body_indent
373
+ } ;
363
374
364
- // First try to format as items, then as statements.
365
- let new_body = match :: format_snippet ( & body_str, & config) {
366
- Some ( new_body) => new_body,
367
- None => match :: format_code_block ( & body_str, & config) {
375
+ // First try to format as items, then as statements.
376
+ let new_body = match :: format_snippet ( & body_str, & config) {
368
377
Some ( new_body) => new_body,
369
- None => return snippet,
370
- } ,
371
- } ;
378
+ None => match :: format_code_block ( & body_str, & config) {
379
+ Some ( new_body) => new_body,
380
+ None => return None ,
381
+ } ,
382
+ } ;
372
383
373
- // Indent the body since it is in a block.
374
- let indent_str = body_indent. to_string ( & config) ;
375
- let mut new_body = new_body
376
- . trim_right ( )
377
- . lines ( )
378
- . fold ( String :: new ( ) , |mut s, l| {
379
- if !l. is_empty ( ) {
380
- s += & indent_str;
384
+ // Indent the body since it is in a block.
385
+ let indent_str = body_indent. to_string ( & config) ;
386
+ let mut new_body = new_body
387
+ . trim_right ( )
388
+ . lines ( )
389
+ . fold ( String :: new ( ) , |mut s, l| {
390
+ if !l. is_empty ( ) {
391
+ s += & indent_str;
392
+ }
393
+ s + l + "\n "
394
+ } ) ;
395
+
396
+ // Undo our replacement of macro variables.
397
+ // FIXME: this could be *much* more efficient.
398
+ for ( old, new) in & substs {
399
+ if old_body. find ( new) . is_some ( ) {
400
+ debug ! (
401
+ "rewrite_macro_def: bailing matching variable: `{}` in `{}`" ,
402
+ new, ident
403
+ ) ;
404
+ return None ;
381
405
}
382
- s + l + "\n "
383
- } ) ;
384
-
385
- // Undo our replacement of macro variables.
386
- // FIXME: this could be *much* more efficient.
387
- for ( old, new) in & substs {
388
- if old_body. find ( new) . is_some ( ) {
389
- debug ! (
390
- "rewrite_macro_def: bailing matching variable: `{}` in `{}`" ,
391
- new, ident
392
- ) ;
393
- return snippet;
406
+ new_body = new_body. replace ( new, old) ;
407
+ }
408
+
409
+ if has_block_body {
410
+ result += new_body. trim ( ) ;
411
+ } else if !new_body. is_empty ( ) {
412
+ result += "\n " ;
413
+ result += & new_body;
414
+ result += & mac_indent_str;
394
415
}
395
- new_body = new_body. replace ( new, old) ;
396
- }
397
416
398
- if has_block_body {
399
- result += new_body. trim ( ) ;
400
- } else if !new_body. is_empty ( ) {
417
+ result += "}" ;
418
+ if def. legacy {
419
+ result += ";" ;
420
+ }
401
421
result += "\n " ;
402
- result += & new_body;
403
- result += & mac_indent_str;
404
- }
422
+ Some ( result)
423
+ } ,
424
+ span. lo ( ) ,
425
+ span. hi ( ) ,
426
+ false
427
+ ) . collect :: < Vec < _ > > ( ) ;
428
+
429
+ let arm_shape = shape
430
+ . block_indent ( context. config . tab_spaces ( ) )
431
+ . with_max_width ( context. config ) ;
432
+
433
+ let fmt = ListFormatting {
434
+ tactic : DefinitiveListTactic :: Vertical ,
435
+ separator : "" ,
436
+ trailing_separator : SeparatorTactic :: Never ,
437
+ separator_place : SeparatorPlace :: Back ,
438
+ shape : arm_shape,
439
+ ends_with_newline : false ,
440
+ preserve_newline : true ,
441
+ config : context. config ,
442
+ } ;
405
443
406
- result += "}" ;
407
- if def. legacy {
408
- result += ";" ;
409
- }
410
- result += "\n " ;
411
- }
444
+ result += write_list ( & branch_items, & fmt) ?. as_str ( ) ;
412
445
413
446
if multi_branch_style {
414
447
result += & indent. to_string ( context. config ) ;
@@ -753,9 +786,9 @@ impl MacroParser {
753
786
// `(` ... `)` `=>` `{` ... `}`
754
787
fn parse_branch ( & mut self ) -> Option < MacroBranch > {
755
788
let tok = self . toks . next ( ) ?;
756
- let args_paren_kind = match tok {
789
+ let ( args_span , args_paren_kind) = match tok {
757
790
TokenTree :: Token ( ..) => return None ,
758
- TokenTree :: Delimited ( _ , ref d) => d. delim ,
791
+ TokenTree :: Delimited ( sp , ref d) => ( sp , d. delim ) ,
759
792
} ;
760
793
let args = tok. joint ( ) . into ( ) ;
761
794
match self . toks . next ( ) ? {
@@ -773,8 +806,9 @@ impl MacroParser {
773
806
self . toks . next ( ) ;
774
807
}
775
808
Some ( MacroBranch {
776
- args,
777
809
args_paren_kind,
810
+ args_span,
811
+ args,
778
812
body,
779
813
} )
780
814
}
@@ -788,8 +822,9 @@ struct Macro {
788
822
// FIXME: it would be more efficient to use references to the token streams
789
823
// rather than clone them, if we can make the borrowing work out.
790
824
struct MacroBranch {
791
- args : ThinTokenStream ,
792
825
args_paren_kind : DelimToken ,
826
+ args_span : Span ,
827
+ args : ThinTokenStream ,
793
828
body : Span ,
794
829
}
795
830
0 commit comments