1
Fork 0

Rework beautify_doc_string so that it returns a Symbol instead of a String

This commit is contained in:
Guillaume Gomez 2020-12-20 23:37:24 +01:00
parent 75e1acb63a
commit 64afdedfb8
4 changed files with 39 additions and 37 deletions

View file

@ -25,9 +25,8 @@ pub struct Comment {
/// Makes a doc string more presentable to users. /// Makes a doc string more presentable to users.
/// Used by rustdoc and perhaps other tools, but not by rustc. /// Used by rustdoc and perhaps other tools, but not by rustc.
pub fn beautify_doc_string(data: Symbol) -> String { pub fn beautify_doc_string(data: Symbol) -> Symbol {
/// remove whitespace-only lines from the start/end of lines fn get_vertical_trim(lines: &[&str]) -> Option<(usize, usize)> {
fn vertical_trim(lines: Vec<String>) -> Vec<String> {
let mut i = 0; let mut i = 0;
let mut j = lines.len(); let mut j = lines.len();
// first line of all-stars should be omitted // first line of all-stars should be omitted
@ -47,55 +46,58 @@ pub fn beautify_doc_string(data: Symbol) -> String {
j -= 1; j -= 1;
} }
lines[i..j].to_vec() if i != 0 || j != lines.len() { Some((i, j)) } else { None }
} }
/// remove a "[ \t]*\*" block from each line, if possible fn get_horizontal_trim(lines: &[&str]) -> Option<usize> {
fn horizontal_trim(lines: Vec<String>) -> Vec<String> {
let mut i = usize::MAX; let mut i = usize::MAX;
let mut can_trim = true;
let mut first = true; let mut first = true;
for line in &lines { for line in lines {
for (j, c) in line.chars().enumerate() { for (j, c) in line.chars().enumerate() {
if j > i || !"* \t".contains(c) { if j > i || !"* \t".contains(c) {
can_trim = false; return None;
break;
} }
if c == '*' { if c == '*' {
if first { if first {
i = j; i = j;
first = false; first = false;
} else if i != j { } else if i != j {
can_trim = false; return None;
} }
break; break;
} }
} }
if i >= line.len() { if i >= line.len() {
can_trim = false; return None;
}
if !can_trim {
break;
} }
} }
Some(i)
}
if can_trim { let data_s = data.as_str();
lines.iter().map(|line| (&line[i + 1..line.len()]).to_string()).collect() if data_s.contains('\n') {
let mut lines = data_s.lines().collect::<Vec<&str>>();
let mut changes = false;
let lines = if let Some((i, j)) = get_vertical_trim(&lines) {
changes = true;
// remove whitespace-only lines from the start/end of lines
&mut lines[i..j]
} else { } else {
lines &mut lines
};
if let Some(horizontal) = get_horizontal_trim(&lines) {
changes = true;
// remove a "[ \t]*\*" block from each line, if possible
for line in lines.iter_mut() {
*line = &line[horizontal + 1..];
}
}
if changes {
return Symbol::intern(&lines.join("\n"));
} }
} }
data
let data = data.as_str();
if data.contains('\n') {
let lines = data.lines().map(|s| s.to_string()).collect::<Vec<String>>();
let lines = vertical_trim(lines);
let lines = horizontal_trim(lines);
lines.join("\n")
} else {
data.to_string()
}
} }
/// Returns `None` if the first `col` chars of `s` contain a non-whitespace char. /// Returns `None` if the first `col` chars of `s` contain a non-whitespace char.

View file

@ -6,7 +6,7 @@ fn test_block_doc_comment_1() {
with_default_session_globals(|| { with_default_session_globals(|| {
let comment = "\n * Test \n ** Test\n * Test\n"; let comment = "\n * Test \n ** Test\n * Test\n";
let stripped = beautify_doc_string(Symbol::intern(comment)); let stripped = beautify_doc_string(Symbol::intern(comment));
assert_eq!(stripped, " Test \n* Test\n Test"); assert_eq!(stripped.as_str(), " Test \n* Test\n Test");
}) })
} }
@ -15,7 +15,7 @@ fn test_block_doc_comment_2() {
with_default_session_globals(|| { with_default_session_globals(|| {
let comment = "\n * Test\n * Test\n"; let comment = "\n * Test\n * Test\n";
let stripped = beautify_doc_string(Symbol::intern(comment)); let stripped = beautify_doc_string(Symbol::intern(comment));
assert_eq!(stripped, " Test\n Test"); assert_eq!(stripped.as_str(), " Test\n Test");
}) })
} }
@ -24,7 +24,7 @@ fn test_block_doc_comment_3() {
with_default_session_globals(|| { with_default_session_globals(|| {
let comment = "\n let a: *i32;\n *a = 5;\n"; let comment = "\n let a: *i32;\n *a = 5;\n";
let stripped = beautify_doc_string(Symbol::intern(comment)); let stripped = beautify_doc_string(Symbol::intern(comment));
assert_eq!(stripped, " let a: *i32;\n *a = 5;"); assert_eq!(stripped.as_str(), " let a: *i32;\n *a = 5;");
}) })
} }
@ -32,12 +32,12 @@ fn test_block_doc_comment_3() {
fn test_line_doc_comment() { fn test_line_doc_comment() {
with_default_session_globals(|| { with_default_session_globals(|| {
let stripped = beautify_doc_string(Symbol::intern(" test")); let stripped = beautify_doc_string(Symbol::intern(" test"));
assert_eq!(stripped, " test"); assert_eq!(stripped.as_str(), " test");
let stripped = beautify_doc_string(Symbol::intern("! test")); let stripped = beautify_doc_string(Symbol::intern("! test"));
assert_eq!(stripped, "! test"); assert_eq!(stripped.as_str(), "! test");
let stripped = beautify_doc_string(Symbol::intern("test")); let stripped = beautify_doc_string(Symbol::intern("test"));
assert_eq!(stripped, "test"); assert_eq!(stripped.as_str(), "test");
let stripped = beautify_doc_string(Symbol::intern("!test")); let stripped = beautify_doc_string(Symbol::intern("!test"));
assert_eq!(stripped, "!test"); assert_eq!(stripped.as_str(), "!test");
}) })
} }

View file

@ -825,7 +825,7 @@ impl<'tcx> SaveContext<'tcx> {
for attr in attrs { for attr in attrs {
if let Some(val) = attr.doc_str() { if let Some(val) = attr.doc_str() {
// FIXME: Should save-analysis beautify doc strings itself or leave it to users? // FIXME: Should save-analysis beautify doc strings itself or leave it to users?
result.push_str(&beautify_doc_string(val)); result.push_str(&beautify_doc_string(val).as_str());
result.push('\n'); result.push('\n');
} else if self.tcx.sess.check_name(attr, sym::doc) { } else if self.tcx.sess.check_name(attr, sym::doc) {
if let Some(meta_list) = attr.meta_item_list() { if let Some(meta_list) = attr.meta_item_list() {

View file

@ -617,7 +617,7 @@ impl Attributes {
let clean_attr = |(attr, parent_module): (&ast::Attribute, _)| { let clean_attr = |(attr, parent_module): (&ast::Attribute, _)| {
if let Some(value) = attr.doc_str() { if let Some(value) = attr.doc_str() {
trace!("got doc_str={:?}", value); trace!("got doc_str={:?}", value);
let value = beautify_doc_string(value); let value = beautify_doc_string(value).to_string();
let kind = if attr.is_doc_comment() { let kind = if attr.is_doc_comment() {
DocFragmentKind::SugaredDoc DocFragmentKind::SugaredDoc
} else { } else {