From 4c8f1e7a5a4d02d50dc6a474d12d2a052efa0f07 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Wed, 21 Nov 2018 15:36:53 +0100 Subject: [PATCH] [meta] Ignore empty lines to compute indent when parsing multiple lines; --- lib/codegen/meta/src/srcgen.rs | 36 ++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/lib/codegen/meta/src/srcgen.rs b/lib/codegen/meta/src/srcgen.rs index 70bcfe6ef7..a7941e9bf8 100644 --- a/lib/codegen/meta/src/srcgen.rs +++ b/lib/codegen/meta/src/srcgen.rs @@ -3,6 +3,7 @@ //! The `srcgen` module contains generic helper routines and classes for //! generating source code. +use std::cmp; use std::collections::{BTreeMap, BTreeSet}; use std::fs; use std::io::Write; @@ -107,8 +108,13 @@ impl Formatter { pub fn doc_comment(&mut self, contents: &str) { parse_multiline(contents) .iter() - .map(|l| format!("/// {}", l)) - .for_each(|s| self.line(s.as_str())); + .map(|l| { + if l.len() == 0 { + "///".into() + } else { + format!("/// {}", l) + } + }).for_each(|s| self.line(s.as_str())); } /// Add a match expression. @@ -156,10 +162,11 @@ fn parse_multiline(s: &str) -> Vec { let expanded_tab = format!("{:-1$}", " ", SHIFTWIDTH); let lines: Vec = 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 .iter() .skip(1) + .filter(|l| !l.trim().is_empty()) .map(|l| l.len() - l.trim_left().len()) .min(); @@ -174,8 +181,9 @@ fn parse_multiline(s: &str) -> Vec { // Remove trailing whitespace from other lines. let mut other_lines = if let Some(indent) = indent { + // Note that empty lines may have fewer than `indent` chars. lines_iter - .map(|l| &l[indent..]) + .map(|l| &l[cmp::min(indent, l.len())..]) .map(|l| l.trim_right()) .map(|l| l.to_string()) .collect::>() @@ -349,4 +357,24 @@ match x { let expected_lines = vec!["/// documentation\n", "/// is\n", "/// good\n"]; 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); + } }