Skip to content

Commit 70e7716

Browse files
committed
Comments WIP
1 parent 41c393c commit 70e7716

File tree

3 files changed

+124
-84
lines changed

3 files changed

+124
-84
lines changed

src/macros.rs

Lines changed: 118 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use syntax::util::ThinVec;
3333
use codemap::SpanUtils;
3434
use comment::{contains_comment, remove_trailing_white_spaces, FindUncommented};
3535
use expr::{rewrite_array, rewrite_call_inner};
36+
use lists::{itemize_list, write_list, DefinitiveListTactic, ListFormatting, SeparatorPlace, SeparatorTactic};
3637
use rewrite::{Rewrite, RewriteContext};
3738
use shape::{Indent, Shape};
3839
use utils::{format_visibility, mk_sp};
@@ -283,6 +284,7 @@ pub fn rewrite_macro(
283284

284285
pub fn rewrite_macro_def(
285286
context: &RewriteContext,
287+
shape: Shape,
286288
indent: Indent,
287289
def: &ast::MacroDef,
288290
ident: ast::Ident,
@@ -317,101 +319,132 @@ pub fn rewrite_macro_def(
317319

318320
let mac_indent_str = mac_indent.to_string(context.config);
319321

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+
}
326337

327-
let args = format_macro_args(branch.args)?;
338+
let args = format_macro_args(branch.args.clone())?;
328339

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+
}
337348

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.
343354

344-
let old_body = context.snippet(branch.body).trim();
345-
let (body_str, substs) = match replace_names(old_body) {
346-
Some(result) => result,
347-
None => return snippet,
348-
};
355+
let old_body = context.snippet(branch.body).trim();
356+
let (body_str, substs) = match replace_names(old_body) {
357+
Some(result) => result,
358+
None => return snippet,
359+
};
349360

350-
let mut config = context.config.clone();
351-
config.set().hide_parse_errors(true);
361+
let mut config = context.config.clone();
362+
config.set().hide_parse_errors(true);
352363

353-
result += " {";
364+
result += " {";
354365

355-
let has_block_body = old_body.starts_with("{");
366+
let has_block_body = old_body.starts_with('{');
356367

357-
let body_indent = if has_block_body {
358-
mac_indent
359-
} else {
360-
// We'll hack the indent below, take this into account when formatting,
361-
let body_indent = mac_indent.block_indent(&config);
362-
let new_width = config.max_width() - body_indent.width();
363-
config.set().max_width(new_width);
364-
body_indent
365-
};
368+
let body_indent = if has_block_body {
369+
mac_indent
370+
} else {
371+
// We'll hack the indent below, take this into account when formatting,
372+
let body_indent = mac_indent.block_indent(&config);
373+
let new_width = config.max_width() - body_indent.width();
374+
config.set().max_width(new_width);
375+
body_indent
376+
};
366377

367-
// First try to format as items, then as statements.
368-
let new_body = match ::format_snippet(&body_str, &config) {
369-
Some(new_body) => new_body,
370-
None => match ::format_code_block(&body_str, &config) {
378+
// First try to format as items, then as statements.
379+
let new_body = match ::format_snippet(&body_str, &config) {
371380
Some(new_body) => new_body,
372-
None => return snippet,
373-
},
374-
};
381+
None => match ::format_code_block(&body_str, &config) {
382+
Some(new_body) => new_body,
383+
None => return None,
384+
},
385+
};
375386

376-
// Indent the body since it is in a block.
377-
let indent_str = body_indent.to_string(&config);
378-
let mut new_body = new_body
379-
.trim_right()
380-
.lines()
381-
.fold(String::new(), |mut s, l| {
382-
if !l.is_empty() {
383-
s += &indent_str;
387+
// Indent the body since it is in a block.
388+
let indent_str = body_indent.to_string(&config);
389+
let mut new_body = new_body
390+
.trim_right()
391+
.lines()
392+
.fold(String::new(), |mut s, l| {
393+
if !l.is_empty() {
394+
s += &indent_str;
395+
}
396+
s + l + "\n"
397+
});
398+
399+
// Undo our replacement of macro variables.
400+
// FIXME: this could be *much* more efficient.
401+
for (old, new) in &substs {
402+
if old_body.find(new).is_some() {
403+
debug!(
404+
"rewrite_macro_def: bailing matching variable: `{}` in `{}`",
405+
new, ident
406+
);
407+
return None;
384408
}
385-
s + l + "\n"
386-
});
387-
388-
// Undo our replacement of macro variables.
389-
// FIXME: this could be *much* more efficient.
390-
for (old, new) in &substs {
391-
if old_body.find(new).is_some() {
392-
debug!(
393-
"rewrite_macro_def: bailing matching variable: `{}` in `{}`",
394-
new, ident
395-
);
396-
return snippet;
409+
new_body = new_body.replace(new, old);
397410
}
398-
new_body = new_body.replace(new, old);
399-
}
400411

401-
if has_block_body {
402-
result += new_body.trim();
403-
} else if !new_body.is_empty() {
412+
if has_block_body {
413+
result += new_body.trim();
414+
} else if !new_body.is_empty() {
415+
result += "\n";
416+
result += &new_body;
417+
result += &mac_indent_str;
418+
}
419+
420+
result += "}";
421+
if def.legacy {
422+
result += ";";
423+
}
404424
result += "\n";
405-
result += &new_body;
406-
result += &mac_indent_str;
407-
}
425+
Some(result)
426+
},
427+
span.lo(),
428+
span.hi(),
429+
false
430+
).collect::<Vec<_>>();
431+
432+
let arm_shape = shape
433+
.block_indent(context.config.tab_spaces())
434+
.with_max_width(context.config);
435+
436+
let fmt = ListFormatting {
437+
tactic: DefinitiveListTactic::Vertical,
438+
separator: "",
439+
trailing_separator: SeparatorTactic::Never,
440+
separator_place: SeparatorPlace::Back,
441+
shape: arm_shape,
442+
ends_with_newline: false,
443+
preserve_newline: true,
444+
config: context.config,
445+
};
408446

409-
result += "}";
410-
if def.legacy {
411-
result += ";";
412-
}
413-
result += "\n";
414-
}
447+
result += write_list(&branch_items, &fmt)?.as_str();
415448

416449
if multi_branch_style {
417450
result += &indent.to_string(context.config);
@@ -759,9 +792,9 @@ impl MacroParser {
759792
// `(` ... `)` `=>` `{` ... `}`
760793
fn parse_branch(&mut self) -> Option<MacroBranch> {
761794
let tok = self.toks.next()?;
762-
let args_paren_kind = match tok {
795+
let (args_span, args_paren_kind) = match tok {
763796
TokenTree::Token(..) => return None,
764-
TokenTree::Delimited(_, ref d) => d.delim,
797+
TokenTree::Delimited(sp, ref d) => (sp, d.delim),
765798
};
766799
let args = tok.joint().into();
767800
match self.toks.next()? {
@@ -779,8 +812,9 @@ impl MacroParser {
779812
self.toks.next();
780813
}
781814
Some(MacroBranch {
782-
args,
783815
args_paren_kind,
816+
args_span,
817+
args,
784818
body,
785819
})
786820
}
@@ -794,8 +828,9 @@ struct Macro {
794828
// FIXME: it would be more efficient to use references to the token streams
795829
// rather than clone them, if we can make the borrowing work out.
796830
struct MacroBranch {
797-
args: ThinTokenStream,
798831
args_paren_kind: DelimToken,
832+
args_span: Span,
833+
args: ThinTokenStream,
799834
body: Span,
800835
}
801836

src/visitor.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
451451
ast::ItemKind::MacroDef(ref def) => {
452452
let rewrite = rewrite_macro_def(
453453
&self.get_context(),
454+
self.shape(),
454455
self.block_indent,
455456
def,
456457
item.ident,

tests/source/macro_rules.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
macro_rules! m {
2+
// a
23
($expr :expr, $( $func : ident ) * ) => {
34
{
45
let x = $expr;
@@ -8,8 +9,11 @@ macro_rules! m {
89
}
910
};
1011

11-
() => { };
12+
/* b */
1213

14+
() => {/* c */};
15+
16+
// d
1317
( $item:ident ) => {
1418
mod macro_item { struct $item ; }
1519
};

0 commit comments

Comments
 (0)