Implement 'vec![expr; expr]'

This commit is contained in:
topecongiro 2017-05-19 19:25:53 +09:00
parent 068b8b3b5c
commit d16a0a399e
4 changed files with 75 additions and 20 deletions

View File

@ -29,7 +29,7 @@ use syntax::util::ThinVec;
use Shape;
use codemap::SpanUtils;
use rewrite::{Rewrite, RewriteContext};
use expr::{rewrite_call, rewrite_array};
use expr::{rewrite_call, rewrite_array, rewrite_pair};
use comment::{FindUncommented, contains_comment};
const FORCED_BRACKET_MACROS: &'static [&'static str] = &["vec!"];
@ -105,6 +105,7 @@ pub fn rewrite_macro(mac: &ast::Mac,
let mut parser = tts_to_parser(context.parse_session, mac.node.tts.clone());
let mut expr_vec = Vec::new();
let mut vec_with_semi = false;
if MacroStyle::Braces != style {
loop {
@ -128,6 +129,29 @@ pub fn rewrite_macro(mac: &ast::Mac,
match parser.token {
Token::Eof => break,
Token::Comma => (),
Token::Semi => {
// Try to parse `vec![expr; expr]`
if FORCED_BRACKET_MACROS.contains(&&macro_name[..]) {
parser.bump();
if parser.token != Token::Eof {
match parser.parse_expr() {
Ok(expr) => {
if context.parse_session.span_diagnostic.has_errors() {
return None;
}
expr_vec.push(expr);
parser.bump();
if parser.token == Token::Eof && expr_vec.len() == 2 {
vec_with_semi = true;
break;
}
}
Err(mut e) => e.cancel(),
}
}
}
return None;
}
_ => return None,
}
@ -156,19 +180,36 @@ pub fn rewrite_macro(mac: &ast::Mac,
})
}
MacroStyle::Brackets => {
let mac_shape = try_opt!(shape.shrink_left(macro_name.len()));
// Handle special case: `vec![expr; expr]`
if vec_with_semi {
let (lbr, rbr) = if context.config.spaces_within_square_brackets {
("[ ", " ]")
} else {
("[", "]")
};
rewrite_pair(&*expr_vec[0],
&*expr_vec[1],
lbr,
"; ",
rbr,
context,
mac_shape)
.map(|s| format!("{}{}", macro_name, s))
} else {
// Format macro invocation as array literal.
let extra_offset = macro_name.len();
let shape = try_opt!(shape.shrink_left(extra_offset));
let rewrite =
try_opt!(rewrite_array(expr_vec.iter().map(|x| &**x),
mk_sp(context.codemap.span_after(mac.span,
original_style.opener()),
original_style
.opener()),
mac.span.hi - BytePos(1)),
context,
shape));
mac_shape));
Some(format!("{}{}", macro_name, rewrite))
}
}
MacroStyle::Braces => {
// Skip macro invocations with braces, for now.
None

View File

@ -34,6 +34,13 @@ fn main() {
a,
];
vec![a; b];
vec!(a; b);
vec!{a; b};
vec![a, b; c];
vec![a; b, c];
unknown_bracket_macro__comma_should_not_be_stripped![
a,
];

View File

@ -38,6 +38,13 @@ fn main() {
// Trailing spaces after a comma
vec![a];
vec![a; b];
vec![a; b];
vec![a; b];
vec![a, b; c];
vec![a; b, c];
unknown_bracket_macro__comma_should_not_be_stripped![
a,
];

View File

@ -158,19 +158,19 @@ fn issue355() {
match mac {
a => println!("a", b),
b => vec![1, 2],
c => vec!(3; 4),
c => vec![3; 4],
d => println!("a", b),
e => vec![1, 2],
f => vec!(3; 4),
f => vec![3; 4],
h => println!("a", b), // h comment
i => vec![1, 2], // i comment
j => vec!(3; 4), // j comment
j => vec![3; 4], // j comment
// k comment
k => println!("a", b),
// l comment
l => vec![1, 2],
// m comment
m => vec!(3; 4),
m => vec![3; 4],
// Rewrite splits macro
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn => {
println!("a", b)
@ -182,7 +182,7 @@ fn issue355() {
// Macro support fails to recognise this macro as splitable
// We push the whole expr to a new line, TODO split this macro as well
pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp => {
vec!(3; 4)
vec![3; 4]
}
// q, r and s: Rewrite splits match arm
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq => {
@ -192,19 +192,19 @@ fn issue355() {
vec![1, 2]
}
ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss => {
vec!(3; 4)
vec![3; 4]
}
// Funky bracketing styles
t => println!{"a", b},
u => vec![1, 2],
v => vec!{3; 4},
v => vec![3; 4],
w => println!["a", b],
x => vec![1, 2],
y => vec![3; 4],
// Brackets with comments
tc => println!{"a", b}, // comment
uc => vec![1, 2], // comment
vc => vec!{3; 4}, // comment
vc => vec![3; 4], // comment
wc => println!["a", b], // comment
xc => vec![1, 2], // comment
yc => vec![3; 4], // comment