Skip to content

Commit

Permalink
Support option group documentation (#7593)
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaReiser authored Sep 22, 2023
1 parent 2ecf597 commit 01843af
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 3 deletions.
6 changes: 6 additions & 0 deletions crates/ruff_dev/src/generate_options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
36 changes: 34 additions & 2 deletions crates/ruff_macros/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
}
})
}
Expand Down
7 changes: 7 additions & 0 deletions crates/ruff_workspace/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
)]
Expand Down
15 changes: 14 additions & 1 deletion crates/ruff_workspace/src/options_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -51,14 +55,18 @@ impl Display for OptionEntry {
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct OptionSet {
record: fn(&mut dyn Visit),
doc: fn() -> Option<&'static str>,
}

impl OptionSet {
pub fn of<T>() -> Self
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.
Expand All @@ -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.
Expand Down
1 change: 1 addition & 0 deletions ruff.schema.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 01843af

Please sign in to comment.