codegen: Generate type aliases for better API ergonomics (#1249)

* codegen: Generate type alias for storage return types

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

* codegen: Generate type alias for call function arguments

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

* testing: Update polkadot.rs code from commit 2e2a75ff81

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

* codegen: Type aliases for runtime API parameters

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

* codegen: Type alias for runtime apis output

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

* storage: Change path of the aliased module

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

* codegen: Adjust module indentation

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

* codegen: Do not alias for api::runtime_types with unresolved generics

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

* codegen: Fix and document runtime API alias generation

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

* Update artifacts

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

* Update cargo.lock file

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

* codegen: Generate composite structs with alias unnamed fields

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

* testing: Update polkadot.rs file

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

* codegen: Alias storage unnamed parameters

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

* Update polkadot.rs

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

* examples: Change polkadot to rococo runtime

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

* codegen: Fix compiling tests in the codegen crate

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

* codegen: Extend storage test with alias module

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

* cli/tests: Adjust exepcted commands to the latest metadata

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

* codegen: Remove missleading comment and docs

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

* codegen: Ensure unique names for generated runtime API types

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

* codegen/tests: Test expected runtime type generation

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

* codegen/tests: Check duplicate params in runtime APIs

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

* codegen/tests: Test colliding names of type aliases and parameters

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

* Fix clippy

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

* codegen: Separate alias module from struct definition

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

* Update polkadot.rs

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

* codegen: Remove outdated docs from composite def

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

---------

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
This commit is contained in:
Alexandru Vasile
2023-12-08 15:07:50 +02:00
committed by GitHub
parent f06a95d687
commit c976d0dbce
15 changed files with 23437 additions and 20542 deletions
+60 -3
View File
@@ -358,12 +358,13 @@ impl RuntimeGenerator {
/// Return a vector of tuples of variant names and corresponding struct definitions.
pub fn generate_structs_from_variants<F>(
type_gen: &TypeGenerator,
types_mod_ident: &syn::Ident,
type_id: u32,
variant_to_struct_name: F,
error_message_type_name: &str,
crate_path: &syn::Path,
should_gen_docs: bool,
) -> Result<Vec<(String, CompositeDef)>, CodegenError>
) -> Result<Vec<(String, CompositeDef, TypeAliases)>, CodegenError>
where
F: Fn(&str) -> std::borrow::Cow<str>,
{
@@ -386,19 +387,75 @@ where
type_gen,
)?;
let alias_module_name = format_ident!("{}", var.name.to_snake_case());
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,
fields.clone(),
Some(parse_quote!(pub)),
type_gen,
docs,
crate_path,
Some(alias_module_name.clone()),
)?;
Ok((var.name.to_string(), struct_def))
let type_aliases = TypeAliases::new(fields, types_mod_ident.clone(), alias_module_name);
Ok((var.name.to_string(), struct_def, type_aliases))
})
.collect()
}
/// Generate the type aliases from a set of enum / struct definitions.
///
/// The type aliases are used to make the generated code more readable.
#[derive(Debug)]
pub struct TypeAliases {
fields: CompositeDefFields,
types_mod_ident: syn::Ident,
mod_name: syn::Ident,
}
impl TypeAliases {
pub fn new(
fields: CompositeDefFields,
types_mod_ident: syn::Ident,
mod_name: syn::Ident,
) -> Self {
TypeAliases {
fields,
types_mod_ident,
mod_name,
}
}
}
impl quote::ToTokens for TypeAliases {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let has_fields = matches!(&self.fields, CompositeDefFields::Named(fields) if !fields.is_empty())
|| matches!(&self.fields, CompositeDefFields::Unnamed(fields) if !fields.is_empty());
if !has_fields {
return;
}
let visibility: syn::Visibility = parse_quote!(pub);
let aliases = self
.fields
.to_type_aliases_tokens(Some(visibility).as_ref());
let mod_name = &self.mod_name;
let types_mod_ident = &self.types_mod_ident;
tokens.extend(quote! {
pub mod #mod_name {
use super::#types_mod_ident;
#aliases
}
})
}
}