Merge pull request #2441 from topecongiro/issue-2438

Return `None` when format_code_block may have failed
This commit is contained in:
Nick Cameron 2018-02-15 14:18:21 +13:00 committed by GitHub
commit 69d7eb0986
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 25 deletions

View File

@ -564,35 +564,45 @@ 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 mut result = String::with_capacity(snippet.len());
let mut is_first = true;
// Trim "fn main() {" on the first line and "}" on the last line,
// then unindent the whole code block.
format_snippet(&snippet, config).map(|s| {
// 2 = "}\n"
s[fn_main_prefix.len()..s.len().checked_sub(2).unwrap_or(0)]
.lines()
.map(|line| {
if line.len() > config.tab_spaces() {
// Make sure that the line has leading whitespaces.
let indent_str =
Indent::from_width(config, config.tab_spaces()).to_string(config);
if line.starts_with(indent_str.as_ref()) {
let offset = if config.hard_tabs() {
1
} else {
config.tab_spaces()
};
&line[offset..]
} else {
line
}
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() {
if !is_first {
result.push('\n');
} else {
is_first = false;
}
let trimmed_line = if line.len() > config.max_width() {
// If there are lines that are larger than max width, we cannot tell
// whether we have succeeded but have some comments or strings that
// are too long, or we have failed to format code block. We will be
// conservative and just return `None` in this case.
return None;
} else if line.len() > config.tab_spaces() {
// Make sure that the line has leading whitespaces.
let indent_str = Indent::from_width(config, config.tab_spaces()).to_string(config);
if line.starts_with(indent_str.as_ref()) {
let offset = if config.hard_tabs() {
1
} else {
line
}
})
.collect::<Vec<_>>()
.join("\n")
})
config.tab_spaces()
};
&line[offset..]
} else {
line
}
} else {
line
};
result.push_str(trimmed_line);
}
Some(result)
}
pub fn format_input<T: Write>(
@ -781,6 +791,12 @@ fn test_format_snippet() {
assert!(test_format_inner(format_snippet, snippet, expected));
}
#[test]
fn test_format_code_block_fail() {
let code_block = "this_line_is_100_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(x, y, z);";
assert!(format_code_block(code_block, &Config::default()).is_none());
}
#[test]
fn test_format_code_block() {
// simple code block

View File

@ -50,6 +50,15 @@ macro_rules! m {
}
}
// #2438
macro_rules! m {
() => {
this_line_is_99_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(
); // this line is drifting
};
}
// #2439
macro_rules! m {
(

View File

@ -42,6 +42,14 @@ mod macro_item {
}
}
// #2438
macro_rules! m {
() => {
this_line_is_99_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(
); // this line is drifting
};
}
// #2439
macro_rules! m {
(