mirror of
https://github.com/openharmony/third_party_rust_clap.git
synced 2026-07-21 00:25:56 -04:00
refactor(derive): Decouple extracting and formatting of doc comments
This commit is contained in:
+5
-24
@@ -19,13 +19,10 @@ use proc_macro2::{self, Span, TokenStream};
|
||||
use proc_macro_error::abort;
|
||||
use quote::{format_ident, quote, quote_spanned, ToTokens};
|
||||
use syn::DeriveInput;
|
||||
use syn::{
|
||||
self, ext::IdentExt, spanned::Spanned, Attribute, Field, Ident, LitStr, MetaNameValue, Type,
|
||||
Variant,
|
||||
};
|
||||
use syn::{self, ext::IdentExt, spanned::Spanned, Attribute, Field, Ident, LitStr, Type, Variant};
|
||||
|
||||
use crate::attr::*;
|
||||
use crate::utils::{inner_type, is_simple_ty, process_doc_comment, Sp, Ty};
|
||||
use crate::utils::{extract_doc_comment, format_doc_comment, inner_type, is_simple_ty, Sp, Ty};
|
||||
|
||||
/// Default casing style for generated arguments.
|
||||
pub const DEFAULT_CASING: CasingStyle = CasingStyle::Kebab;
|
||||
@@ -873,26 +870,10 @@ impl Item {
|
||||
}
|
||||
|
||||
fn push_doc_comment(&mut self, attrs: &[Attribute], short_name: &str, long_name: Option<&str>) {
|
||||
use syn::Lit::*;
|
||||
use syn::Meta::*;
|
||||
let lines = extract_doc_comment(attrs);
|
||||
|
||||
let comment_parts: Vec<_> = attrs
|
||||
.iter()
|
||||
.filter(|attr| attr.path.is_ident("doc"))
|
||||
.filter_map(|attr| {
|
||||
if let Ok(NameValue(MetaNameValue { lit: Str(s), .. })) = attr.parse_meta() {
|
||||
Some(s.value())
|
||||
} else {
|
||||
// non #[doc = "..."] attributes are not our concern
|
||||
// we leave them for rustc to handle
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
if let Some((short_help, long_help)) =
|
||||
process_doc_comment(&comment_parts, !self.verbatim_doc_comment)
|
||||
{
|
||||
if !lines.is_empty() {
|
||||
let (short_help, long_help) = format_doc_comment(&lines, !self.verbatim_doc_comment);
|
||||
let short_name = format_ident!("{}", short_name);
|
||||
let short = Method::new(
|
||||
short_name,
|
||||
|
||||
@@ -5,36 +5,52 @@
|
||||
|
||||
use std::iter;
|
||||
|
||||
pub fn process_doc_comment(
|
||||
lines: &[String],
|
||||
preprocess: bool,
|
||||
) -> Option<(Option<String>, Option<String>)> {
|
||||
pub fn extract_doc_comment(attrs: &[syn::Attribute]) -> Vec<String> {
|
||||
use syn::Lit::*;
|
||||
use syn::Meta::*;
|
||||
use syn::MetaNameValue;
|
||||
|
||||
// multiline comments (`/** ... */`) may have LFs (`\n`) in them,
|
||||
// we need to split so we could handle the lines correctly
|
||||
//
|
||||
// we also need to remove leading and trailing blank lines
|
||||
let mut lines: Vec<&str> = lines
|
||||
let mut lines: Vec<_> = attrs
|
||||
.iter()
|
||||
.filter(|attr| attr.path.is_ident("doc"))
|
||||
.filter_map(|attr| {
|
||||
if let Ok(NameValue(MetaNameValue { lit: Str(s), .. })) = attr.parse_meta() {
|
||||
Some(s.value())
|
||||
} else {
|
||||
// non #[doc = "..."] attributes are not our concern
|
||||
// we leave them for rustc to handle
|
||||
None
|
||||
}
|
||||
})
|
||||
.skip_while(|s| is_blank(s))
|
||||
.flat_map(|s| s.split('\n'))
|
||||
.flat_map(|s| {
|
||||
let lines = s
|
||||
.split('\n')
|
||||
.map(|s| {
|
||||
// remove one leading space no matter what
|
||||
let s = s.strip_prefix(' ').unwrap_or(s);
|
||||
s.to_owned()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
lines
|
||||
})
|
||||
.collect();
|
||||
|
||||
while let Some(true) = lines.last().map(|s| is_blank(s)) {
|
||||
lines.pop();
|
||||
}
|
||||
|
||||
if lines.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
// remove one leading space no matter what
|
||||
for line in lines.iter_mut() {
|
||||
*line = line.strip_prefix(' ').unwrap_or(line);
|
||||
}
|
||||
lines
|
||||
}
|
||||
|
||||
pub fn format_doc_comment(lines: &[String], preprocess: bool) -> (Option<String>, Option<String>) {
|
||||
if let Some(first_blank) = lines.iter().position(|s| is_blank(s)) {
|
||||
let (short, long) = if preprocess {
|
||||
let paragraphs = split_paragraphs(&lines);
|
||||
let paragraphs = split_paragraphs(lines);
|
||||
let short = paragraphs[0].clone();
|
||||
let long = paragraphs.join("\n\n");
|
||||
(remove_period(short), long)
|
||||
@@ -44,20 +60,20 @@ pub fn process_doc_comment(
|
||||
(short, long)
|
||||
};
|
||||
|
||||
Some((Some(short), Some(long)))
|
||||
(Some(short), Some(long))
|
||||
} else {
|
||||
let short = if preprocess {
|
||||
let s = merge_lines(&lines);
|
||||
let s = merge_lines(lines);
|
||||
remove_period(s)
|
||||
} else {
|
||||
lines.join("\n")
|
||||
};
|
||||
|
||||
Some((Some(short), None))
|
||||
(Some(short), None)
|
||||
}
|
||||
}
|
||||
|
||||
fn split_paragraphs(lines: &[&str]) -> Vec<String> {
|
||||
fn split_paragraphs(lines: &[String]) -> Vec<String> {
|
||||
let mut last_line = 0;
|
||||
iter::from_fn(|| {
|
||||
let slice = &lines[last_line..];
|
||||
@@ -91,6 +107,10 @@ fn is_blank(s: &str) -> bool {
|
||||
s.trim().is_empty()
|
||||
}
|
||||
|
||||
fn merge_lines(lines: &[&str]) -> String {
|
||||
lines.iter().map(|s| s.trim()).collect::<Vec<_>>().join(" ")
|
||||
fn merge_lines(lines: impl IntoIterator<Item = impl AsRef<str>>) -> String {
|
||||
lines
|
||||
.into_iter()
|
||||
.map(|s| s.as_ref().trim().to_owned())
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ")
|
||||
}
|
||||
|
||||
@@ -2,8 +2,10 @@ mod doc_comments;
|
||||
mod spanned;
|
||||
mod ty;
|
||||
|
||||
pub use doc_comments::extract_doc_comment;
|
||||
pub use doc_comments::format_doc_comment;
|
||||
|
||||
pub use self::{
|
||||
doc_comments::process_doc_comment,
|
||||
spanned::Sp,
|
||||
ty::{inner_type, is_simple_ty, sub_type, subty_if_name, Ty},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user