-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
bevy_reflect: Reflect doc comments (#6234)
# Objective Resolves #6197 Make it so that doc comments can be retrieved via reflection. ## Solution Adds the new `documentation` feature to `bevy_reflect` (disabled by default). When enabled, documentation can be found using `TypeInfo::doc` for reflected types: ```rust /// Some struct. /// /// # Example /// /// ```ignore /// let some_struct = SomeStruct; /// ``` #[derive(Reflect)] struct SomeStruct; let info = <SomeStruct as Typed>::type_info(); assert_eq!( Some(" Some struct.\n\n # Example\n\n ```ignore\n let some_struct = SomeStruct;\n ```"), info.docs() ); ``` ### Notes for Reviewers The bulk of the files simply added the same 16 lines of code (with slightly different documentation). Most of the real changes occur in the `bevy_reflect_derive` files as well as in the added tests. --- ## Changelog * Added `documentation` feature to `bevy_reflect` * Added `TypeInfo::docs` method (and similar methods for all info types)
- Loading branch information
Showing
22 changed files
with
777 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
77 changes: 77 additions & 0 deletions
77
crates/bevy_reflect/bevy_reflect_derive/src/documentation.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
//! Contains code related to documentation reflection (requires the `documentation` feature). | ||
|
||
use proc_macro2::TokenStream; | ||
use quote::{quote, ToTokens}; | ||
use syn::{Attribute, Lit, Meta}; | ||
|
||
/// A struct used to represent a type's documentation, if any. | ||
/// | ||
/// When converted to a [`TokenStream`], this will output an `Option<String>` | ||
/// containing the collection of doc comments. | ||
#[derive(Default)] | ||
pub(crate) struct Documentation { | ||
docs: Vec<String>, | ||
} | ||
|
||
impl Documentation { | ||
/// Create a new [`Documentation`] from a type's attributes. | ||
/// | ||
/// This will collect all `#[doc = "..."]` attributes, including the ones generated via `///` and `//!`. | ||
pub fn from_attributes<'a>(attributes: impl IntoIterator<Item = &'a Attribute>) -> Self { | ||
let docs = attributes | ||
.into_iter() | ||
.filter_map(|attr| { | ||
let meta = attr.parse_meta().ok()?; | ||
match meta { | ||
Meta::NameValue(pair) if pair.path.is_ident("doc") => { | ||
if let Lit::Str(lit) = pair.lit { | ||
Some(lit.value()) | ||
} else { | ||
None | ||
} | ||
} | ||
_ => None, | ||
} | ||
}) | ||
.collect(); | ||
|
||
Self { docs } | ||
} | ||
|
||
/// The full docstring, if any. | ||
pub fn doc_string(&self) -> Option<String> { | ||
if self.docs.is_empty() { | ||
return None; | ||
} | ||
|
||
let len = self.docs.len(); | ||
Some( | ||
self.docs | ||
.iter() | ||
.enumerate() | ||
.map(|(index, doc)| { | ||
if index < len - 1 { | ||
format!("{}\n", doc) | ||
} else { | ||
doc.to_owned() | ||
} | ||
}) | ||
.collect(), | ||
) | ||
} | ||
|
||
/// Push a new docstring to the collection | ||
pub fn push(&mut self, doc: String) { | ||
self.docs.push(doc); | ||
} | ||
} | ||
|
||
impl ToTokens for Documentation { | ||
fn to_tokens(&self, tokens: &mut TokenStream) { | ||
if let Some(doc) = self.doc_string() { | ||
quote!(Some(#doc)).to_tokens(tokens); | ||
} else { | ||
quote!(None).to_tokens(tokens); | ||
} | ||
} | ||
} |
Oops, something went wrong.