Run cargo fmt on the whole code base (#9394)

* Run cargo fmt on the whole code base

* Second run

* Add CI check

* Fix compilation

* More unnecessary braces

* Handle weights

* Use --all

* Use correct attributes...

* Fix UI tests

* AHHHHHHHHH

* 🤦

* Docs

* Fix compilation

* 🤷

* Please stop

* 🤦 x 2

* More

* make rustfmt.toml consistent with polkadot

Co-authored-by: André Silva <andrerfosilva@gmail.com>
This commit is contained in:
Bastian Köcher
2021-07-21 16:32:32 +02:00
committed by GitHub
parent d451c38c1c
commit 7b56ab15b4
1010 changed files with 53339 additions and 51208 deletions
@@ -26,8 +26,10 @@
//! 3. The [`PassByEnum`](derive.PassByInner.html) derive macro for implementing `PassBy` with `Enum`.
//! 4. The [`PassByInner`](derive.PassByInner.html) derive macro for implementing `PassBy` with `Inner`.
use syn::{parse_macro_input, ItemTrait, DeriveInput, Result, Token};
use syn::parse::{Parse, ParseStream};
use syn::{
parse::{Parse, ParseStream},
parse_macro_input, DeriveInput, ItemTrait, Result, Token,
};
mod pass_by;
mod runtime_interface;
@@ -35,7 +37,7 @@ mod utils;
struct Options {
wasm_only: bool,
tracing: bool
tracing: bool,
}
impl Options {
@@ -86,17 +88,21 @@ pub fn runtime_interface(
#[proc_macro_derive(PassByCodec)]
pub fn pass_by_codec(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input = parse_macro_input!(input as DeriveInput);
pass_by::codec_derive_impl(input).unwrap_or_else(|e| e.to_compile_error()).into()
pass_by::codec_derive_impl(input)
.unwrap_or_else(|e| e.to_compile_error())
.into()
}
#[proc_macro_derive(PassByInner)]
pub fn pass_by_inner(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input = parse_macro_input!(input as DeriveInput);
pass_by::inner_derive_impl(input).unwrap_or_else(|e| e.to_compile_error()).into()
pass_by::inner_derive_impl(input)
.unwrap_or_else(|e| e.to_compile_error())
.into()
}
#[proc_macro_derive(PassByEnum)]
pub fn pass_by_enum(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input = parse_macro_input!(input as DeriveInput);
pass_by::enum_derive_impl(input).unwrap_or_else(|e| e.to_compile_error()).into()
}
}
@@ -22,7 +22,7 @@
use crate::utils::{generate_crate_access, generate_runtime_interface_include};
use syn::{DeriveInput, Result, Generics, parse_quote};
use syn::{parse_quote, DeriveInput, Generics, Result};
use quote::quote;
@@ -53,7 +53,7 @@ pub fn derive_impl(mut input: DeriveInput) -> Result<TokenStream> {
fn add_trait_bounds(generics: &mut Generics) {
let crate_ = generate_crate_access();
generics.type_params_mut()
generics
.type_params_mut()
.for_each(|type_param| type_param.bounds.push(parse_quote!(#crate_::codec::Codec)));
}
@@ -21,11 +21,11 @@
use crate::utils::{generate_crate_access, generate_runtime_interface_include};
use syn::{DeriveInput, Result, Data, Fields, Error, Ident};
use syn::{Data, DeriveInput, Error, Fields, Ident, Result};
use quote::quote;
use proc_macro2::{TokenStream, Span};
use proc_macro2::{Span, TokenStream};
/// The derive implementation for `PassBy` with `Enum`.
pub fn derive_impl(input: DeriveInput) -> Result<TokenStream> {
@@ -81,22 +81,21 @@ pub fn derive_impl(input: DeriveInput) -> Result<TokenStream> {
/// enum or a variant is not an unit.
fn get_enum_field_idents<'a>(data: &'a Data) -> Result<impl Iterator<Item = Result<&'a Ident>>> {
match data {
Data::Enum(d) => {
Data::Enum(d) =>
if d.variants.len() <= 256 {
Ok(
d.variants.iter().map(|v| if let Fields::Unit = v.fields {
Ok(d.variants.iter().map(|v| {
if let Fields::Unit = v.fields {
Ok(&v.ident)
} else {
Err(Error::new(
Span::call_site(),
"`PassByEnum` only supports unit variants.",
))
})
)
}
}))
} else {
Err(Error::new(Span::call_site(), "`PassByEnum` only supports `256` variants."))
}
},
_ => Err(Error::new(Span::call_site(), "`PassByEnum` only supports enums as input type."))
},
_ => Err(Error::new(Span::call_site(), "`PassByEnum` only supports enums as input type.")),
}
}
@@ -22,11 +22,11 @@
use crate::utils::{generate_crate_access, generate_runtime_interface_include};
use syn::{DeriveInput, Result, Generics, parse_quote, Type, Data, Error, Fields, Ident};
use syn::{parse_quote, Data, DeriveInput, Error, Fields, Generics, Ident, Result, Type};
use quote::quote;
use proc_macro2::{TokenStream, Span};
use proc_macro2::{Span, TokenStream};
/// The derive implementation for `PassBy` with `Inner` and `PassByInner`.
pub fn derive_impl(mut input: DeriveInput) -> Result<TokenStream> {
@@ -80,7 +80,8 @@ pub fn derive_impl(mut input: DeriveInput) -> Result<TokenStream> {
fn add_trait_bounds(generics: &mut Generics) {
let crate_ = generate_crate_access();
generics.type_params_mut()
generics
.type_params_mut()
.for_each(|type_param| type_param.bounds.push(parse_quote!(#crate_::RIType)));
}
@@ -97,15 +98,13 @@ fn extract_inner_ty_and_name(data: &Data) -> Result<(Type, Option<Ident>)> {
Fields::Unnamed(ref unnamed) if unnamed.unnamed.len() == 1 => {
let field = &unnamed.unnamed[0];
return Ok((field.ty.clone(), field.ident.clone()))
}
},
_ => {},
}
}
Err(
Error::new(
Span::call_site(),
"Only newtype/one field structs are supported by `PassByInner`!",
)
)
Err(Error::new(
Span::call_site(),
"Only newtype/one field structs are supported by `PassByInner`!",
))
}
@@ -30,15 +30,16 @@
//! are feature-gated, so that one is compiled for the native and the other for the wasm side.
use crate::utils::{
generate_crate_access, create_exchangeable_host_function_ident, get_function_arguments,
get_function_argument_names, get_runtime_interface, create_function_ident_with_version,
create_exchangeable_host_function_ident, create_function_ident_with_version,
generate_crate_access, get_function_argument_names, get_function_arguments,
get_runtime_interface,
};
use syn::{
Ident, ItemTrait, TraitItemMethod, FnArg, Signature, Result, spanned::Spanned, parse_quote,
parse_quote, spanned::Spanned, FnArg, Ident, ItemTrait, Result, Signature, TraitItemMethod,
};
use proc_macro2::{TokenStream, Span};
use proc_macro2::{Span, TokenStream};
use quote::{quote, quote_spanned};
@@ -51,21 +52,22 @@ pub fn generate(trait_def: &ItemTrait, is_wasm_only: bool, tracing: bool) -> Res
let runtime_interface = get_runtime_interface(trait_def)?;
// latest version dispatch
let token_stream: Result<TokenStream> = runtime_interface.latest_versions()
.try_fold(
TokenStream::new(),
|mut t, (latest_version, method)| {
t.extend(function_for_method(method, latest_version, is_wasm_only)?);
Ok(t)
}
);
let token_stream: Result<TokenStream> = runtime_interface.latest_versions().try_fold(
TokenStream::new(),
|mut t, (latest_version, method)| {
t.extend(function_for_method(method, latest_version, is_wasm_only)?);
Ok(t)
},
);
// earlier versions compatibility dispatch (only std variant)
let result: Result<TokenStream> = runtime_interface.all_versions().try_fold(token_stream?, |mut t, (version, method)|
{
t.extend(function_std_impl(trait_name, method, version, is_wasm_only, tracing)?);
Ok(t)
});
let result: Result<TokenStream> =
runtime_interface
.all_versions()
.try_fold(token_stream?, |mut t, (version, method)| {
t.extend(function_std_impl(trait_name, method, version, is_wasm_only, tracing)?);
Ok(t)
});
result
}
@@ -76,21 +78,16 @@ fn function_for_method(
latest_version: u32,
is_wasm_only: bool,
) -> Result<TokenStream> {
let std_impl = if !is_wasm_only {
function_std_latest_impl(method, latest_version)?
} else {
quote!()
};
let std_impl =
if !is_wasm_only { function_std_latest_impl(method, latest_version)? } else { quote!() };
let no_std_impl = function_no_std_impl(method)?;
Ok(
quote! {
#std_impl
Ok(quote! {
#std_impl
#no_std_impl
}
)
#no_std_impl
})
}
/// Generates the bare function implementation for `cfg(not(feature = "std"))`.
@@ -102,31 +99,27 @@ fn function_no_std_impl(method: &TraitItemMethod) -> Result<TokenStream> {
let return_value = &method.sig.output;
let attrs = method.attrs.iter().filter(|a| !a.path.is_ident("version"));
Ok(
quote! {
#[cfg(not(feature = "std"))]
#( #attrs )*
pub fn #function_name( #( #args, )* ) #return_value {
// Call the host function
#host_function_name.get()( #( #arg_names, )* )
}
Ok(quote! {
#[cfg(not(feature = "std"))]
#( #attrs )*
pub fn #function_name( #( #args, )* ) #return_value {
// Call the host function
#host_function_name.get()( #( #arg_names, )* )
}
)
})
}
/// Generate call to latest function version for `cfg((feature = "std")`
///
/// This should generate simple `fn func(..) { func_version_<latest_version>(..) }`.
fn function_std_latest_impl(
method: &TraitItemMethod,
latest_version: u32,
) -> Result<TokenStream> {
fn function_std_latest_impl(method: &TraitItemMethod, latest_version: u32) -> Result<TokenStream> {
let function_name = &method.sig.ident;
let args = get_function_arguments(&method.sig).map(FnArg::Typed);
let arg_names = get_function_argument_names(&method.sig).collect::<Vec<_>>();
let return_value = &method.sig.output;
let attrs = method.attrs.iter().filter(|a| !a.path.is_ident("version"));
let latest_function_name = create_function_ident_with_version(&method.sig.ident, latest_version);
let latest_function_name =
create_function_ident_with_version(&method.sig.ident, latest_version);
Ok(quote_spanned! { method.span() =>
#[cfg(feature = "std")]
@@ -153,17 +146,16 @@ fn function_std_impl(
let crate_ = generate_crate_access();
let args = get_function_arguments(&method.sig).map(FnArg::Typed).chain(
// Add the function context as last parameter when this is a wasm only interface.
iter::from_fn(||
iter::from_fn(|| {
if is_wasm_only {
Some(
parse_quote!(
mut __function_context__: &mut dyn #crate_::sp_wasm_interface::FunctionContext
)
)
Some(parse_quote!(
mut __function_context__: &mut dyn #crate_::sp_wasm_interface::FunctionContext
))
} else {
None
}
).take(1),
})
.take(1),
);
let return_value = &method.sig.output;
let attrs = method.attrs.iter().filter(|a| !a.path.is_ident("version"));
@@ -179,15 +171,13 @@ fn function_std_impl(
)
};
Ok(
quote_spanned! { method.span() =>
#[cfg(feature = "std")]
#( #attrs )*
fn #function_name( #( #args, )* ) #return_value {
#call_to_trait
}
Ok(quote_spanned! { method.span() =>
#[cfg(feature = "std")]
#( #attrs )*
fn #function_name( #( #args, )* ) #return_value {
#call_to_trait
}
)
})
}
/// Generate the call to the interface trait.
@@ -199,10 +189,8 @@ fn generate_call_to_trait(
) -> TokenStream {
let crate_ = generate_crate_access();
let method_name = create_function_ident_with_version(&method.sig.ident, version);
let expect_msg = format!(
"`{}` called outside of an Externalities-provided environment.",
method_name,
);
let expect_msg =
format!("`{}` called outside of an Externalities-provided environment.", method_name,);
let arg_names = get_function_argument_names(&method.sig);
if takes_self_argument(&method.sig) {
@@ -22,35 +22,36 @@
//! executor. These implementations call the bare function interface.
use crate::utils::{
generate_crate_access, create_host_function_ident, get_function_argument_names,
get_function_argument_types_without_ref, get_function_argument_types_ref_and_mut,
get_function_argument_names_and_types_without_ref, get_function_arguments,
get_function_argument_types, create_exchangeable_host_function_ident, get_runtime_interface,
create_function_ident_with_version,
create_exchangeable_host_function_ident, create_function_ident_with_version,
create_host_function_ident, generate_crate_access, get_function_argument_names,
get_function_argument_names_and_types_without_ref, get_function_argument_types,
get_function_argument_types_ref_and_mut, get_function_argument_types_without_ref,
get_function_arguments, get_runtime_interface,
};
use syn::{
ItemTrait, TraitItemMethod, Result, ReturnType, Ident, Pat, Error, Signature, spanned::Spanned,
spanned::Spanned, Error, Ident, ItemTrait, Pat, Result, ReturnType, Signature, TraitItemMethod,
};
use proc_macro2::{TokenStream, Span};
use proc_macro2::{Span, TokenStream};
use quote::{quote, ToTokens};
use inflector::Inflector;
use std::iter::{Iterator, self};
use std::iter::{self, Iterator};
/// Generate the extern host functions for wasm and the `HostFunctions` struct that provides the
/// implementations for the host functions on the host.
pub fn generate(trait_def: &ItemTrait, is_wasm_only: bool) -> Result<TokenStream> {
let trait_name = &trait_def.ident;
let extern_host_function_impls = get_runtime_interface(trait_def)?
.latest_versions()
.try_fold(TokenStream::new(), |mut t, (version, method)| {
let extern_host_function_impls = get_runtime_interface(trait_def)?.latest_versions().try_fold(
TokenStream::new(),
|mut t, (version, method)| {
t.extend(generate_extern_host_function(method, version, trait_name)?);
Ok::<_, Error>(t)
})?;
},
)?;
let exchangeable_host_functions = get_runtime_interface(trait_def)?
.latest_versions()
.try_fold(TokenStream::new(), |mut t, (_, m)| {
@@ -59,27 +60,29 @@ pub fn generate(trait_def: &ItemTrait, is_wasm_only: bool) -> Result<TokenStream
})?;
let host_functions_struct = generate_host_functions_struct(trait_def, is_wasm_only)?;
Ok(
quote! {
/// The implementations of the extern host functions. This special implementation module
/// is required to change the extern host functions signature to
/// `unsafe fn name(args) -> ret` to make the function implementations exchangeable.
#[cfg(not(feature = "std"))]
mod extern_host_function_impls {
use super::*;
Ok(quote! {
/// The implementations of the extern host functions. This special implementation module
/// is required to change the extern host functions signature to
/// `unsafe fn name(args) -> ret` to make the function implementations exchangeable.
#[cfg(not(feature = "std"))]
mod extern_host_function_impls {
use super::*;
#extern_host_function_impls
}
#exchangeable_host_functions
#host_functions_struct
#extern_host_function_impls
}
)
#exchangeable_host_functions
#host_functions_struct
})
}
/// Generate the extern host function for the given method.
fn generate_extern_host_function(method: &TraitItemMethod, version: u32, trait_name: &Ident) -> Result<TokenStream> {
fn generate_extern_host_function(
method: &TraitItemMethod,
version: u32,
trait_name: &Ident,
) -> Result<TokenStream> {
let crate_ = generate_crate_access();
let args = get_function_arguments(&method.sig);
let arg_types = get_function_argument_types_without_ref(&method.sig);
@@ -106,33 +109,31 @@ fn generate_extern_host_function(method: &TraitItemMethod, version: u32, trait_n
ReturnType::Default => quote!(),
ReturnType::Type(_, ref ty) => quote! {
<#ty as #crate_::wasm::FromFFIValue>::from_ffi_value(result)
}
},
};
Ok(
quote! {
#[doc = #doc_string]
pub fn #function ( #( #args ),* ) #return_value {
extern "C" {
/// The extern function.
pub fn #ext_function (
#( #arg_names: <#arg_types as #crate_::RIType>::FFIType ),*
) #ffi_return_value;
}
// Generate all wrapped ffi values.
#(
let #arg_names2 = <#arg_types2 as #crate_::wasm::IntoFFIValue>::into_ffi_value(
&#arg_names2,
);
)*
let result = unsafe { #ext_function( #( #arg_names3.get() ),* ) };
#convert_return_value
Ok(quote! {
#[doc = #doc_string]
pub fn #function ( #( #args ),* ) #return_value {
extern "C" {
/// The extern function.
pub fn #ext_function (
#( #arg_names: <#arg_types as #crate_::RIType>::FFIType ),*
) #ffi_return_value;
}
// Generate all wrapped ffi values.
#(
let #arg_names2 = <#arg_types2 as #crate_::wasm::IntoFFIValue>::into_ffi_value(
&#arg_names2,
);
)*
let result = unsafe { #ext_function( #( #arg_names3.get() ),* ) };
#convert_return_value
}
)
})
}
/// Generate the host exchangeable function for the given method.
@@ -144,44 +145,43 @@ fn generate_exchangeable_host_function(method: &TraitItemMethod) -> Result<Token
let doc_string = format!(" Exchangeable host function used by [`{}`].", method.sig.ident);
let output = &method.sig.output;
Ok(
quote! {
#[cfg(not(feature = "std"))]
#[allow(non_upper_case_globals)]
#[doc = #doc_string]
pub static #exchangeable_function : #crate_::wasm::ExchangeableFunction<
fn ( #( #arg_types ),* ) #output
> = #crate_::wasm::ExchangeableFunction::new(extern_host_function_impls::#function);
}
)
Ok(quote! {
#[cfg(not(feature = "std"))]
#[allow(non_upper_case_globals)]
#[doc = #doc_string]
pub static #exchangeable_function : #crate_::wasm::ExchangeableFunction<
fn ( #( #arg_types ),* ) #output
> = #crate_::wasm::ExchangeableFunction::new(extern_host_function_impls::#function);
})
}
/// Generate the `HostFunctions` struct that implements `wasm-interface::HostFunctions` to provide
/// implementations for the extern host functions.
fn generate_host_functions_struct(trait_def: &ItemTrait, is_wasm_only: bool) -> Result<TokenStream> {
fn generate_host_functions_struct(
trait_def: &ItemTrait,
is_wasm_only: bool,
) -> Result<TokenStream> {
let crate_ = generate_crate_access();
let host_functions = get_runtime_interface(trait_def)?
.all_versions()
.map(|(version, method)|
.map(|(version, method)| {
generate_host_function_implementation(&trait_def.ident, method, version, is_wasm_only)
)
})
.collect::<Result<Vec<_>>>()?;
Ok(
quote! {
/// Provides implementations for the extern host functions.
#[cfg(feature = "std")]
pub struct HostFunctions;
Ok(quote! {
/// Provides implementations for the extern host functions.
#[cfg(feature = "std")]
pub struct HostFunctions;
#[cfg(feature = "std")]
impl #crate_::sp_wasm_interface::HostFunctions for HostFunctions {
fn host_functions() -> Vec<&'static dyn #crate_::sp_wasm_interface::Function> {
vec![ #( #host_functions ),* ]
}
#[cfg(feature = "std")]
impl #crate_::sp_wasm_interface::HostFunctions for HostFunctions {
fn host_functions() -> Vec<&'static dyn #crate_::sp_wasm_interface::Function> {
vec![ #( #host_functions ),* ]
}
}
)
})
}
/// Generates the host function struct that implements `wasm_interface::Function` and returns a static
@@ -199,71 +199,65 @@ fn generate_host_function_implementation(
let struct_name = Ident::new(&name.to_pascal_case(), Span::call_site());
let crate_ = generate_crate_access();
let signature = generate_wasm_interface_signature_for_host_function(&method.sig)?;
let wasm_to_ffi_values = generate_wasm_to_ffi_values(
&method.sig,
trait_name,
).collect::<Result<Vec<_>>>()?;
let wasm_to_ffi_values =
generate_wasm_to_ffi_values(&method.sig, trait_name).collect::<Result<Vec<_>>>()?;
let ffi_to_host_values = generate_ffi_to_host_value(&method.sig).collect::<Result<Vec<_>>>()?;
let host_function_call = generate_host_function_call(&method.sig, version, is_wasm_only);
let into_preallocated_ffi_value = generate_into_preallocated_ffi_value(&method.sig)?;
let convert_return_value = generate_return_value_into_wasm_value(&method.sig);
Ok(
quote! {
{
struct #struct_name;
Ok(quote! {
{
struct #struct_name;
impl #crate_::sp_wasm_interface::Function for #struct_name {
fn name(&self) -> &str {
#name
}
fn signature(&self) -> #crate_::sp_wasm_interface::Signature {
#signature
}
fn execute(
&self,
__function_context__: &mut dyn #crate_::sp_wasm_interface::FunctionContext,
args: &mut dyn Iterator<Item = #crate_::sp_wasm_interface::Value>,
) -> std::result::Result<Option<#crate_::sp_wasm_interface::Value>, String> {
#( #wasm_to_ffi_values )*
#( #ffi_to_host_values )*
#host_function_call
#into_preallocated_ffi_value
#convert_return_value
}
impl #crate_::sp_wasm_interface::Function for #struct_name {
fn name(&self) -> &str {
#name
}
&#struct_name as &dyn #crate_::sp_wasm_interface::Function
fn signature(&self) -> #crate_::sp_wasm_interface::Signature {
#signature
}
fn execute(
&self,
__function_context__: &mut dyn #crate_::sp_wasm_interface::FunctionContext,
args: &mut dyn Iterator<Item = #crate_::sp_wasm_interface::Value>,
) -> std::result::Result<Option<#crate_::sp_wasm_interface::Value>, String> {
#( #wasm_to_ffi_values )*
#( #ffi_to_host_values )*
#host_function_call
#into_preallocated_ffi_value
#convert_return_value
}
}
&#struct_name as &dyn #crate_::sp_wasm_interface::Function
}
)
})
}
/// Generate the `wasm_interface::Signature` for the given host function `sig`.
fn generate_wasm_interface_signature_for_host_function(sig: &Signature) -> Result<TokenStream> {
let crate_ = generate_crate_access();
let return_value = match &sig.output {
ReturnType::Type(_, ty) =>
quote! {
Some( <<#ty as #crate_::RIType>::FFIType as #crate_::sp_wasm_interface::IntoValue>::VALUE_TYPE )
},
ReturnType::Default => quote!( None ),
ReturnType::Type(_, ty) => quote! {
Some( <<#ty as #crate_::RIType>::FFIType as #crate_::sp_wasm_interface::IntoValue>::VALUE_TYPE )
},
ReturnType::Default => quote!(None),
};
let arg_types = get_function_argument_types_without_ref(sig)
.map(|ty| quote! {
<<#ty as #crate_::RIType>::FFIType as #crate_::sp_wasm_interface::IntoValue>::VALUE_TYPE
});
Ok(
let arg_types = get_function_argument_types_without_ref(sig).map(|ty| {
quote! {
#crate_::sp_wasm_interface::Signature {
args: std::borrow::Cow::Borrowed(&[ #( #arg_types ),* ][..]),
return_value: #return_value,
}
<<#ty as #crate_::RIType>::FFIType as #crate_::sp_wasm_interface::IntoValue>::VALUE_TYPE
}
)
});
Ok(quote! {
#crate_::sp_wasm_interface::Signature {
args: std::borrow::Cow::Borrowed(&[ #( #arg_types ),* ][..]),
return_value: #return_value,
}
})
}
/// Generate the code that converts the wasm values given to `HostFunctions::execute` into the FFI
@@ -279,24 +273,23 @@ fn generate_wasm_to_ffi_values<'a>(
function_name,
);
get_function_argument_names_and_types_without_ref(sig)
.map(move |(name, ty)| {
let try_from_error = format!(
"Could not instantiate `{}` from wasm value while executing `{}` from interface `{}`!",
name.to_token_stream(),
function_name,
trait_name,
);
get_function_argument_names_and_types_without_ref(sig).map(move |(name, ty)| {
let try_from_error = format!(
"Could not instantiate `{}` from wasm value while executing `{}` from interface `{}`!",
name.to_token_stream(),
function_name,
trait_name,
);
let var_name = generate_ffi_value_var_name(&name)?;
let var_name = generate_ffi_value_var_name(&name)?;
Ok(quote! {
let val = args.next().ok_or_else(|| #error_message)?;
let #var_name = <
<#ty as #crate_::RIType>::FFIType as #crate_::sp_wasm_interface::TryFromValue
>::try_from_value(val).ok_or_else(|| #try_from_error)?;
})
Ok(quote! {
let val = args.next().ok_or_else(|| #error_message)?;
let #var_name = <
<#ty as #crate_::RIType>::FFIType as #crate_::sp_wasm_interface::TryFromValue
>::try_from_value(val).ok_or_else(|| #try_from_error)?;
})
})
}
/// Generate the code to convert the ffi values on the host to the host values using `FromFFIValue`.
@@ -311,14 +304,12 @@ fn generate_ffi_to_host_value<'a>(
.map(move |((name, ty), mut_access)| {
let ffi_value_var_name = generate_ffi_value_var_name(&name)?;
Ok(
quote! {
let #mut_access #name = <#ty as #crate_::host::FromFFIValue>::from_ffi_value(
__function_context__,
#ffi_value_var_name,
)?;
}
)
Ok(quote! {
let #mut_access #name = <#ty as #crate_::host::FromFFIValue>::from_ffi_value(
__function_context__,
#ffi_value_var_name,
)?;
})
})
}
@@ -326,19 +317,17 @@ fn generate_ffi_to_host_value<'a>(
fn generate_host_function_call(sig: &Signature, version: u32, is_wasm_only: bool) -> TokenStream {
let host_function_name = create_function_ident_with_version(&sig.ident, version);
let result_var_name = generate_host_function_result_var_name(&sig.ident);
let ref_and_mut = get_function_argument_types_ref_and_mut(sig).map(|ram|
ram.map(|(vr, vm)| quote!(#vr #vm))
);
let ref_and_mut =
get_function_argument_types_ref_and_mut(sig).map(|ram| ram.map(|(vr, vm)| quote!(#vr #vm)));
let names = get_function_argument_names(sig);
let var_access = names.zip(ref_and_mut)
.map(|(n, ref_and_mut)| {
quote!( #ref_and_mut #n )
})
let var_access = names
.zip(ref_and_mut)
.map(|(n, ref_and_mut)| quote!( #ref_and_mut #n ))
// If this is a wasm only interface, we add the function context as last parameter.
.chain(
iter::from_fn(|| if is_wasm_only { Some(quote!(__function_context__)) } else { None })
.take(1)
.take(1),
);
quote! {
@@ -354,16 +343,15 @@ fn generate_host_function_result_var_name(name: &Ident) -> Ident {
/// Generate the variable name that stores the FFI value.
fn generate_ffi_value_var_name(pat: &Pat) -> Result<Ident> {
match pat {
Pat::Ident(pat_ident) => {
Pat::Ident(pat_ident) =>
if let Some(by_ref) = pat_ident.by_ref {
Err(Error::new(by_ref.span(), "`ref` not supported!"))
} else if let Some(sub_pattern) = &pat_ident.subpat {
Err(Error::new(sub_pattern.0.span(), "Not supported!"))
} else {
Ok(Ident::new(&format!("{}_ffi_value", pat_ident.ident), Span::call_site()))
}
}
_ => Err(Error::new(pat.span(), "Not supported as variable name!"))
},
_ => Err(Error::new(pat.span(), "Not supported as variable name!")),
}
}
@@ -373,25 +361,23 @@ fn generate_ffi_value_var_name(pat: &Pat) -> Result<Ident> {
/// that the type implements `IntoPreAllocatedFFIValue`.
fn generate_into_preallocated_ffi_value(sig: &Signature) -> Result<TokenStream> {
let crate_ = generate_crate_access();
let ref_and_mut = get_function_argument_types_ref_and_mut(sig).map(|ram|
ram.and_then(|(vr, vm)| vm.map(|v| (vr, v)))
);
let ref_and_mut = get_function_argument_types_ref_and_mut(sig)
.map(|ram| ram.and_then(|(vr, vm)| vm.map(|v| (vr, v))));
let names_and_types = get_function_argument_names_and_types_without_ref(sig);
ref_and_mut.zip(names_and_types)
ref_and_mut
.zip(names_and_types)
.filter_map(|(ram, (name, ty))| ram.map(|_| (name, ty)))
.map(|(name, ty)| {
let ffi_var_name = generate_ffi_value_var_name(&name)?;
Ok(
quote! {
<#ty as #crate_::host::IntoPreallocatedFFIValue>::into_preallocated_ffi_value(
#name,
__function_context__,
#ffi_var_name,
)?;
}
)
Ok(quote! {
<#ty as #crate_::host::IntoPreallocatedFFIValue>::into_preallocated_ffi_value(
#name,
__function_context__,
#ffi_var_name,
)?;
})
})
.collect()
}
@@ -401,7 +387,7 @@ fn generate_return_value_into_wasm_value(sig: &Signature) -> TokenStream {
let crate_ = generate_crate_access();
match &sig.output {
ReturnType::Default => quote!( Ok(None) ),
ReturnType::Default => quote!(Ok(None)),
ReturnType::Type(_, ty) => {
let result_var_name = generate_host_function_result_var_name(&sig.ident);
@@ -411,6 +397,6 @@ fn generate_return_value_into_wasm_value(sig: &Signature) -> TokenStream {
__function_context__,
).map(#crate_::sp_wasm_interface::IntoValue::into_value).map(Some)
}
}
},
}
}
@@ -19,15 +19,14 @@
//! default implementations and implements the trait for `&mut dyn Externalities`.
use crate::utils::{
generate_crate_access,
get_function_argument_types_without_ref,
get_runtime_interface,
create_function_ident_with_version,
create_function_ident_with_version, generate_crate_access,
get_function_argument_types_without_ref, get_runtime_interface,
};
use syn::{
ItemTrait, TraitItemMethod, Result, Error, fold::{self, Fold}, spanned::Spanned,
Visibility, Receiver, Type, Generics,
fold::{self, Fold},
spanned::Spanned,
Error, Generics, ItemTrait, Receiver, Result, TraitItemMethod, Type, Visibility,
};
use proc_macro2::TokenStream;
@@ -40,13 +39,11 @@ pub fn process(trait_def: &ItemTrait, is_wasm_only: bool) -> Result<TokenStream>
let impl_trait = impl_trait_for_externalities(trait_def, is_wasm_only)?;
let essential_trait_def = declare_essential_trait(trait_def)?;
Ok(
quote! {
#impl_trait
Ok(quote! {
#impl_trait
#essential_trait_def
}
)
#essential_trait_def
})
}
/// Converts the given trait definition into the essential trait definition without method
@@ -66,12 +63,10 @@ impl ToEssentialTraitDef {
let mut errors = self.errors;
let methods = self.methods;
if let Some(first_error) = errors.pop() {
Err(
errors.into_iter().fold(first_error, |mut o, n| {
o.combine(n);
o
})
)
Err(errors.into_iter().fold(first_error, |mut o, n| {
o.combine(n);
o
}))
} else {
Ok(methods)
}
@@ -101,12 +96,12 @@ impl Fold for ToEssentialTraitDef {
}
let arg_types = get_function_argument_types_without_ref(&method.sig);
arg_types.filter_map(|ty|
match *ty {
arg_types
.filter_map(|ty| match *ty {
Type::ImplTrait(impl_trait) => Some(impl_trait),
_ => None
}
).for_each(|invalid| self.push_error(&invalid, "`impl Trait` syntax not supported."));
_ => None,
})
.for_each(|invalid| self.push_error(&invalid, "`impl Trait` syntax not supported."));
self.error_on_generic_parameters(&method.sig.generics);
@@ -145,13 +140,11 @@ fn declare_essential_trait(trait_def: &ItemTrait) -> Result<TokenStream> {
}
let methods = folder.into_methods()?;
Ok(
quote! {
trait #trait_ {
#( #methods )*
}
Ok(quote! {
trait #trait_ {
#( #methods )*
}
)
})
}
/// Implements the given trait definition for `dyn Externalities`.
@@ -172,12 +165,10 @@ fn impl_trait_for_externalities(trait_def: &ItemTrait, is_wasm_only: bool) -> Re
quote!( &mut dyn #crate_::Externalities )
};
Ok(
quote! {
#[cfg(feature = "std")]
impl #trait_ for #impl_type {
#( #methods )*
}
Ok(quote! {
#[cfg(feature = "std")]
impl #trait_ for #impl_type {
#( #methods )*
}
)
})
}
@@ -17,16 +17,19 @@
//! Util function used by this crate.
use proc_macro2::{TokenStream, Span};
use proc_macro2::{Span, TokenStream};
use syn::{
Ident, Error, Signature, Pat, PatType, FnArg, Type, token, TraitItemMethod, ItemTrait,
TraitItem, parse_quote, spanned::Spanned, Result, Meta, NestedMeta, Lit, Attribute,
parse_quote, spanned::Spanned, token, Attribute, Error, FnArg, Ident, ItemTrait, Lit, Meta,
NestedMeta, Pat, PatType, Result, Signature, TraitItem, TraitItemMethod, Type,
};
use proc_macro_crate::{crate_name, FoundCrate};
use std::{env, collections::{BTreeMap, btree_map::Entry}};
use std::{
collections::{btree_map::Entry, BTreeMap},
env,
};
use quote::quote;
@@ -53,8 +56,9 @@ impl<'a> RuntimeInterfaceFunction<'a> {
pub fn latest_version(&self) -> (u32, &TraitItemMethod) {
(
self.latest_version,
self.versions.get(&self.latest_version)
.expect("If latest_version has a value, the key with this value is in the versions; qed")
self.versions.get(&self.latest_version).expect(
"If latest_version has a value, the key with this value is in the versions; qed",
),
)
}
}
@@ -70,9 +74,12 @@ impl<'a> RuntimeInterface<'a> {
}
pub fn all_versions(&self) -> impl Iterator<Item = (u32, &TraitItemMethod)> {
self.items.iter().flat_map(|(_, item)| item.versions.iter()).map(|(v, i)| (*v, *i))
self.items
.iter()
.flat_map(|(_, item)| item.versions.iter())
.map(|(v, i)| (*v, *i))
}
}
}
/// Generates the include for the runtime-interface crate.
pub fn generate_runtime_interface_include() -> TokenStream {
@@ -88,16 +95,16 @@ pub fn generate_runtime_interface_include() -> TokenStream {
Err(e) => {
let err = Error::new(Span::call_site(), e).to_compile_error();
quote!( #err )
}
},
}
}
/// Generates the access to the `sp-runtime-interface` crate.
pub fn generate_crate_access() -> TokenStream {
if env::var("CARGO_PKG_NAME").unwrap() == "sp-runtime-interface" {
quote!( sp_runtime_interface )
quote!(sp_runtime_interface)
} else {
quote!( proc_macro_runtime_interface )
quote!(proc_macro_runtime_interface)
}
}
@@ -109,26 +116,14 @@ pub fn create_exchangeable_host_function_ident(name: &Ident) -> Ident {
/// Create the host function identifier for the given function name.
pub fn create_host_function_ident(name: &Ident, version: u32, trait_name: &Ident) -> Ident {
Ident::new(
&format!(
"ext_{}_{}_version_{}",
trait_name.to_string().to_snake_case(),
name,
version,
),
&format!("ext_{}_{}_version_{}", trait_name.to_string().to_snake_case(), name, version,),
Span::call_site(),
)
}
/// Create the host function identifier for the given function name.
pub fn create_function_ident_with_version(name: &Ident, version: u32) -> Ident {
Ident::new(
&format!(
"{}_version_{}",
name,
version,
),
Span::call_site(),
)
Ident::new(&format!("{}_version_{}", name, version,), Span::call_site())
}
/// Returns the function arguments of the given `Signature`, minus any `self` arguments.
@@ -143,10 +138,8 @@ pub fn get_function_arguments<'a>(sig: &'a Signature) -> impl Iterator<Item = Pa
.map(|(i, arg)| {
let mut res = arg.clone();
if let Pat::Wild(wild) = &*arg.pat {
let ident = Ident::new(
&format!("__runtime_interface_generated_{}_", i),
wild.span(),
);
let ident =
Ident::new(&format!("__runtime_interface_generated_{}_", i), wild.span());
res.pat = Box::new(parse_quote!( #ident ))
}
@@ -170,12 +163,10 @@ pub fn get_function_argument_types<'a>(sig: &'a Signature) -> impl Iterator<Item
pub fn get_function_argument_types_without_ref<'a>(
sig: &'a Signature,
) -> impl Iterator<Item = Box<Type>> + 'a {
get_function_arguments(sig)
.map(|pt| pt.ty)
.map(|ty| match *ty {
Type::Reference(type_ref) => type_ref.elem,
_ => ty,
})
get_function_arguments(sig).map(|pt| pt.ty).map(|ty| match *ty {
Type::Reference(type_ref) => type_ref.elem,
_ => ty,
})
}
/// Returns the function argument names and types, minus any `self`. If any of the arguments
@@ -183,11 +174,10 @@ pub fn get_function_argument_types_without_ref<'a>(
pub fn get_function_argument_names_and_types_without_ref<'a>(
sig: &'a Signature,
) -> impl Iterator<Item = (Box<Pat>, Box<Type>)> + 'a {
get_function_arguments(sig)
.map(|pt| match *pt.ty {
Type::Reference(type_ref) => (pt.pat, type_ref.elem),
_ => (pt.pat, pt.ty),
})
get_function_arguments(sig).map(|pt| match *pt.ty {
Type::Reference(type_ref) => (pt.pat, type_ref.elem),
_ => (pt.pat, pt.ty),
})
}
/// Returns the `&`/`&mut` for all function argument types, minus the `self` arg. If a function
@@ -195,23 +185,18 @@ pub fn get_function_argument_names_and_types_without_ref<'a>(
pub fn get_function_argument_types_ref_and_mut<'a>(
sig: &'a Signature,
) -> impl Iterator<Item = Option<(token::And, Option<token::Mut>)>> + 'a {
get_function_arguments(sig)
.map(|pt| pt.ty)
.map(|ty| match *ty {
Type::Reference(type_ref) => Some((type_ref.and_token, type_ref.mutability)),
_ => None,
})
get_function_arguments(sig).map(|pt| pt.ty).map(|ty| match *ty {
Type::Reference(type_ref) => Some((type_ref.and_token, type_ref.mutability)),
_ => None,
})
}
/// Returns an iterator over all trait methods for the given trait definition.
fn get_trait_methods<'a>(trait_def: &'a ItemTrait) -> impl Iterator<Item = &'a TraitItemMethod> {
trait_def
.items
.iter()
.filter_map(|i| match i {
TraitItem::Method(ref method) => Some(method),
_ => None,
})
trait_def.items.iter().filter_map(|i| match i {
TraitItem::Method(ref method) => Some(method),
_ => None,
})
}
/// Parse version attribute.
@@ -221,36 +206,34 @@ fn parse_version_attribute(version: &Attribute) -> Result<u32> {
let meta = version.parse_meta()?;
let err = Err(Error::new(
meta.span(),
"Unexpected `version` attribute. The supported format is `#[version(1)]`",
)
);
meta.span(),
"Unexpected `version` attribute. The supported format is `#[version(1)]`",
));
match meta {
Meta::List(list) => {
Meta::List(list) =>
if list.nested.len() != 1 {
err
} else if let Some(NestedMeta::Lit(Lit::Int(i))) = list.nested.first() {
i.base10_parse()
} else {
err
}
},
},
_ => err,
}
}
/// Return item version (`#[version(X)]`) attribute, if present.
fn get_item_version(item: &TraitItemMethod) -> Result<Option<u32>> {
item.attrs.iter().find(|attr| attr.path.is_ident("version"))
item.attrs
.iter()
.find(|attr| attr.path.is_ident("version"))
.map(|attr| parse_version_attribute(attr))
.transpose()
}
/// Returns all runtime interface members, with versions.
pub fn get_runtime_interface<'a>(trait_def: &'a ItemTrait)
-> Result<RuntimeInterface<'a>>
{
pub fn get_runtime_interface<'a>(trait_def: &'a ItemTrait) -> Result<RuntimeInterface<'a>> {
let mut functions: BTreeMap<syn::Ident, RuntimeInterfaceFunction<'a>> = BTreeMap::new();
for item in get_trait_methods(trait_def) {
@@ -258,25 +241,26 @@ pub fn get_runtime_interface<'a>(trait_def: &'a ItemTrait)
let version = get_item_version(item)?.unwrap_or(1);
match functions.entry(name.clone()) {
Entry::Vacant(entry) => { entry.insert(RuntimeInterfaceFunction::new(version, item)); },
Entry::Vacant(entry) => {
entry.insert(RuntimeInterfaceFunction::new(version, item));
},
Entry::Occupied(mut entry) => {
if let Some(existing_item) = entry.get().versions.get(&version) {
let mut err = Error::new(
item.span(),
"Duplicated version attribute",
);
let mut err = Error::new(item.span(), "Duplicated version attribute");
err.combine(Error::new(
existing_item.span(),
"Previous version with the same number defined here",
));
return Err(err);
return Err(err)
}
let interface_item = entry.get_mut();
if interface_item.latest_version < version { interface_item.latest_version = version; }
if interface_item.latest_version < version {
interface_item.latest_version = version;
}
interface_item.versions.insert(version, item);
}
},
}
}
@@ -286,8 +270,11 @@ pub fn get_runtime_interface<'a>(trait_def: &'a ItemTrait)
if next_expected != *version {
return Err(Error::new(
item.span(),
format!("Unexpected version attribute: missing version '{}' for this function", next_expected),
));
format!(
"Unexpected version attribute: missing version '{}' for this function",
next_expected
),
))
}
next_expected += 1;
}