Support option group documentation (#7593)

This commit is contained in:
Micha Reiser 2023-09-22 18:31:52 +02:00 committed by GitHub
parent 2ecf59726f
commit 01843af21a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 3 deletions

View file

@ -16,6 +16,12 @@ pub(crate) fn generate() -> String {
fn generate_set(output: &mut String, set: &Set) {
writeln!(output, "### {title}\n", title = set.title()).unwrap();
if let Some(documentation) = set.metadata().documentation() {
output.push_str(documentation);
output.push('\n');
output.push('\n');
}
let mut visitor = CollectOptionsVisitor::default();
set.metadata().record(&mut visitor);

View file

@ -10,7 +10,12 @@ use syn::{
};
pub(crate) fn derive_impl(input: DeriveInput) -> syn::Result<proc_macro2::TokenStream> {
let DeriveInput { ident, data, .. } = input;
let DeriveInput {
ident,
data,
attrs: struct_attributes,
..
} = input;
match data {
Data::Struct(DataStruct {
@ -50,12 +55,39 @@ pub(crate) fn derive_impl(input: DeriveInput) -> syn::Result<proc_macro2::TokenS
};
}
Ok(quote! {
let docs: Vec<&Attribute> = struct_attributes
.iter()
.filter(|attr| attr.path().is_ident("doc"))
.collect();
// Convert the list of `doc` attributes into a single string.
let doc = dedent(
&docs
.into_iter()
.map(parse_doc)
.collect::<syn::Result<Vec<_>>>()?
.join("\n"),
)
.trim_matches('\n')
.to_string();
let documentation = if doc.is_empty() {
None
} else {
Some(quote!(
fn documentation() -> Option<&'static str> {
Some(&#doc)
}
))
};
Ok(quote! {
impl crate::options_base::OptionsMetadata for #ident {
fn record(visit: &mut dyn crate::options_base::Visit) {
#(#output);*
}
#documentation
}
})
}

View file

@ -2412,8 +2412,15 @@ impl OptionsMetadata for FormatOrOutputFormat {
fn record(visit: &mut dyn Visit) {
FormatOptions::record(visit);
}
fn documentation() -> Option<&'static str> {
FormatOptions::documentation()
}
}
/// Experimental: Configures how `ruff format` formats your code.
///
/// Please provide feedback in [this discussion](https://github.com/astral-sh/ruff/discussions/7310).
#[derive(
Debug, PartialEq, Eq, Default, Serialize, Deserialize, ConfigurationOptions, CombineOptions,
)]

View file

@ -16,6 +16,10 @@ pub trait OptionsMetadata {
/// Visits the options metadata of this object by calling `visit` for each option.
fn record(visit: &mut dyn Visit);
fn documentation() -> Option<&'static str> {
None
}
/// Returns the extracted metadata.
fn metadata() -> OptionSet
where
@ -51,6 +55,7 @@ impl Display for OptionEntry {
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct OptionSet {
record: fn(&mut dyn Visit),
doc: fn() -> Option<&'static str>,
}
impl OptionSet {
@ -58,7 +63,10 @@ impl OptionSet {
where
T: OptionsMetadata + 'static,
{
Self { record: T::record }
Self {
record: T::record,
doc: T::documentation,
}
}
/// Visits the options in this set by calling `visit` for each option.
@ -67,6 +75,11 @@ impl OptionSet {
record(visit);
}
pub fn documentation(&self) -> Option<&'static str> {
let documentation = self.doc;
documentation()
}
/// Returns `true` if this set has an option that resolves to `name`.
///
/// The name can be separated by `.` to find a nested option.

1
ruff.schema.json generated
View file

@ -1163,6 +1163,7 @@
"additionalProperties": false
},
"FormatOptions": {
"description": "Experimental: Configures how `ruff format` formats your code.\n\nPlease provide feedback in [this discussion](https://github.com/astral-sh/ruff/discussions/7310).",
"type": "object",
"properties": {
"indent-style": {