mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-18 09:53:26 +00:00
Merge pull request #3002 from lqd/normalize-doc-attributes
normalize_doc_attributes option: convert doc attributes to comments
This commit is contained in:
commit
1739041f03
@ -2188,6 +2188,32 @@ If you want to format code that requires edition 2018, add the following to your
|
||||
edition = "2018"
|
||||
```
|
||||
|
||||
## `normalize_doc_attributes`
|
||||
|
||||
Convert `#![doc]` and `#[doc]` attributes to `//!` and `///` doc comments.
|
||||
|
||||
- **Default value**: `false`
|
||||
- **Possible values**: `true`, `false`
|
||||
- **Stable**: No
|
||||
|
||||
#### `false` (default):
|
||||
|
||||
```rust
|
||||
#![doc = "Example documentation"]
|
||||
|
||||
#[doc = "Example item documentation"]
|
||||
pub enum Foo {}
|
||||
```
|
||||
|
||||
#### `true`:
|
||||
|
||||
```rust
|
||||
//! Example documentation
|
||||
|
||||
/// Example item documentation
|
||||
pub enum Foo {}
|
||||
```
|
||||
|
||||
## `emit_mode`
|
||||
|
||||
Internal option
|
||||
|
37
src/attr.rs
37
src/attr.rs
@ -10,7 +10,7 @@
|
||||
|
||||
//! Format attributes and meta items.
|
||||
|
||||
use comment::{contains_comment, rewrite_doc_comment};
|
||||
use comment::{contains_comment, rewrite_doc_comment, CommentStyle};
|
||||
use config::lists::*;
|
||||
use config::IndentStyle;
|
||||
use expr::rewrite_literal;
|
||||
@ -350,13 +350,34 @@ impl Rewrite for ast::Attribute {
|
||||
if contains_comment(snippet) {
|
||||
return Some(snippet.to_owned());
|
||||
}
|
||||
// 1 = `[`
|
||||
let shape = shape.offset_left(prefix.len() + 1)?;
|
||||
Some(
|
||||
self.meta()
|
||||
.and_then(|meta| meta.rewrite(context, shape))
|
||||
.map_or_else(|| snippet.to_owned(), |rw| format!("{}[{}]", prefix, rw)),
|
||||
)
|
||||
|
||||
if let Some(ref meta) = self.meta() {
|
||||
// This attribute is possibly a doc attribute needing normalization to a doc comment
|
||||
if context.config.normalize_doc_attributes() && meta.check_name("doc") {
|
||||
if let Some(ref literal) = meta.value_str() {
|
||||
let comment_style = match self.style {
|
||||
ast::AttrStyle::Inner => CommentStyle::Doc,
|
||||
ast::AttrStyle::Outer => CommentStyle::TripleSlash,
|
||||
};
|
||||
|
||||
let doc_comment = format!("{}{}", comment_style.opener(), literal);
|
||||
return rewrite_doc_comment(
|
||||
&doc_comment,
|
||||
shape.comment(context.config),
|
||||
context.config,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 1 = `[`
|
||||
let shape = shape.offset_left(prefix.len() + 1)?;
|
||||
Some(
|
||||
meta.rewrite(context, shape)
|
||||
.map_or_else(|| snippet.to_owned(), |rw| format!("{}[{}]", prefix, rw)),
|
||||
)
|
||||
} else {
|
||||
Some(snippet.to_owned())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ create_config! {
|
||||
comment_width: usize, 80, false,
|
||||
"Maximum length of comments. No effect unless wrap_comments = true";
|
||||
normalize_comments: bool, false, false, "Convert /* */ comments to // comments where possible";
|
||||
normalize_doc_attributes: bool, false, false, "Normalize doc attributes as doc comments";
|
||||
license_template_path: String, String::default(), false,
|
||||
"Beginning of file must match license template";
|
||||
format_strings: bool, false, false, "Format string literals where necessary";
|
||||
|
@ -30,6 +30,7 @@ impl Bar {
|
||||
/// Blah blah blooo.
|
||||
/// Blah blah blooo.
|
||||
#[an_attribute]
|
||||
#[doc = "an attribute that shouldn't be normalized to a doc comment"]
|
||||
fn foo(&mut self) -> isize {
|
||||
}
|
||||
|
||||
|
91
tests/source/doc-attrib.rs
Normal file
91
tests/source/doc-attrib.rs
Normal file
@ -0,0 +1,91 @@
|
||||
// rustfmt-wrap_comments: true
|
||||
// rustfmt-normalize_doc_attributes: true
|
||||
|
||||
// Only doc = "" attributes should be normalized
|
||||
#![doc = "Example doc attribute comment"]
|
||||
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
|
||||
html_root_url = "https://doc.rust-lang.org/nightly/",
|
||||
html_playground_url = "https://play.rust-lang.org/", test(attr(deny(warnings))))]
|
||||
|
||||
|
||||
// Long `#[doc = "..."]`
|
||||
struct A { #[doc = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"] b: i32 }
|
||||
|
||||
|
||||
#[doc = "The `nodes` and `edges` method each return instantiations of `Cow<[T]>` to leave implementers the freedom to create entirely new vectors or to pass back slices into internally owned vectors."]
|
||||
struct B { b: i32 }
|
||||
|
||||
|
||||
#[doc = "Level 1 comment"]
|
||||
mod tests {
|
||||
#[doc = "Level 2 comment"]
|
||||
impl A {
|
||||
#[doc = "Level 3 comment"]
|
||||
fn f() {
|
||||
#[doc = "Level 4 comment"]
|
||||
fn g() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct C {
|
||||
#[doc = "item doc attrib comment"]
|
||||
// regular item comment
|
||||
b: i32,
|
||||
|
||||
// regular item comment
|
||||
#[doc = "item doc attrib comment"]
|
||||
c: i32,
|
||||
}
|
||||
|
||||
// non-regression test for regular attributes, from #2647
|
||||
#[cfg(feature = "this_line_is_101_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")]
|
||||
pub fn foo() {}
|
||||
|
||||
// path attrs
|
||||
#[clippy::bar]
|
||||
#[clippy::bar=foo]
|
||||
#[clippy::bar(a, b, c)]
|
||||
pub fn foo() {}
|
||||
|
||||
mod issue_2620 {
|
||||
#[derive(Debug, StructOpt)]
|
||||
#[structopt(about = "Display information about the character on FF Logs")]
|
||||
pub struct Params {
|
||||
#[structopt(help = "The server the character is on")]
|
||||
server: String,
|
||||
#[structopt(help = "The character's first name")]
|
||||
first_name: String,
|
||||
#[structopt(help = "The character's last name")]
|
||||
last_name: String,
|
||||
#[structopt(
|
||||
short = "j",
|
||||
long = "job",
|
||||
help = "The job to look at",
|
||||
parse(try_from_str)
|
||||
)]
|
||||
job: Option<Job>
|
||||
}
|
||||
}
|
||||
|
||||
// non-regression test for regular attributes, from #2969
|
||||
#[cfg(not(all(feature="std",
|
||||
any(target_os = "linux", target_os = "android",
|
||||
target_os = "netbsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "haiku",
|
||||
target_os = "emscripten",
|
||||
target_os = "solaris",
|
||||
target_os = "cloudabi",
|
||||
target_os = "macos", target_os = "ios",
|
||||
target_os = "freebsd",
|
||||
target_os = "openbsd", target_os = "bitrig",
|
||||
target_os = "redox",
|
||||
target_os = "fuchsia",
|
||||
windows,
|
||||
all(target_arch = "wasm32", feature = "stdweb"),
|
||||
all(target_arch = "wasm32", feature = "wasm-bindgen"),
|
||||
))))]
|
||||
type Os = NoSource;
|
@ -33,6 +33,7 @@ impl Bar {
|
||||
/// Blah blah blooo.
|
||||
/// Blah blah blooo.
|
||||
#[an_attribute]
|
||||
#[doc = "an attribute that shouldn't be normalized to a doc comment"]
|
||||
fn foo(&mut self) -> isize {}
|
||||
|
||||
/// Blah blah bing.
|
||||
|
105
tests/target/doc-attrib.rs
Normal file
105
tests/target/doc-attrib.rs
Normal file
@ -0,0 +1,105 @@
|
||||
// rustfmt-wrap_comments: true
|
||||
// rustfmt-normalize_doc_attributes: true
|
||||
|
||||
// Only doc = "" attributes should be normalized
|
||||
//! Example doc attribute comment
|
||||
#![doc(
|
||||
html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
|
||||
html_root_url = "https://doc.rust-lang.org/nightly/",
|
||||
html_playground_url = "https://play.rust-lang.org/",
|
||||
test(attr(deny(warnings)))
|
||||
)]
|
||||
|
||||
// Long `#[doc = "..."]`
|
||||
struct A {
|
||||
/// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
b: i32,
|
||||
}
|
||||
|
||||
/// The `nodes` and `edges` method each return instantiations of `Cow<[T]>` to
|
||||
/// leave implementers the freedom to create entirely new vectors or to pass
|
||||
/// back slices into internally owned vectors.
|
||||
struct B {
|
||||
b: i32,
|
||||
}
|
||||
|
||||
/// Level 1 comment
|
||||
mod tests {
|
||||
/// Level 2 comment
|
||||
impl A {
|
||||
/// Level 3 comment
|
||||
fn f() {
|
||||
/// Level 4 comment
|
||||
fn g() {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct C {
|
||||
/// item doc attrib comment
|
||||
// regular item comment
|
||||
b: i32,
|
||||
|
||||
// regular item comment
|
||||
/// item doc attrib comment
|
||||
c: i32,
|
||||
}
|
||||
|
||||
// non-regression test for regular attributes, from #2647
|
||||
#[cfg(
|
||||
feature = "this_line_is_101_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
)]
|
||||
pub fn foo() {}
|
||||
|
||||
// path attrs
|
||||
#[clippy::bar]
|
||||
#[clippy::bar=foo]
|
||||
#[clippy::bar(a, b, c)]
|
||||
pub fn foo() {}
|
||||
|
||||
mod issue_2620 {
|
||||
#[derive(Debug, StructOpt)]
|
||||
#[structopt(about = "Display information about the character on FF Logs")]
|
||||
pub struct Params {
|
||||
#[structopt(help = "The server the character is on")]
|
||||
server: String,
|
||||
#[structopt(help = "The character's first name")]
|
||||
first_name: String,
|
||||
#[structopt(help = "The character's last name")]
|
||||
last_name: String,
|
||||
#[structopt(
|
||||
short = "j",
|
||||
long = "job",
|
||||
help = "The job to look at",
|
||||
parse(try_from_str)
|
||||
)]
|
||||
job: Option<Job>,
|
||||
}
|
||||
}
|
||||
|
||||
// non-regression test for regular attributes, from #2969
|
||||
#[cfg(not(all(
|
||||
feature = "std",
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "android",
|
||||
target_os = "netbsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "haiku",
|
||||
target_os = "emscripten",
|
||||
target_os = "solaris",
|
||||
target_os = "cloudabi",
|
||||
target_os = "macos",
|
||||
target_os = "ios",
|
||||
target_os = "freebsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "bitrig",
|
||||
target_os = "redox",
|
||||
target_os = "fuchsia",
|
||||
windows,
|
||||
all(target_arch = "wasm32", feature = "stdweb"),
|
||||
all(target_arch = "wasm32", feature = "wasm-bindgen"),
|
||||
)
|
||||
)))]
|
||||
type Os = NoSource;
|
Loading…
Reference in New Issue
Block a user