Skip to content

Commit

Permalink
codegen: Opt out of documentation (#843)
Browse files Browse the repository at this point in the history
* codegen: Opt-out for API documentation

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* cli: Add `--no-docs` flag

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* tests: Check no documentation was generated

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Update cargo.lock

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* tests: Adjust testing for the new codegen API

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* macro: Ensure `subxt` macro does not contain documentation

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* macro: Expose documentation flag

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* expose_documentation => generate_docs

---------

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Co-authored-by: James Wilson <james@jsdw.me>
  • Loading branch information
lexnv and jsdw authored Mar 2, 2023
1 parent 1c5faf3 commit 5320ca9
Show file tree
Hide file tree
Showing 13 changed files with 244 additions and 93 deletions.
141 changes: 72 additions & 69 deletions Cargo.lock

Large diffs are not rendered by default.

16 changes: 15 additions & 1 deletion cli/src/commands/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ pub struct Opts {
/// Defaults to `::subxt`.
#[clap(long = "crate")]
crate_path: Option<String>,
/// Do not generate documentation for the runtime API code.
///
/// Defaults to `false` (documentation is generated).
#[clap(long, action)]
no_docs: bool,
}

fn derive_for_type_parser(src: &str) -> Result<(String, String), String> {
Expand Down Expand Up @@ -69,7 +74,13 @@ pub async fn run(opts: Opts) -> color_eyre::Result<()> {
subxt_codegen::utils::fetch_metadata_bytes(&url).await?
};

codegen(&bytes, opts.derives, opts.derives_for_type, opts.crate_path)?;
codegen(
&bytes,
opts.derives,
opts.derives_for_type,
opts.crate_path,
opts.no_docs,
)?;
Ok(())
}

Expand All @@ -78,6 +89,7 @@ fn codegen(
raw_derives: Vec<String>,
derives_for_type: Vec<(String, String)>,
crate_path: Option<String>,
no_docs: bool,
) -> color_eyre::Result<()> {
let item_mod = syn::parse_quote!(
pub mod api {}
Expand All @@ -100,12 +112,14 @@ fn codegen(

let type_substitutes = TypeSubstitutes::new(&crate_path);

let should_gen_docs = !no_docs;
let runtime_api = subxt_codegen::generate_runtime_api_from_bytes(
item_mod,
metadata_bytes,
derives,
type_substitutes,
crate_path,
should_gen_docs,
);
println!("{runtime_api}");
Ok(())
Expand Down
10 changes: 8 additions & 2 deletions codegen/src/api/calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ pub fn generate_calls(
pallet: &PalletMetadata<PortableForm>,
types_mod_ident: &syn::Ident,
crate_path: &CratePath,
should_gen_docs: bool,
) -> TokenStream2 {
// Early return if the pallet has no calls.
let call = if let Some(ref calls) = pallet.calls {
Expand All @@ -54,6 +55,7 @@ pub fn generate_calls(
|name| name.to_upper_camel_case().into(),
"Call",
crate_path,
should_gen_docs,
);
let (call_structs, call_fns): (Vec<_>, Vec<_>) = struct_defs
.iter_mut()
Expand Down Expand Up @@ -98,7 +100,8 @@ pub fn generate_calls(
let fn_name = format_ident!("{}", variant_name.to_snake_case());
// Propagate the documentation just to `TransactionApi` methods, while
// draining the documentation of inner call structures.
let docs = struct_def.docs.take();
let docs = should_gen_docs.then_some(struct_def.docs.take()).flatten();

// The call structure's documentation was stripped above.
let call_struct = quote! {
#struct_def
Expand All @@ -124,9 +127,12 @@ pub fn generate_calls(

let call_ty = type_gen.resolve_type(call.ty.id());
let docs = call_ty.docs();
let docs = should_gen_docs
.then_some(quote! { #( #[doc = #docs ] )* })
.unwrap_or_default();

quote! {
#( #[doc = #docs ] )*
#docs
pub mod calls {
use super::root_mod;
use super::#types_mod_ident;
Expand Down
6 changes: 5 additions & 1 deletion codegen/src/api/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ pub fn generate_constants(
pallet: &PalletMetadata<PortableForm>,
types_mod_ident: &syn::Ident,
crate_path: &CratePath,
should_gen_docs: bool,
) -> TokenStream2 {
// Early return if the pallet has no constants.
if pallet.constants.is_empty() {
Expand All @@ -64,9 +65,12 @@ pub fn generate_constants(

let return_ty = type_gen.resolve_type_path(constant.ty.id());
let docs = &constant.docs;
let docs = should_gen_docs
.then_some(quote! { #( #[doc = #docs ] )* })
.unwrap_or_default();

quote! {
#( #[doc = #docs ] )*
#docs
pub fn #fn_name(&self) -> #crate_path::constants::StaticConstantAddress<#crate_path::metadata::DecodeStaticType<#return_ty>> {
#crate_path::constants::StaticConstantAddress::new(
#pallet_name,
Expand Down
7 changes: 6 additions & 1 deletion codegen/src/api/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ pub fn generate_events(
pallet: &PalletMetadata<PortableForm>,
types_mod_ident: &syn::Ident,
crate_path: &CratePath,
should_gen_docs: bool,
) -> TokenStream2 {
// Early return if the pallet has no events.
let event = if let Some(ref event) = pallet.event {
Expand All @@ -59,6 +60,7 @@ pub fn generate_events(
|name| name.into(),
"Event",
crate_path,
should_gen_docs,
);
let event_structs = struct_defs.iter().map(|(variant_name, struct_def)| {
let pallet_name = &pallet.name;
Expand All @@ -77,9 +79,12 @@ pub fn generate_events(
let event_type = type_gen.resolve_type_path(event.ty.id());
let event_ty = type_gen.resolve_type(event.ty.id());
let docs = event_ty.docs();
let docs = should_gen_docs
.then_some(quote! { #( #[doc = #docs ] )* })
.unwrap_or_default();

quote! {
#( #[doc = #docs ] )*
#docs
pub type Event = #event_type;
pub mod events {
use super::#types_mod_ident;
Expand Down
34 changes: 30 additions & 4 deletions codegen/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ use syn::parse_quote;
/// * `derives` - Provide custom derives for the generated types.
/// * `type_substitutes` - Provide custom type substitutes.
/// * `crate_path` - Path to the `subxt` crate.
/// * `should_gen_docs` - True if the generated API contains the documentation from the metadata.
///
/// **Note:** This is a wrapper over [RuntimeGenerator] for static metadata use-cases.
pub fn generate_runtime_api_from_path<P>(
Expand All @@ -64,6 +65,7 @@ pub fn generate_runtime_api_from_path<P>(
derives: DerivesRegistry,
type_substitutes: TypeSubstitutes,
crate_path: CratePath,
should_gen_docs: bool,
) -> TokenStream2
where
P: AsRef<path::Path>,
Expand All @@ -82,6 +84,7 @@ where
derives,
type_substitutes,
crate_path,
should_gen_docs,
)
}

Expand All @@ -96,6 +99,7 @@ where
/// * `derives` - Provide custom derives for the generated types.
/// * `type_substitutes` - Provide custom type substitutes.
/// * `crate_path` - Path to the `subxt` crate.
/// * `should_gen_docs` - True if the generated API contains the documentation from the metadata.
///
/// **Note:** This is a wrapper over [RuntimeGenerator] for static metadata use-cases.
pub fn generate_runtime_api_from_url(
Expand All @@ -104,6 +108,7 @@ pub fn generate_runtime_api_from_url(
derives: DerivesRegistry,
type_substitutes: TypeSubstitutes,
crate_path: CratePath,
should_gen_docs: bool,
) -> TokenStream2 {
let bytes = fetch_metadata_bytes_blocking(url)
.unwrap_or_else(|e| abort_call_site!("Failed to obtain metadata: {}", e));
Expand All @@ -114,6 +119,7 @@ pub fn generate_runtime_api_from_url(
derives,
type_substitutes,
crate_path,
should_gen_docs,
)
}

Expand All @@ -126,6 +132,7 @@ pub fn generate_runtime_api_from_url(
/// * `derives` - Provide custom derives for the generated types.
/// * `type_substitutes` - Provide custom type substitutes.
/// * `crate_path` - Path to the `subxt` crate.
/// * `should_gen_docs` - True if the generated API contains the documentation from the metadata.
///
/// **Note:** This is a wrapper over [RuntimeGenerator] for static metadata use-cases.
pub fn generate_runtime_api_from_bytes(
Expand All @@ -134,12 +141,19 @@ pub fn generate_runtime_api_from_bytes(
derives: DerivesRegistry,
type_substitutes: TypeSubstitutes,
crate_path: CratePath,
should_gen_docs: bool,
) -> TokenStream2 {
let metadata = frame_metadata::RuntimeMetadataPrefixed::decode(&mut &bytes[..])
.unwrap_or_else(|e| abort_call_site!("Failed to decode metadata: {}", e));

let generator = RuntimeGenerator::new(metadata);
generator.generate_runtime(item_mod, derives, type_substitutes, crate_path)
generator.generate_runtime(
item_mod,
derives,
type_substitutes,
crate_path,
should_gen_docs,
)
}

/// Create the API for interacting with a Substrate runtime.
Expand Down Expand Up @@ -172,6 +186,7 @@ impl RuntimeGenerator {
derives: DerivesRegistry,
type_substitutes: TypeSubstitutes,
crate_path: CratePath,
should_gen_docs: bool,
) -> TokenStream2 {
let item_mod_attrs = item_mod.attrs.clone();
let item_mod_ir = ir::ItemMod::from(item_mod);
Expand All @@ -183,6 +198,7 @@ impl RuntimeGenerator {
type_substitutes,
derives.clone(),
crate_path.clone(),
should_gen_docs,
);
let types_mod = type_gen.generate_types_mod();
let types_mod_ident = types_mod.ident();
Expand Down Expand Up @@ -218,17 +234,24 @@ impl RuntimeGenerator {
pallet,
types_mod_ident,
&crate_path,
should_gen_docs,
);

let event =
events::generate_events(&type_gen, pallet, types_mod_ident, &crate_path);
let event = events::generate_events(
&type_gen,
pallet,
types_mod_ident,
&crate_path,
should_gen_docs,
);

let storage_mod = storage::generate_storage(
&self.metadata,
&type_gen,
pallet,
types_mod_ident,
&crate_path,
should_gen_docs,
);

let constants_mod = constants::generate_constants(
Expand All @@ -237,6 +260,7 @@ impl RuntimeGenerator {
pallet,
types_mod_ident,
&crate_path,
should_gen_docs,
);

quote! {
Expand Down Expand Up @@ -376,6 +400,7 @@ pub fn generate_structs_from_variants<F>(
variant_to_struct_name: F,
error_message_type_name: &str,
crate_path: &CratePath,
should_gen_docs: bool,
) -> Vec<(String, CompositeDef)>
where
F: Fn(&str) -> std::borrow::Cow<str>,
Expand All @@ -393,14 +418,15 @@ where
&[],
type_gen,
);
let docs = should_gen_docs.then_some(var.docs()).unwrap_or_default();
let struct_def = CompositeDef::struct_def(
&ty,
struct_name.as_ref(),
Default::default(),
fields,
Some(parse_quote!(pub)),
type_gen,
var.docs(),
docs,
crate_path,
);
(var.name().to_string(), struct_def)
Expand Down
19 changes: 15 additions & 4 deletions codegen/src/api/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ pub fn generate_storage(
pallet: &PalletMetadata<PortableForm>,
types_mod_ident: &syn::Ident,
crate_path: &CratePath,
should_gen_docs: bool,
) -> TokenStream2 {
let storage = if let Some(ref storage) = pallet.storage {
storage
Expand All @@ -52,7 +53,14 @@ pub fn generate_storage(
.entries
.iter()
.map(|entry| {
generate_storage_entry_fns(metadata, type_gen, pallet, entry, crate_path)
generate_storage_entry_fns(
metadata,
type_gen,
pallet,
entry,
crate_path,
should_gen_docs,
)
})
.collect();

Expand All @@ -75,6 +83,7 @@ fn generate_storage_entry_fns(
pallet: &PalletMetadata<PortableForm>,
storage_entry: &StorageEntryMetadata<PortableForm>,
crate_path: &CratePath,
should_gen_docs: bool,
) -> TokenStream2 {
let (fields, key_impl) = match storage_entry.ty {
StorageEntryType::Plain(_) => (vec![], quote!(vec![])),
Expand Down Expand Up @@ -183,7 +192,9 @@ fn generate_storage_entry_fns(
let storage_entry_value_ty = type_gen.resolve_type_path(storage_entry_ty.id());

let docs = &storage_entry.docs;
let docs_token = quote! { #( #[doc = #docs ] )* };
let docs = should_gen_docs
.then_some(quote! { #( #[doc = #docs ] )* })
.unwrap_or_default();

let key_args = fields.iter().map(|(field_name, field_type)| {
// The field type is translated from `std::vec::Vec<T>` to `[T]`. We apply
Expand Down Expand Up @@ -224,7 +235,7 @@ fn generate_storage_entry_fns(
let root_entry_fn = if is_map_type {
let fn_name_root = format_ident!("{}_root", fn_name);
quote! (
#docs_token
#docs
pub fn #fn_name_root(
&self,
) -> #crate_path::storage::address::StaticStorageAddress::<#crate_path::metadata::DecodeStaticType<#storage_entry_value_ty>, (), #is_defaultable_type, #is_iterable_type> {
Expand All @@ -242,7 +253,7 @@ fn generate_storage_entry_fns(

quote! {
// Access a specific value from a storage entry
#docs_token
#docs
pub fn #fn_name(
&self,
#( #key_args, )*
Expand Down
4 changes: 3 additions & 1 deletion codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@
//! let substs = TypeSubstitutes::new(&CratePath::default());
//! // Generate the Runtime API.
//! let generator = subxt_codegen::RuntimeGenerator::new(metadata);
//! let runtime_api = generator.generate_runtime(item_mod, derives, substs, CratePath::default());
//! // Include metadata documentation in the Runtime API.
//! let generate_docs = true;
//! let runtime_api = generator.generate_runtime(item_mod, derives, substs, CratePath::default(), generate_docs);
//! println!("{}", runtime_api);
//! ```
Expand Down
Loading

0 comments on commit 5320ca9

Please sign in to comment.