use std::collections::HashMap;
use config::lists::*;
-use syntax::codemap::{BytePos, Span};
use syntax::parse::new_parser_from_tts;
use syntax::parse::parser::Parser;
use syntax::parse::token::{BinOpToken, DelimToken, Token};
use syntax::print::pprust;
+use syntax::source_map::{BytePos, Span};
use syntax::symbol;
use syntax::tokenstream::{Cursor, ThinTokenStream, TokenStream, TokenTree};
-use syntax::util::ThinVec;
+use syntax::ThinVec;
use syntax::{ast, ptr};
-use codemap::SpanUtils;
use comment::{
contains_comment, remove_trailing_white_spaces, CharClasses, FindUncommented, FullCodeCharKind,
LineClasses,
use overflow;
use rewrite::{Rewrite, RewriteContext};
use shape::{Indent, Shape};
+use source_map::SpanUtils;
use spanned::Spanned;
use utils::{format_visibility, mk_sp, rewrite_ident, wrap_str};
Some(context.snippet(span).to_owned())
}
+struct InsideMacroGuard<'a> {
+ context: &'a RewriteContext<'a>,
+ is_nested: bool,
+}
+
+impl<'a> InsideMacroGuard<'a> {
+ fn inside_macro_context(context: &'a RewriteContext) -> InsideMacroGuard<'a> {
+ let is_nested = context.inside_macro.replace(true);
+ InsideMacroGuard { context, is_nested }
+ }
+}
+
+impl<'a> Drop for InsideMacroGuard<'a> {
+ fn drop(&mut self) {
+ self.context.inside_macro.replace(self.is_nested);
+ }
+}
+
pub fn rewrite_macro(
mac: &ast::Mac,
extra_ident: Option<ast::Ident>,
shape: Shape,
position: MacroPosition,
) -> Option<String> {
- context.inside_macro.replace(true);
- let result = rewrite_macro_inner(mac, extra_ident, context, shape, position);
+ let guard = InsideMacroGuard::inside_macro_context(context);
+ let result = rewrite_macro_inner(mac, extra_ident, context, shape, position, guard.is_nested);
if result.is_none() {
context.macro_rewrite_failure.replace(true);
}
- context.inside_macro.replace(false);
result
}
context: &RewriteContext,
shape: Shape,
position: MacroPosition,
+ is_nested_macro: bool,
) -> Option<String> {
if context.config.use_try_shorthand() {
if let Some(expr) = convert_try_mac(mac, context) {
let macro_name = rewrite_macro_name(context, &mac.node.path, extra_ident);
- let style = if FORCED_BRACKET_MACROS.contains(&¯o_name[..]) {
+ let style = if FORCED_BRACKET_MACROS.contains(&¯o_name[..]) && !is_nested_macro {
DelimToken::Bracket
} else {
original_style
} else {
Some(SeparatorTactic::Never)
};
- if FORCED_BRACKET_MACROS.contains(macro_name) {
+ if FORCED_BRACKET_MACROS.contains(macro_name) && !is_nested_macro {
context.inside_macro.replace(false);
if context.use_block_indent() {
force_trailing_comma = Some(SeparatorTactic::Vertical);
false,
).collect::<Vec<_>>();
- let fmt = ListFormatting {
- tactic: DefinitiveListTactic::Vertical,
- separator: if def.legacy { ";" } else { "" },
- trailing_separator: SeparatorTactic::Always,
- separator_place: SeparatorPlace::Back,
- shape: arm_shape,
- ends_with_newline: true,
- preserve_newline: true,
- nested: false,
- config: context.config,
- };
+ let fmt = ListFormatting::new(arm_shape, context.config)
+ .separator(if def.legacy { ";" } else { "" })
+ .trailing_separator(SeparatorTactic::Always)
+ .preserve_newline(true);
if multi_branch_style {
result += " {";
};
trimmed_lines.push((trimmed, line, prefix_space_width));
prefix_space_width
- })
- .min()?;
+ }).min()?;
Some(
first_line + "\n" + &trimmed_lines
}
None => String::new(),
},
- )
- .collect::<Vec<_>>()
+ ).collect::<Vec<_>>()
.join("\n"),
)
}
let body_indent = if has_block_body {
shape.indent
} else {
- // We'll hack the indent below, take this into account when formatting,
- let body_indent = shape.indent.block_indent(&config);
- let new_width = config.max_width() - body_indent.width();
- config.set().max_width(new_width);
- body_indent
+ shape.indent.block_indent(&config)
};
+ let new_width = config.max_width() - body_indent.width();
+ config.set().max_width(new_width);
// First try to format as items, then as statements.
let new_body = match ::format_snippet(&body_str, &config) {
Some(new_body) => new_body,
- None => match ::format_code_block(&body_str, &config) {
- Some(new_body) => new_body,
- None => return None,
- },
+ None => {
+ let new_width = new_width + config.tab_spaces();
+ config.set().max_width(new_width);
+ match ::format_code_block(&body_str, &config) {
+ Some(new_body) => new_body,
+ None => return None,
+ }
+ }
};
let new_body = wrap_str(new_body, config.max_width(), shape)?;
}
(s + l + "\n", !kind.is_string() || l.ends_with('\\'))
},
- )
- .0;
+ ).0;
// Undo our replacement of macro variables.
// FIXME: this could be *much* more efficient.