Skip to content

Commit a221757

Browse files
committed
Extract branch rewrite function
1 parent e718546 commit a221757

File tree

1 file changed

+95
-95
lines changed

1 file changed

+95
-95
lines changed

src/macros.rs

Lines changed: 95 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -310,115 +310,27 @@ pub fn rewrite_macro_def(
310310

311311
let multi_branch_style = def.legacy || parsed_def.branches.len() != 1;
312312

313-
let mac_indent = if multi_branch_style {
314-
indent.block_indent(context.config)
313+
let arm_shape = if multi_branch_style {
314+
shape
315+
.block_indent(context.config.tab_spaces())
316+
.with_max_width(context.config)
315317
} else {
316-
indent
318+
shape
317319
};
318320

319-
let mac_indent_str = mac_indent.to_string(context.config);
320-
321321
let branch_items = itemize_list(
322322
context.codemap,
323323
parsed_def.branches.iter(),
324324
"}",
325325
";",
326326
|branch| branch.span.lo(),
327327
|branch| branch.span.hi(),
328-
|branch| {
329-
// Only attempt to format function-like macros.
330-
if branch.args_paren_kind != DelimToken::Paren {
331-
// FIXME(#1539): implement for non-sugared macros.
332-
return None;
333-
}
334-
335-
let mut result = format_macro_args(branch.args.clone())?;
336-
337-
if multi_branch_style {
338-
result += " =>";
339-
}
340-
341-
// The macro body is the most interesting part. It might end up as various
342-
// AST nodes, but also has special variables (e.g, `$foo`) which can't be
343-
// parsed as regular Rust code (and note that these can be escaped using
344-
// `$$`). We'll try and format like an AST node, but we'll substitute
345-
// variables for new names with the same length first.
346-
347-
let old_body = context.snippet(branch.body).trim();
348-
let (body_str, substs) = replace_names(old_body);
349-
350-
let mut config = context.config.clone();
351-
config.set().hide_parse_errors(true);
352-
353-
result += " {";
354-
355-
let has_block_body = old_body.starts_with('{');
356-
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-
};
366-
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) {
371-
Some(new_body) => new_body,
372-
None => return None,
373-
},
374-
};
375-
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;
384-
}
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 None;
397-
}
398-
new_body = new_body.replace(new, old);
399-
}
400-
401-
if has_block_body {
402-
result += new_body.trim();
403-
} else if !new_body.is_empty() {
404-
result += "\n";
405-
result += &new_body;
406-
result += &mac_indent_str;
407-
}
408-
409-
result += "}";
410-
411-
Some(result)
412-
},
328+
|branch| branch.rewrite(context, arm_shape, multi_branch_style),
413329
context.codemap.span_after(span, "{"),
414330
span.hi(),
415331
false,
416332
).collect::<Vec<_>>();
417333

418-
let arm_shape = shape
419-
.block_indent(context.config.tab_spaces())
420-
.with_max_width(context.config);
421-
422334
let fmt = ListFormatting {
423335
tactic: DefinitiveListTactic::Vertical,
424336
separator: if def.legacy { ";" } else { "" },
@@ -432,7 +344,7 @@ pub fn rewrite_macro_def(
432344

433345
if multi_branch_style {
434346
result += " {\n";
435-
result += &mac_indent_str;
347+
result += &arm_shape.indent.to_string(context.config);
436348
}
437349

438350
result += write_list(&branch_items, &fmt)?.as_str();
@@ -827,6 +739,94 @@ struct MacroBranch {
827739
body: Span,
828740
}
829741

742+
impl MacroBranch {
743+
fn rewrite(&self, context: &RewriteContext, shape: Shape, multi_branch_style: bool) -> Option<String> {
744+
// Only attempt to format function-like macros.
745+
if self.args_paren_kind != DelimToken::Paren {
746+
// FIXME(#1539): implement for non-sugared macros.
747+
return None;
748+
}
749+
750+
let mut result = format_macro_args(self.args.clone())?;
751+
752+
if multi_branch_style {
753+
result += " =>";
754+
}
755+
756+
// The macro body is the most interesting part. It might end up as various
757+
// AST nodes, but also has special variables (e.g, `$foo`) which can't be
758+
// parsed as regular Rust code (and note that these can be escaped using
759+
// `$$`). We'll try and format like an AST node, but we'll substitute
760+
// variables for new names with the same length first.
761+
762+
let old_body = context.snippet(self.body).trim();
763+
let (body_str, substs) = replace_names(old_body);
764+
765+
let mut config = context.config.clone();
766+
config.set().hide_parse_errors(true);
767+
768+
result += " {";
769+
770+
let has_block_body = old_body.starts_with('{');
771+
772+
let body_indent = if has_block_body {
773+
shape.indent
774+
} else {
775+
// We'll hack the indent below, take this into account when formatting,
776+
let body_indent = shape.indent.block_indent(&config);
777+
let new_width = config.max_width() - body_indent.width();
778+
config.set().max_width(new_width);
779+
body_indent
780+
};
781+
782+
// First try to format as items, then as statements.
783+
let new_body = match ::format_snippet(&body_str, &config) {
784+
Some(new_body) => new_body,
785+
None => match ::format_code_block(&body_str, &config) {
786+
Some(new_body) => new_body,
787+
None => return None,
788+
},
789+
};
790+
791+
// Indent the body since it is in a block.
792+
let indent_str = body_indent.to_string(&config);
793+
let mut new_body = new_body
794+
.trim_right()
795+
.lines()
796+
.fold(String::new(), |mut s, l| {
797+
if !l.is_empty() {
798+
s += &indent_str;
799+
}
800+
s + l + "\n"
801+
});
802+
803+
// Undo our replacement of macro variables.
804+
// FIXME: this could be *much* more efficient.
805+
for (old, new) in &substs {
806+
if old_body.find(new).is_some() {
807+
debug!(
808+
"rewrite_macro_def: bailing matching variable: `{}`",
809+
new
810+
);
811+
return None;
812+
}
813+
new_body = new_body.replace(new, old);
814+
}
815+
816+
if has_block_body {
817+
result += new_body.trim();
818+
} else if !new_body.is_empty() {
819+
result += "\n";
820+
result += &new_body;
821+
result += &shape.indent.to_string(&config);
822+
}
823+
824+
result += "}";
825+
826+
Some(result)
827+
}
828+
}
829+
830830
#[cfg(test)]
831831
mod test {
832832
use super::*;

0 commit comments

Comments
 (0)