[meta] Ignore empty lines to compute indent when parsing multiple lines;

This commit is contained in:
Benjamin Bouvier
2018-11-21 15:36:53 +01:00
committed by Dan Gohman
parent 12df943409
commit 4c8f1e7a5a

View File

@@ -3,6 +3,7 @@
//! The `srcgen` module contains generic helper routines and classes for //! The `srcgen` module contains generic helper routines and classes for
//! generating source code. //! generating source code.
use std::cmp;
use std::collections::{BTreeMap, BTreeSet}; use std::collections::{BTreeMap, BTreeSet};
use std::fs; use std::fs;
use std::io::Write; use std::io::Write;
@@ -107,8 +108,13 @@ impl Formatter {
pub fn doc_comment(&mut self, contents: &str) { pub fn doc_comment(&mut self, contents: &str) {
parse_multiline(contents) parse_multiline(contents)
.iter() .iter()
.map(|l| format!("/// {}", l)) .map(|l| {
.for_each(|s| self.line(s.as_str())); if l.len() == 0 {
"///".into()
} else {
format!("/// {}", l)
}
}).for_each(|s| self.line(s.as_str()));
} }
/// Add a match expression. /// Add a match expression.
@@ -156,10 +162,11 @@ fn parse_multiline(s: &str) -> Vec<String> {
let expanded_tab = format!("{:-1$}", " ", SHIFTWIDTH); let expanded_tab = format!("{:-1$}", " ", SHIFTWIDTH);
let lines: Vec<String> = s.lines().map(|l| l.replace("\t", &expanded_tab)).collect(); let lines: Vec<String> = s.lines().map(|l| l.replace("\t", &expanded_tab)).collect();
// Determine minimum indentation, ignoring the first line. // Determine minimum indentation, ignoring the first line and empty lines.
let indent = lines let indent = lines
.iter() .iter()
.skip(1) .skip(1)
.filter(|l| !l.trim().is_empty())
.map(|l| l.len() - l.trim_left().len()) .map(|l| l.len() - l.trim_left().len())
.min(); .min();
@@ -174,8 +181,9 @@ fn parse_multiline(s: &str) -> Vec<String> {
// Remove trailing whitespace from other lines. // Remove trailing whitespace from other lines.
let mut other_lines = if let Some(indent) = indent { let mut other_lines = if let Some(indent) = indent {
// Note that empty lines may have fewer than `indent` chars.
lines_iter lines_iter
.map(|l| &l[indent..]) .map(|l| &l[cmp::min(indent, l.len())..])
.map(|l| l.trim_right()) .map(|l| l.trim_right())
.map(|l| l.to_string()) .map(|l| l.to_string())
.collect::<Vec<_>>() .collect::<Vec<_>>()
@@ -349,4 +357,24 @@ match x {
let expected_lines = vec!["/// documentation\n", "/// is\n", "/// good\n"]; let expected_lines = vec!["/// documentation\n", "/// is\n", "/// good\n"];
assert_eq!(fmt.lines, expected_lines); assert_eq!(fmt.lines, expected_lines);
} }
#[test]
fn fmt_can_add_doc_comments_with_empty_lines() {
let mut fmt = Formatter::new();
fmt.doc_comment(
r#"documentation
can be really good.
If you stick to writing it.
"#,
);
let expected_lines = from_raw_string(
r#"
/// documentation
/// can be really good.
///
/// If you stick to writing it."#,
);
assert_eq!(fmt.lines, expected_lines);
}
} }