Skip to content

Commit 36685f2

Browse files
committed
Comments WIP
1 parent 9771840 commit 36685f2

File tree

3 files changed

+121
-81
lines changed

3 files changed

+121
-81
lines changed

src/macros.rs

Lines changed: 115 additions & 80 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,98 +319,129 @@ 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) = replace_names(old_body);
355+
let old_body = context.snippet(branch.body).trim();
356+
let (body_str, substs) = replace_names(old_body);
346357

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);
349360

350-
result += " {";
361+
result += " {";
351362

352-
let has_block_body = old_body.starts_with("{");
363+
let has_block_body = old_body.starts_with('{');
353364

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+
};
363374

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) {
368377
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+
};
372383

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;
381405
}
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;
394415
}
395-
new_body = new_body.replace(new, old);
396-
}
397416

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+
}
401421
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+
};
405443

406-
result += "}";
407-
if def.legacy {
408-
result += ";";
409-
}
410-
result += "\n";
411-
}
444+
result += write_list(&branch_items, &fmt)?.as_str();
412445

413446
if multi_branch_style {
414447
result += &indent.to_string(context.config);
@@ -753,9 +786,9 @@ impl MacroParser {
753786
// `(` ... `)` `=>` `{` ... `}`
754787
fn parse_branch(&mut self) -> Option<MacroBranch> {
755788
let tok = self.toks.next()?;
756-
let args_paren_kind = match tok {
789+
let (args_span, args_paren_kind) = match tok {
757790
TokenTree::Token(..) => return None,
758-
TokenTree::Delimited(_, ref d) => d.delim,
791+
TokenTree::Delimited(sp, ref d) => (sp, d.delim),
759792
};
760793
let args = tok.joint().into();
761794
match self.toks.next()? {
@@ -773,8 +806,9 @@ impl MacroParser {
773806
self.toks.next();
774807
}
775808
Some(MacroBranch {
776-
args,
777809
args_paren_kind,
810+
args_span,
811+
args,
778812
body,
779813
})
780814
}
@@ -788,8 +822,9 @@ struct Macro {
788822
// FIXME: it would be more efficient to use references to the token streams
789823
// rather than clone them, if we can make the borrowing work out.
790824
struct MacroBranch {
791-
args: ThinTokenStream,
792825
args_paren_kind: DelimToken,
826+
args_span: Span,
827+
args: ThinTokenStream,
793828
body: Span,
794829
}
795830

src/visitor.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
439439
ast::ItemKind::MacroDef(ref def) => {
440440
let rewrite = rewrite_macro_def(
441441
&self.get_context(),
442+
self.shape(),
442443
self.block_indent,
443444
def,
444445
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)