From a18a40cbc141ad1437796a53b1d1a893c5cb5dff Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Mon, 21 Aug 2017 23:19:01 +0900 Subject: [PATCH] Add indent to macro we could not format --- src/macros.rs | 65 +++++++++++++++++++++++++++++++++++++++--- tests/source/macros.rs | 9 ++++++ tests/target/macros.rs | 12 ++++++++ 3 files changed, 82 insertions(+), 4 deletions(-) diff --git a/src/macros.rs b/src/macros.rs index ae2a16510b8..b1f740e6a87 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -19,6 +19,8 @@ // List-like invocations with parentheses will be formatted as function calls, // and those with brackets will be formatted as array literals. +use std::iter::repeat; + use syntax::ast; use syntax::codemap::BytePos; use syntax::parse::new_parser_from_tts; @@ -27,7 +29,7 @@ use syntax::tokenstream::TokenStream; use syntax::util::ThinVec; -use Shape; +use {Indent, Shape}; use codemap::SpanUtils; use comment::{contains_comment, FindUncommented}; use expr::{rewrite_array, rewrite_call_inner}; @@ -116,14 +118,14 @@ pub fn rewrite_macro( Ok(expr) => { // Recovered errors. if context.parse_session.span_diagnostic.has_errors() { - return Some(context.snippet(mac.span)); + return indent_macro_snippet(&context.snippet(mac.span), shape.indent); } expr } Err(mut e) => { e.cancel(); - return Some(context.snippet(mac.span)); + return indent_macro_snippet(&context.snippet(mac.span), shape.indent); } }; @@ -242,7 +244,7 @@ pub fn rewrite_macro( } MacroStyle::Braces => { // Skip macro invocations with braces, for now. - None + indent_macro_snippet(&context.snippet(mac.span), shape.indent) } } } @@ -280,3 +282,58 @@ fn macro_style(mac: &ast::Mac, context: &RewriteContext) -> MacroStyle { MacroStyle::Braces } } + +/// Indent each line according to the specified `indent`. +/// e.g. +/// ```rust +/// foo!{ +/// x, +/// y, +/// foo( +/// a, +/// b, +/// c, +/// ), +/// } +/// ``` +/// will become +/// ```rust +/// foo!{ +/// x, +/// y, +/// foo( +/// a, +/// b, +/// c, +// ), +/// } +/// ``` +fn indent_macro_snippet(macro_str: &str, indent: Indent) -> Option { + let min_prefix_space_width = + try_opt!(macro_str.lines().skip(1).map(get_prefix_space_width).min()); + + let mut lines = macro_str.lines(); + let first_line = try_opt!(lines.next()); + + Some( + String::from(first_line) + "\n" + + &lines + .map(|line| { + let new_indent_width = indent.width() + + get_prefix_space_width(line) + .checked_sub(min_prefix_space_width) + .unwrap_or(0); + repeat_white_space(new_indent_width) + line.trim() + }) + .collect::>() + .join("\n"), + ) +} + +fn get_prefix_space_width(s: &str) -> usize { + s.chars().position(|c| c != ' ').unwrap_or(0) +} + +fn repeat_white_space(ws_count: usize) -> String { + repeat(" ").take(ws_count).collect::() +} diff --git a/tests/source/macros.rs b/tests/source/macros.rs index e3d7229a0e1..d8e6efe9199 100644 --- a/tests/source/macros.rs +++ b/tests/source/macros.rs @@ -112,6 +112,7 @@ macro_rules! foo { foo!(#[doc = "bar"] baz); } + fn issue1739() { sql_function!(add_rss_item, add_rss_item_t, @@ -125,6 +126,14 @@ fn issue1739() { .par_map_inplace(|el| *el = 0.); } +fn issue_1885() { + let threads = people.into_iter().map(|name| { + chan_select! { + rx.recv() => {} + } + }).collect::>(); +} + // Put the following tests with macro invocations whose arguments cannot be parsed as expressioins // at the end of the file for now. diff --git a/tests/target/macros.rs b/tests/target/macros.rs index f80f6843fe2..21c0b983ff9 100644 --- a/tests/target/macros.rs +++ b/tests/target/macros.rs @@ -146,6 +146,7 @@ macro_rules! foo { baz ); } + fn issue1739() { sql_function!( add_rss_item, @@ -166,6 +167,17 @@ fn issue1739() { ]).par_map_inplace(|el| *el = 0.); } +fn issue_1885() { + let threads = people + .into_iter() + .map(|name| { + chan_select! { + rx.recv() => {} + } + }) + .collect::>(); +} + // Put the following tests with macro invocations whose arguments cannot be parsed as expressioins // at the end of the file for now.