diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2022-01-20 23:37:32 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-01-20 23:37:32 +0100 |
| commit | aa7f4520a1d5fc634f80a6ebe532fe2bdfa52501 (patch) | |
| tree | 3848647bb2e7c33f7b9684a2ad9ebf5b58801f8e | |
| parent | 530c884372cbee0ab81df404c90b0bc3b551a474 (diff) | |
| parent | 06b00ad19972c18150fe25a9b3716ffdf5300a83 (diff) | |
| download | rust-aa7f4520a1d5fc634f80a6ebe532fe2bdfa52501.tar.gz rust-aa7f4520a1d5fc634f80a6ebe532fe2bdfa52501.zip | |
Rollup merge of #93038 - GuillaumeGomez:block-doc-comments, r=notriddle
Fix star handling in block doc comments Fixes #92872. Some extra explanation about this PR and why https://github.com/rust-lang/rust/pull/92357 created this regression: when we merge doc comment kinds for example in: ```rust /// he /** * hello */ #[doc = "boom"] ``` We don't want to remove the empty lines between them. However, to correctly compute the "horizontal trim", we still need it, so instead, I put back a part of the "vertical trim" directly in the "horizontal trim" computation so it doesn't impact the output buffer but allows us to correctly handle the stars. r? ``@camelid``
| -rw-r--r-- | compiler/rustc_ast/src/attr/mod.rs | 11 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/util/comments.rs | 29 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/util/comments/tests.rs | 14 | ||||
| -rw-r--r-- | compiler/rustc_save_analysis/src/lib.rs | 4 | ||||
| -rw-r--r-- | src/librustdoc/clean/types.rs | 4 | ||||
| -rw-r--r-- | src/test/rustdoc/strip-block-doc-comments-stars.docblock.html | 2 | ||||
| -rw-r--r-- | src/test/rustdoc/strip-block-doc-comments-stars.rs | 11 |
7 files changed, 60 insertions, 15 deletions
diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index d66774040f7..6a0ace04d4b 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -242,6 +242,17 @@ impl Attribute { } } + pub fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> { + match self.kind { + AttrKind::DocComment(kind, data) => Some((data, kind)), + AttrKind::Normal(ref item, _) if item.path == sym::doc => item + .meta_kind() + .and_then(|kind| kind.value_str()) + .map(|data| (data, CommentKind::Line)), + _ => None, + } + } + pub fn doc_str(&self) -> Option<Symbol> { match self.kind { AttrKind::DocComment(.., data) => Some(data), diff --git a/compiler/rustc_ast/src/util/comments.rs b/compiler/rustc_ast/src/util/comments.rs index 0a391123dd3..612ee71f350 100644 --- a/compiler/rustc_ast/src/util/comments.rs +++ b/compiler/rustc_ast/src/util/comments.rs @@ -1,3 +1,4 @@ +use crate::token::CommentKind; use rustc_span::source_map::SourceMap; use rustc_span::{BytePos, CharPos, FileName, Pos, Symbol}; @@ -25,7 +26,7 @@ pub struct Comment { /// Makes a doc string more presentable to users. /// Used by rustdoc and perhaps other tools, but not by rustc. -pub fn beautify_doc_string(data: Symbol) -> Symbol { +pub fn beautify_doc_string(data: Symbol, kind: CommentKind) -> Symbol { fn get_vertical_trim(lines: &[&str]) -> Option<(usize, usize)> { let mut i = 0; let mut j = lines.len(); @@ -42,10 +43,28 @@ pub fn beautify_doc_string(data: Symbol) -> Symbol { if i != 0 || j != lines.len() { Some((i, j)) } else { None } } - fn get_horizontal_trim(lines: &[&str]) -> Option<usize> { + fn get_horizontal_trim(lines: &[&str], kind: CommentKind) -> Option<usize> { let mut i = usize::MAX; let mut first = true; + // In case we have doc comments like `/**` or `/*!`, we want to remove stars if they are + // present. However, we first need to strip the empty lines so they don't get in the middle + // when we try to compute the "horizontal trim". + let lines = if kind == CommentKind::Block { + let mut i = 0; + let mut j = lines.len(); + + while i < j && lines[i].trim().is_empty() { + i += 1; + } + while j > i && lines[j - 1].trim().is_empty() { + j -= 1; + } + &lines[i..j] + } else { + lines + }; + for line in lines { for (j, c) in line.chars().enumerate() { if j > i || !"* \t".contains(c) { @@ -79,11 +98,13 @@ pub fn beautify_doc_string(data: Symbol) -> Symbol { } else { &mut lines }; - if let Some(horizontal) = get_horizontal_trim(&lines) { + if let Some(horizontal) = get_horizontal_trim(&lines, kind) { changes = true; // remove a "[ \t]*\*" block from each line, if possible for line in lines.iter_mut() { - *line = &line[horizontal + 1..]; + if horizontal + 1 < line.len() { + *line = &line[horizontal + 1..]; + } } } if changes { diff --git a/compiler/rustc_ast/src/util/comments/tests.rs b/compiler/rustc_ast/src/util/comments/tests.rs index 6d137f3774f..98f692a7724 100644 --- a/compiler/rustc_ast/src/util/comments/tests.rs +++ b/compiler/rustc_ast/src/util/comments/tests.rs @@ -5,7 +5,7 @@ use rustc_span::create_default_session_globals_then; fn test_block_doc_comment_1() { create_default_session_globals_then(|| { 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), CommentKind::Block); assert_eq!(stripped.as_str(), " Test \n* Test\n Test"); }) } @@ -14,7 +14,7 @@ fn test_block_doc_comment_1() { fn test_block_doc_comment_2() { create_default_session_globals_then(|| { let comment = "\n * Test\n * Test\n"; - let stripped = beautify_doc_string(Symbol::intern(comment)); + let stripped = beautify_doc_string(Symbol::intern(comment), CommentKind::Block); assert_eq!(stripped.as_str(), " Test\n Test"); }) } @@ -23,7 +23,7 @@ fn test_block_doc_comment_2() { fn test_block_doc_comment_3() { create_default_session_globals_then(|| { 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), CommentKind::Block); assert_eq!(stripped.as_str(), " let a: *i32;\n *a = 5;"); }) } @@ -31,13 +31,13 @@ fn test_block_doc_comment_3() { #[test] fn test_line_doc_comment() { create_default_session_globals_then(|| { - let stripped = beautify_doc_string(Symbol::intern(" test")); + let stripped = beautify_doc_string(Symbol::intern(" test"), CommentKind::Line); assert_eq!(stripped.as_str(), " test"); - let stripped = beautify_doc_string(Symbol::intern("! test")); + let stripped = beautify_doc_string(Symbol::intern("! test"), CommentKind::Line); assert_eq!(stripped.as_str(), "! test"); - let stripped = beautify_doc_string(Symbol::intern("test")); + let stripped = beautify_doc_string(Symbol::intern("test"), CommentKind::Line); assert_eq!(stripped.as_str(), "test"); - let stripped = beautify_doc_string(Symbol::intern("!test")); + let stripped = beautify_doc_string(Symbol::intern("!test"), CommentKind::Line); assert_eq!(stripped.as_str(), "!test"); }) } diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs index 21cb93cc5f4..b95fe1b0549 100644 --- a/compiler/rustc_save_analysis/src/lib.rs +++ b/compiler/rustc_save_analysis/src/lib.rs @@ -821,9 +821,9 @@ impl<'tcx> SaveContext<'tcx> { let mut result = String::new(); for attr in attrs { - if let Some(val) = attr.doc_str() { + if let Some((val, kind)) = attr.doc_str_and_comment_kind() { // FIXME: Should save-analysis beautify doc strings itself or leave it to users? - result.push_str(beautify_doc_string(val).as_str()); + result.push_str(beautify_doc_string(val, kind).as_str()); result.push('\n'); } } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 7ae7b940f26..993503005d7 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1041,9 +1041,9 @@ impl Attributes { ) -> Attributes { let mut doc_strings: Vec<DocFragment> = vec![]; let clean_attr = |(attr, parent_module): (&ast::Attribute, Option<DefId>)| { - if let Some(value) = attr.doc_str() { + if let Some((value, kind)) = attr.doc_str_and_comment_kind() { trace!("got doc_str={:?}", value); - let value = beautify_doc_string(value); + let value = beautify_doc_string(value, kind); let kind = if attr.is_doc_comment() { DocFragmentKind::SugaredDoc } else { diff --git a/src/test/rustdoc/strip-block-doc-comments-stars.docblock.html b/src/test/rustdoc/strip-block-doc-comments-stars.docblock.html new file mode 100644 index 00000000000..22b0b5dc47e --- /dev/null +++ b/src/test/rustdoc/strip-block-doc-comments-stars.docblock.html @@ -0,0 +1,2 @@ +<div class="docblock"><p>a</p> +</div> \ No newline at end of file diff --git a/src/test/rustdoc/strip-block-doc-comments-stars.rs b/src/test/rustdoc/strip-block-doc-comments-stars.rs new file mode 100644 index 00000000000..ed2297b4fac --- /dev/null +++ b/src/test/rustdoc/strip-block-doc-comments-stars.rs @@ -0,0 +1,11 @@ +#![crate_name = "foo"] + +// The goal of this test is to answer that it won't be generated as a list because +// block doc comments can have their lines starting with a star. + +// @has foo/fn.foo.html +// @snapshot docblock - '//*[@class="rustdoc-toggle top-doc"]//*[@class="docblock"]' +/** + * a + */ +pub fn foo() {} |
