rustc_expand: Don not beautify doc comments before passing them to macros

Beautify all doc strings in rustdoc instead, including those in `#[doc]` attributes
This commit is contained in:
Vadim Petrochenkov 2020-07-22 12:28:17 +03:00
parent 000c070b70
commit 712de2b521
6 changed files with 37 additions and 54 deletions

View File

@ -1,5 +1,4 @@
use crate::ast::AttrStyle;
use crate::token::CommentKind;
use rustc_span::source_map::SourceMap;
use rustc_span::{BytePos, CharPos, FileName, Pos, Symbol};
@ -64,7 +63,9 @@ pub fn block_doc_comment_style(block_comment: &str, terminated: bool) -> Option<
}
}
pub fn strip_doc_comment_decoration(data: Symbol, comment_kind: CommentKind) -> String {
/// 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) -> String {
/// remove whitespace-only lines from the start/end of lines
fn vertical_trim(lines: Vec<String>) -> Vec<String> {
let mut i = 0;
@ -126,18 +127,14 @@ pub fn strip_doc_comment_decoration(data: Symbol, comment_kind: CommentKind) ->
}
}
match comment_kind {
CommentKind::Line => {
let data = data.as_str();
let prefix_len = if data.starts_with('!') { 1 } else { 0 };
data[prefix_len..].to_string()
}
CommentKind::Block => {
let lines = data.as_str().lines().map(|s| s.to_string()).collect::<Vec<String>>();
let lines = vertical_trim(lines);
let lines = horizontal_trim(lines);
lines.join("\n")
}
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()
}
}

View File

@ -12,7 +12,7 @@ fn line_doc_comments() {
fn test_block_doc_comment_1() {
with_default_session_globals(|| {
let comment = "\n * Test \n ** Test\n * Test\n";
let stripped = strip_doc_comment_decoration(Symbol::intern(comment), CommentKind::Block);
let stripped = beautify_doc_string(Symbol::intern(comment));
assert_eq!(stripped, " Test \n* Test\n Test");
})
}
@ -21,7 +21,7 @@ fn test_block_doc_comment_1() {
fn test_block_doc_comment_2() {
with_default_session_globals(|| {
let comment = "\n * Test\n * Test\n";
let stripped = strip_doc_comment_decoration(Symbol::intern(comment), CommentKind::Block);
let stripped = beautify_doc_string(Symbol::intern(comment));
assert_eq!(stripped, " Test\n Test");
})
}
@ -30,7 +30,7 @@ fn test_block_doc_comment_2() {
fn test_block_doc_comment_3() {
with_default_session_globals(|| {
let comment = "\n let a: *i32;\n *a = 5;\n";
let stripped = strip_doc_comment_decoration(Symbol::intern(comment), CommentKind::Block);
let stripped = beautify_doc_string(Symbol::intern(comment));
assert_eq!(stripped, " let a: *i32;\n *a = 5;");
})
}
@ -38,13 +38,13 @@ fn test_block_doc_comment_3() {
#[test]
fn test_line_doc_comment() {
with_default_session_globals(|| {
let stripped = strip_doc_comment_decoration(Symbol::intern(" test"), CommentKind::Line);
let stripped = beautify_doc_string(Symbol::intern(" test"));
assert_eq!(stripped, " test");
let stripped = strip_doc_comment_decoration(Symbol::intern("! test"), CommentKind::Line);
assert_eq!(stripped, " test");
let stripped = strip_doc_comment_decoration(Symbol::intern("test"), CommentKind::Line);
assert_eq!(stripped, "test");
let stripped = strip_doc_comment_decoration(Symbol::intern("!test"), CommentKind::Line);
let stripped = beautify_doc_string(Symbol::intern("! test"));
assert_eq!(stripped, "! test");
let stripped = beautify_doc_string(Symbol::intern("test"));
assert_eq!(stripped, "test");
let stripped = beautify_doc_string(Symbol::intern("!test"));
assert_eq!(stripped, "!test");
})
}

View File

@ -3,7 +3,6 @@ use crate::base::ExtCtxt;
use rustc_ast::ast;
use rustc_ast::token;
use rustc_ast::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint};
use rustc_ast::util::comments;
use rustc_ast_pretty::pprust;
use rustc_data_structures::sync::Lrc;
use rustc_errors::Diagnostic;
@ -148,10 +147,9 @@ impl FromInternal<(TreeAndJoint, &'_ ParseSess, &'_ mut Vec<Self>)>
tt!(Punct::new('\'', true))
}
Literal(lit) => tt!(Literal { lit }),
DocComment(comment_kind, attr_style, data) => {
let stripped = comments::strip_doc_comment_decoration(data, comment_kind);
DocComment(_, attr_style, data) => {
let mut escaped = String::new();
for ch in stripped.chars() {
for ch in data.as_str().chars() {
escaped.extend(ch.escape_debug());
}
let stream = vec![

View File

@ -22,7 +22,6 @@ use rustc_ast::ast::{
use rustc_ast::ptr::P;
use rustc_ast::token::{self, DelimToken, Token, TokenKind};
use rustc_ast::tokenstream::{self, DelimSpan, TokenStream, TokenTree, TreeAndJoint};
use rustc_ast::util::comments::strip_doc_comment_decoration;
use rustc_ast_pretty::pprust;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, FatalError, PResult};
use rustc_session::parse::ParseSess;
@ -209,20 +208,18 @@ impl TokenCursor {
}
fn next_desugared(&mut self) -> Token {
let (data, comment_kind, attr_style, sp) = match self.next() {
Token { kind: token::DocComment(comment_kind, attr_style, data), span } => {
(data, comment_kind, attr_style, span)
let (data, attr_style, sp) = match self.next() {
Token { kind: token::DocComment(_, attr_style, data), span } => {
(data, attr_style, span)
}
tok => return tok,
};
let stripped = strip_doc_comment_decoration(data, comment_kind);
// Searches for the occurrences of `"#*` and returns the minimum number of `#`s
// required to wrap the text.
let mut num_of_hashes = 0;
let mut count = 0;
for ch in stripped.chars() {
for ch in data.as_str().chars() {
count = match ch {
'"' => 1,
'#' if count > 0 => count + 1,
@ -238,10 +235,7 @@ impl TokenCursor {
[
TokenTree::token(token::Ident(sym::doc, false), sp),
TokenTree::token(token::Eq, sp),
TokenTree::token(
TokenKind::lit(token::StrRaw(num_of_hashes), Symbol::intern(&stripped), None),
sp,
),
TokenTree::token(TokenKind::lit(token::StrRaw(num_of_hashes), data, None), sp),
]
.iter()
.cloned()

View File

@ -10,7 +10,7 @@ mod span_utils;
mod sig;
use rustc_ast::ast::{self};
use rustc_ast::util::comments::strip_doc_comment_decoration;
use rustc_ast::util::comments::beautify_doc_string;
use rustc_ast_pretty::pprust::attribute_to_string;
use rustc_hir as hir;
use rustc_hir::def::{DefKind as HirDefKind, Res};
@ -822,11 +822,8 @@ impl<'tcx> SaveContext<'tcx> {
for attr in attrs {
if let Some(val) = attr.doc_str() {
if let ast::AttrKind::DocComment(comment_kind, _) = attr.kind {
result.push_str(&strip_doc_comment_decoration(val, comment_kind));
} else {
result.push_str(&val.as_str());
}
// FIXME: Should save-analysis beautify doc strings itself or leave it to users?
result.push_str(&beautify_doc_string(val));
result.push('\n');
} else if attr.check_name(sym::doc) {
if let Some(meta_list) = attr.meta_item_list() {

View File

@ -10,7 +10,7 @@ use std::{slice, vec};
use rustc_ast::ast::{self, AttrStyle};
use rustc_ast::attr;
use rustc_ast::util::comments::strip_doc_comment_decoration;
use rustc_ast::util::comments::beautify_doc_string;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir as hir;
use rustc_hir::def::Res;
@ -506,15 +506,12 @@ impl Attributes {
.iter()
.filter_map(|attr| {
if let Some(value) = attr.doc_str() {
let (value, mk_fragment): (_, fn(_, _, _) -> _) =
if let ast::AttrKind::DocComment(comment_kind, _) = attr.kind {
(
strip_doc_comment_decoration(value, comment_kind),
DocFragment::SugaredDoc,
)
} else {
(value.to_string(), DocFragment::RawDoc)
};
let value = beautify_doc_string(value);
let mk_fragment: fn(_, _, _) -> _ = if attr.is_doc_comment() {
DocFragment::SugaredDoc
} else {
DocFragment::RawDoc
};
let line = doc_line;
doc_line += value.lines().count();