Merge pull request #2524 from topecongiro/issue-2523

Do not unindent code block in comments with unformattable macro
This commit is contained in:
Nick Cameron 2018-03-12 11:21:09 +13:00 committed by GitHub
commit af5d3cc87b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 68 additions and 8 deletions

View File

@ -2652,6 +2652,7 @@ fn can_be_overflowed(&self, context: &RewriteContext, len: usize) -> bool {
MacroArg::Expr(ref expr) => can_be_overflowed_expr(context, expr, len),
MacroArg::Ty(ref ty) => can_be_overflowed_type(context, ty, len),
MacroArg::Pat(..) => false,
MacroArg::Item(..) => len == 1,
}
}
}

View File

@ -597,14 +597,23 @@ pub fn format_snippet(snippet: &str, config: &Config) -> Option<String> {
}
}
const FN_MAIN_PREFIX: &str = "fn main() {\n";
fn enclose_in_main_block(s: &str, config: &Config) -> String {
let indent = Indent::from_width(config, config.tab_spaces());
FN_MAIN_PREFIX.to_owned() + &indent.to_string(config)
+ &s.lines()
.collect::<Vec<_>>()
.join(&indent.to_string_with_newline(config)) + "\n}"
}
/// Format the given code block. Mainly targeted for code block in comment.
/// The code block may be incomplete (i.e. parser may be unable to parse it).
/// To avoid panic in parser, we wrap the code block with a dummy function.
/// The returned code block does *not* end with newline.
pub fn format_code_block(code_snippet: &str, config: &Config) -> Option<String> {
// Wrap the given code block with `fn main()` if it does not have one.
let fn_main_prefix = "fn main() {\n";
let snippet = fn_main_prefix.to_owned() + code_snippet + "\n}";
let snippet = enclose_in_main_block(code_snippet, config);
let mut result = String::with_capacity(snippet.len());
let mut is_first = true;
@ -613,7 +622,7 @@ pub fn format_code_block(code_snippet: &str, config: &Config) -> Option<String>
let formatted = format_snippet(&snippet, config)?;
// 2 = "}\n"
let block_len = formatted.len().checked_sub(2).unwrap_or(0);
for line in formatted[fn_main_prefix.len()..block_len].lines() {
for line in formatted[FN_MAIN_PREFIX.len()..block_len].lines() {
if !is_first {
result.push('\n');
} else {

View File

@ -22,7 +22,7 @@
use std::collections::HashMap;
use config::lists::*;
use syntax::ast;
use syntax::{ast, ptr};
use syntax::codemap::{BytePos, Span};
use syntax::parse::new_parser_from_tts;
use syntax::parse::parser::Parser;
@ -39,6 +39,7 @@
use overflow;
use rewrite::{Rewrite, RewriteContext};
use shape::{Indent, Shape};
use spanned::Spanned;
use utils::{format_visibility, mk_sp, wrap_str};
const FORCED_BRACKET_MACROS: &[&str] = &["vec!"];
@ -71,9 +72,21 @@ fn opener(&self) -> &'static str {
#[derive(Debug)]
pub enum MacroArg {
Expr(ast::Expr),
Ty(ast::Ty),
Pat(ast::Pat),
Expr(ptr::P<ast::Expr>),
Ty(ptr::P<ast::Ty>),
Pat(ptr::P<ast::Pat>),
// `parse_item` returns `Option<ptr::P<ast::Item>>`.
Item(Option<ptr::P<ast::Item>>),
}
impl Rewrite for ast::Item {
fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
let mut visitor = ::visitor::FmtVisitor::from_context(context);
visitor.block_indent = shape.indent;
visitor.last_pos = self.span().lo();
visitor.visit_item(self);
Some(visitor.buffer)
}
}
impl Rewrite for MacroArg {
@ -82,6 +95,7 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
MacroArg::Expr(ref expr) => expr.rewrite(context, shape),
MacroArg::Ty(ref ty) => ty.rewrite(context, shape),
MacroArg::Pat(ref pat) => pat.rewrite(context, shape),
MacroArg::Item(ref item) => item.as_ref().and_then(|item| item.rewrite(context, shape)),
}
}
}
@ -97,7 +111,7 @@ macro_rules! parse_macro_arg {
} else {
// Parsing succeeded.
*parser = cloned_parser;
return Some(MacroArg::$macro_arg((*x).clone()));
return Some(MacroArg::$macro_arg(x.clone()));
}
}
Err(mut e) => {
@ -111,6 +125,7 @@ macro_rules! parse_macro_arg {
parse_macro_arg!(Expr, parse_expr);
parse_macro_arg!(Ty, parse_ty);
parse_macro_arg!(Pat, parse_pat);
parse_macro_arg!(Item, parse_item);
None
}

View File

@ -187,6 +187,7 @@ fn span(&self) -> Span {
MacroArg::Expr(ref expr) => expr.span(),
MacroArg::Ty(ref ty) => ty.span(),
MacroArg::Pat(ref pat) => pat.span(),
MacroArg::Item(ref item) => item.as_ref().unwrap().span(),
}
}
}

View File

@ -0,0 +1,17 @@
// rustfmt-normalize_comments: true
// Do not unindent macro calls in comment with unformattable syntax.
//! ```rust
//! let x = 3 ;
//! some_macro!(pub fn fn foo() (
//! println!("Don't unindent me!");
//! ));
//! ```
// Format items that appear as arguments of macro call.
//! ```rust
//! let x = 3 ;
//! some_macro!(pub fn foo() {
//! println!("Don't unindent me!");
//! });
//! ```

View File

@ -0,0 +1,17 @@
// rustfmt-normalize_comments: true
// Do not unindent macro calls in comment with unformattable syntax.
//! ```rust
//! let x = 3;
//! some_macro!(pub fn fn foo() (
//! println!("Don't unindent me!");
//! ));
//! ```
// Format items that appear as arguments of macro call.
//! ```rust
//! let x = 3;
//! some_macro!(pub fn foo() {
//! println!("Don't unindent me!");
//! });
//! ```