mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-11 14:11:09 +00:00
Update syn, proc-macro2 and quote to 1.x (#4028)
This commit is contained in:
@@ -19,6 +19,7 @@ use crate::utils::{
|
||||
fold_fn_decl_for_client_side, unwrap_or_error, extract_parameter_names_types_and_borrows,
|
||||
generate_native_call_generator_fn_name, return_type_extract_type,
|
||||
generate_method_runtime_api_impl_name, generate_call_api_at_fn_name, prefix_function_with_trait,
|
||||
replace_wild_card_parameter_names,
|
||||
};
|
||||
|
||||
use proc_macro2::{TokenStream, Span};
|
||||
@@ -27,9 +28,8 @@ use quote::quote;
|
||||
|
||||
use syn::{
|
||||
spanned::Spanned, parse_macro_input, parse::{Parse, ParseStream, Result, Error}, ReturnType,
|
||||
fold::{self, Fold}, parse_quote, ItemTrait, Generics, GenericParam, Attribute, FnArg,
|
||||
visit::{Visit, self}, Pat, TraitBound, Meta, NestedMeta, Lit, TraitItem, Ident, Type,
|
||||
TraitItemMethod
|
||||
fold::{self, Fold}, parse_quote, ItemTrait, Generics, GenericParam, Attribute, FnArg, Type,
|
||||
visit::{Visit, self}, TraitBound, Meta, NestedMeta, Lit, TraitItem, Ident, TraitItemMethod,
|
||||
};
|
||||
|
||||
use std::collections::HashMap;
|
||||
@@ -95,9 +95,9 @@ impl Parse for RuntimeApiDecls {
|
||||
fn extend_generics_with_block(generics: &mut Generics) {
|
||||
let c = generate_crate_access(HIDDEN_INCLUDES_ID);
|
||||
|
||||
generics.lt_token = Some(parse_quote!(<));
|
||||
generics.lt_token = Some(Default::default());
|
||||
generics.params.insert(0, parse_quote!( Block: #c::runtime_api::BlockT ));
|
||||
generics.gt_token = Some(parse_quote!(>));
|
||||
generics.gt_token = Some(Default::default());
|
||||
}
|
||||
|
||||
/// Remove all attributes from the vector that are supported by us in the declaration of a runtime
|
||||
@@ -182,7 +182,7 @@ fn generate_native_call_generators(decl: &ItemTrait) -> Result<TokenStream> {
|
||||
let crate_ = generate_crate_access(HIDDEN_INCLUDES_ID);
|
||||
|
||||
// Auxiliary function that is used to convert between types that use different block types.
|
||||
// The function expects that both a convertable by encoding the one and decoding the other.
|
||||
// The function expects that both are convertible by encoding the one and decoding the other.
|
||||
result.push(quote!(
|
||||
#[cfg(any(feature = "std", test))]
|
||||
fn convert_between_block_types
|
||||
@@ -198,10 +198,10 @@ fn generate_native_call_generators(decl: &ItemTrait) -> Result<TokenStream> {
|
||||
|
||||
// Generate a native call generator for each function of the given trait.
|
||||
for fn_ in fns {
|
||||
let params = extract_parameter_names_types_and_borrows(&fn_.decl)?;
|
||||
let params = extract_parameter_names_types_and_borrows(&fn_)?;
|
||||
let trait_fn_name = &fn_.ident;
|
||||
let fn_name = generate_native_call_generator_fn_name(&fn_.ident);
|
||||
let output = return_type_replace_block_with_node_block(fn_.decl.output.clone());
|
||||
let output = return_type_replace_block_with_node_block(fn_.output.clone());
|
||||
let output_ty = return_type_extract_type(&output);
|
||||
let output = quote!( std::result::Result<#output_ty, String> );
|
||||
|
||||
@@ -217,7 +217,7 @@ fn generate_native_call_generators(decl: &ItemTrait) -> Result<TokenStream> {
|
||||
});
|
||||
// Same as for the input types, we need to check if we also need to convert the output,
|
||||
// before returning it.
|
||||
let output_conversion = if return_type_is_using_block(&fn_.decl.output) {
|
||||
let output_conversion = if return_type_is_using_block(&fn_.output) {
|
||||
quote!(
|
||||
convert_between_block_types(
|
||||
&res,
|
||||
@@ -234,22 +234,21 @@ fn generate_native_call_generators(decl: &ItemTrait) -> Result<TokenStream> {
|
||||
// the user. Otherwise if it is not using the block, we don't need to add anything.
|
||||
let input_borrows = params
|
||||
.iter()
|
||||
.map(|v| if type_is_using_block(&v.1) { v.2.clone() } else { quote!() });
|
||||
.map(|v| if type_is_using_block(&v.1) { v.2.clone() } else { None });
|
||||
|
||||
// Replace all `Block` with `NodeBlock`, add `'a` lifetime to references and collect
|
||||
// all the function inputs.
|
||||
let fn_inputs = fn_
|
||||
.decl
|
||||
.inputs
|
||||
.iter()
|
||||
.map(|v| fn_arg_replace_block_with_node_block(v.clone()))
|
||||
.map(|v| match v {
|
||||
FnArg::Captured(ref arg) => {
|
||||
FnArg::Typed(ref arg) => {
|
||||
let mut arg = arg.clone();
|
||||
if let Type::Reference(ref mut r) = arg.ty {
|
||||
if let Type::Reference(ref mut r) = *arg.ty {
|
||||
r.lifetime = Some(parse_quote!( 'a ));
|
||||
}
|
||||
FnArg::Captured(arg)
|
||||
FnArg::Typed(arg)
|
||||
},
|
||||
r => r.clone(),
|
||||
});
|
||||
@@ -310,15 +309,15 @@ fn parse_renamed_attribute(renamed: &Attribute) -> Result<(String, u32)> {
|
||||
} else {
|
||||
let mut itr = list.nested.iter();
|
||||
let old_name = match itr.next() {
|
||||
Some(NestedMeta::Literal(Lit::Str(i))) => {
|
||||
Some(NestedMeta::Lit(Lit::Str(i))) => {
|
||||
i.value()
|
||||
},
|
||||
_ => return err,
|
||||
};
|
||||
|
||||
let version = match itr.next() {
|
||||
Some(NestedMeta::Literal(Lit::Int(i))) => {
|
||||
i.value() as u32
|
||||
Some(NestedMeta::Lit(Lit::Int(i))) => {
|
||||
i.base10_parse()?
|
||||
},
|
||||
_ => return err,
|
||||
};
|
||||
@@ -488,6 +487,8 @@ fn generate_runtime_decls(decls: &[ItemTrait]) -> TokenStream {
|
||||
if remove_supported_attributes(&mut method.attrs).contains_key(CHANGED_IN_ATTRIBUTE) {
|
||||
None
|
||||
} else {
|
||||
// Make sure we replace all the wild card parameter names.
|
||||
replace_wild_card_parameter_names(&mut method.sig);
|
||||
Some(TraitItem::Method(method.clone()))
|
||||
}
|
||||
}
|
||||
@@ -565,7 +566,7 @@ impl<'a> ToClientSideDecl<'a> {
|
||||
let context_arg: syn::FnArg = parse_quote!( context: #crate_::runtime_api::ExecutionContext );
|
||||
let mut fn_decl_ctx = self.create_method_decl(method, quote!( context ));
|
||||
fn_decl_ctx.sig.ident = Ident::new(&format!("{}_with_context", &fn_decl_ctx.sig.ident), Span::call_site());
|
||||
fn_decl_ctx.sig.decl.inputs.insert(2, context_arg);
|
||||
fn_decl_ctx.sig.inputs.insert(2, context_arg);
|
||||
|
||||
fn_decl_ctx
|
||||
}
|
||||
@@ -577,12 +578,12 @@ impl<'a> ToClientSideDecl<'a> {
|
||||
return None;
|
||||
}
|
||||
|
||||
let fn_decl = &method.sig.decl;
|
||||
let ret_type = return_type_extract_type(&fn_decl.output);
|
||||
let fn_sig = &method.sig;
|
||||
let ret_type = return_type_extract_type(&fn_sig.output);
|
||||
|
||||
// Get types and if the value is borrowed from all parameters.
|
||||
// If there is an error, we push it as the block to the user.
|
||||
let param_types = match extract_parameter_names_types_and_borrows(fn_decl) {
|
||||
let param_types = match extract_parameter_names_types_and_borrows(fn_sig) {
|
||||
Ok(res) => res.into_iter().map(|v| {
|
||||
let ty = v.1;
|
||||
let borrow = v.2;
|
||||
@@ -614,8 +615,12 @@ impl<'a> ToClientSideDecl<'a> {
|
||||
/// Takes the method declared by the user and creates the declaration we require for the runtime
|
||||
/// api client side. This method will call by default the `method_runtime_api_impl` for doing
|
||||
/// the actual call into the runtime.
|
||||
fn create_method_decl(&mut self, mut method: TraitItemMethod, context: TokenStream) -> TraitItemMethod {
|
||||
let params = match extract_parameter_names_types_and_borrows(&method.sig.decl) {
|
||||
fn create_method_decl(
|
||||
&mut self,
|
||||
mut method: TraitItemMethod,
|
||||
context: TokenStream,
|
||||
) -> TraitItemMethod {
|
||||
let params = match extract_parameter_names_types_and_borrows(&method.sig) {
|
||||
Ok(res) => res.into_iter().map(|v| v.0).collect::<Vec<_>>(),
|
||||
Err(e) => {
|
||||
self.errors.push(e.to_compile_error());
|
||||
@@ -623,13 +628,10 @@ impl<'a> ToClientSideDecl<'a> {
|
||||
}
|
||||
};
|
||||
let params2 = params.clone();
|
||||
let ret_type = return_type_extract_type(&method.sig.decl.output);
|
||||
let ret_type = return_type_extract_type(&method.sig.output);
|
||||
|
||||
fold_fn_decl_for_client_side(&mut method.sig, &self.block_id, &self.crate_);
|
||||
|
||||
method.sig.decl = fold_fn_decl_for_client_side(
|
||||
method.sig.decl.clone(),
|
||||
&self.block_id,
|
||||
&self.crate_
|
||||
);
|
||||
let name_impl = generate_method_runtime_api_impl_name(&self.trait_, &method.sig.ident);
|
||||
let crate_ = self.crate_;
|
||||
|
||||
@@ -650,7 +652,7 @@ impl<'a> ToClientSideDecl<'a> {
|
||||
|
||||
let ident = Ident::new(
|
||||
&format!("{}_before_version_{}", method.sig.ident, version),
|
||||
method.sig.ident.span()
|
||||
method.sig.ident.span(),
|
||||
);
|
||||
method.sig.ident = ident;
|
||||
method.attrs.push(parse_quote!( #[deprecated] ));
|
||||
@@ -674,22 +676,26 @@ impl<'a> ToClientSideDecl<'a> {
|
||||
let runtime_api_impl_params_encoded =
|
||||
#crate_::runtime_api::Encode::encode(&( #( &#params ),* ));
|
||||
|
||||
self.#name_impl(at, #context, #param_tuple, runtime_api_impl_params_encoded)
|
||||
.and_then(|r|
|
||||
match r {
|
||||
#crate_::runtime_api::NativeOrEncoded::Native(n) => {
|
||||
#native_handling
|
||||
},
|
||||
#crate_::runtime_api::NativeOrEncoded::Encoded(r) => {
|
||||
<#ret_type as #crate_::runtime_api::Decode>::decode(&mut &r[..])
|
||||
.map_err(|err|
|
||||
#crate_::error::Error::CallResultDecode(
|
||||
#function_name, err
|
||||
).into()
|
||||
)
|
||||
}
|
||||
self.#name_impl(
|
||||
__runtime_api_at_param__,
|
||||
#context,
|
||||
#param_tuple,
|
||||
runtime_api_impl_params_encoded,
|
||||
).and_then(|r|
|
||||
match r {
|
||||
#crate_::runtime_api::NativeOrEncoded::Native(n) => {
|
||||
#native_handling
|
||||
},
|
||||
#crate_::runtime_api::NativeOrEncoded::Encoded(r) => {
|
||||
<#ret_type as #crate_::runtime_api::Decode>::decode(&mut &r[..])
|
||||
.map_err(|err|
|
||||
#crate_::error::Error::CallResultDecode(
|
||||
#function_name, err
|
||||
).into()
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -745,15 +751,12 @@ fn parse_runtime_api_version(version: &Attribute) -> Result<u64> {
|
||||
|
||||
match meta {
|
||||
Meta::List(list) => {
|
||||
if list.nested.len() > 1 && list.nested.is_empty() {
|
||||
if list.nested.len() != 1 {
|
||||
err
|
||||
} else if let Some(NestedMeta::Lit(Lit::Int(i))) = list.nested.first() {
|
||||
i.base10_parse()
|
||||
} else {
|
||||
match list.nested.first().as_ref().map(|v| v.value()) {
|
||||
Some(NestedMeta::Literal(Lit::Int(i))) => {
|
||||
Ok(i.value())
|
||||
},
|
||||
_ => err,
|
||||
}
|
||||
err
|
||||
}
|
||||
},
|
||||
_ => err,
|
||||
@@ -848,32 +851,8 @@ struct CheckTraitDecl {
|
||||
|
||||
impl<'ast> Visit<'ast> for CheckTraitDecl {
|
||||
fn visit_fn_arg(&mut self, input: &'ast FnArg) {
|
||||
match input {
|
||||
FnArg::Captured(ref arg) => {
|
||||
match arg.pat {
|
||||
Pat::Ident(ref pat) if pat.ident == "at" => {
|
||||
self.errors.push(
|
||||
Error::new(
|
||||
pat.span(),
|
||||
"`decl_runtime_apis!` adds automatically a parameter \
|
||||
`at: &BlockId<Block>`. Please rename/remove your parameter."
|
||||
)
|
||||
)
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
},
|
||||
FnArg::SelfRef(_) | FnArg::SelfValue(_) => {
|
||||
self.errors.push(Error::new(input.span(), "Self values are not supported."))
|
||||
}
|
||||
_ => {
|
||||
self.errors.push(
|
||||
Error::new(
|
||||
input.span(),
|
||||
"Only function arguments in the form `pat: type` are supported."
|
||||
)
|
||||
)
|
||||
}
|
||||
if let FnArg::Receiver(_) = input {
|
||||
self.errors.push(Error::new(input.span(), "`self` as argument not supported."))
|
||||
}
|
||||
|
||||
visit::visit_fn_arg(self, input);
|
||||
@@ -897,7 +876,7 @@ impl<'ast> Visit<'ast> for CheckTraitDecl {
|
||||
}
|
||||
|
||||
fn visit_trait_bound(&mut self, input: &'ast TraitBound) {
|
||||
if let Some(last_ident) = input.path.segments.last().map(|v| &v.value().ident) {
|
||||
if let Some(last_ident) = input.path.segments.last().map(|v| &v.ident) {
|
||||
if last_ident == "BlockT" || last_ident == BLOCK_GENERIC_IDENT {
|
||||
self.errors.push(
|
||||
Error::new(
|
||||
|
||||
@@ -26,7 +26,7 @@ use proc_macro2::{Span, TokenStream};
|
||||
use quote::quote;
|
||||
|
||||
use syn::{
|
||||
spanned::Spanned, parse_macro_input, Ident, Type, ItemImpl, MethodSig, Path,
|
||||
spanned::Spanned, parse_macro_input, Ident, Type, ItemImpl, Path, Signature,
|
||||
ImplItem, parse::{Parse, ParseStream, Result, Error}, PathArguments, GenericArgument, TypePath,
|
||||
fold::{self, Fold}, parse_quote
|
||||
};
|
||||
@@ -56,12 +56,12 @@ impl Parse for RuntimeApiImpls {
|
||||
/// Generates the call to the implementation of the requested function.
|
||||
/// The generated code includes decoding of the input arguments and encoding of the output.
|
||||
fn generate_impl_call(
|
||||
signature: &MethodSig,
|
||||
signature: &Signature,
|
||||
runtime: &Type,
|
||||
input: &Ident,
|
||||
impl_trait: &Path
|
||||
) -> Result<TokenStream> {
|
||||
let params = extract_parameter_names_types_and_borrows(&signature.decl)?;
|
||||
let params = extract_parameter_names_types_and_borrows(signature)?;
|
||||
|
||||
let c = generate_crate_access(HIDDEN_INCLUDES_ID);
|
||||
let c_iter = iter::repeat(&c);
|
||||
@@ -110,23 +110,20 @@ fn extract_impl_trait<'a>(impl_: &'a ItemImpl) -> Result<&'a Path> {
|
||||
/// Extracts the runtime block identifier.
|
||||
fn extract_runtime_block_ident(trait_: &Path) -> Result<&TypePath> {
|
||||
let span = trait_.span();
|
||||
let segment = trait_
|
||||
let generics = trait_
|
||||
.segments
|
||||
.last()
|
||||
.ok_or_else(
|
||||
|| Error::new(span, "Empty path not supported")
|
||||
)?;
|
||||
let generics = segment.value();
|
||||
.ok_or_else(|| Error::new(span, "Empty path not supported"))?;
|
||||
|
||||
match &generics.arguments {
|
||||
PathArguments::AngleBracketed(ref args) => {
|
||||
args.args.first().and_then(|v| match v.value() {
|
||||
GenericArgument::Type(Type::Path(block)) => Some(block),
|
||||
args.args.first().and_then(|v| match v {
|
||||
GenericArgument::Type(Type::Path(ref block)) => Some(block),
|
||||
_ => None
|
||||
}).ok_or_else(|| Error::new(args.span(), "Missing `Block` generic parameter."))
|
||||
},
|
||||
PathArguments::None => {
|
||||
let span = trait_.segments.last().as_ref().unwrap().value().span();
|
||||
let span = trait_.segments.last().as_ref().unwrap().span();
|
||||
Err(Error::new(span, "Missing `Block` generic parameter."))
|
||||
},
|
||||
PathArguments::Parenthesized(_) => {
|
||||
@@ -149,7 +146,6 @@ fn generate_impl_calls(
|
||||
.segments
|
||||
.last()
|
||||
.ok_or_else(|| Error::new(impl_trait_path.span(), "Empty trait path not possible!"))?
|
||||
.value()
|
||||
.ident;
|
||||
|
||||
for item in &impl_.items {
|
||||
@@ -363,7 +359,7 @@ fn generate_runtime_api_base_structures(impls: &[ItemImpl]) -> Result<TokenStrea
|
||||
res
|
||||
}
|
||||
|
||||
fn commit_on_ok<R, E>(&self, res: &::std::result::Result<R, E>) {
|
||||
fn commit_on_ok<R, E>(&self, res: &std::result::Result<R, E>) {
|
||||
if *self.commit_on_success.borrow() {
|
||||
if res.is_err() {
|
||||
self.changes.borrow_mut().discard_prospective();
|
||||
@@ -385,7 +381,6 @@ fn extend_with_runtime_decl_path(mut trait_: Path) -> Path {
|
||||
.last()
|
||||
.as_ref()
|
||||
.expect("Trait path should always contain at least one item; qed")
|
||||
.value()
|
||||
.ident;
|
||||
|
||||
generate_runtime_mod_name_for_trait(trait_name)
|
||||
@@ -455,16 +450,16 @@ impl<'a> Fold for ApiRuntimeImplToApiRuntimeApiImpl<'a> {
|
||||
let block_id = self.node_block_id;
|
||||
|
||||
// Generate the access to the native parameters
|
||||
let param_tuple_access = if input.sig.decl.inputs.len() == 1 {
|
||||
let param_tuple_access = if input.sig.inputs.len() == 1 {
|
||||
vec![ quote!( p ) ]
|
||||
} else {
|
||||
input.sig.decl.inputs.iter().enumerate().map(|(i, _)| {
|
||||
input.sig.inputs.iter().enumerate().map(|(i, _)| {
|
||||
let i = syn::Index::from(i);
|
||||
quote!( p.#i )
|
||||
}).collect::<Vec<_>>()
|
||||
};
|
||||
|
||||
let (param_types, error) = match extract_parameter_names_types_and_borrows(&input.sig.decl) {
|
||||
let (param_types, error) = match extract_parameter_names_types_and_borrows(&input.sig) {
|
||||
Ok(res) => (
|
||||
res.into_iter().map(|v| {
|
||||
let ty = v.1;
|
||||
@@ -476,18 +471,23 @@ impl<'a> Fold for ApiRuntimeImplToApiRuntimeApiImpl<'a> {
|
||||
Err(e) => (Vec::new(), Some(e.to_compile_error())),
|
||||
};
|
||||
|
||||
let context_arg: syn::FnArg = parse_quote!( context: #crate_::runtime_api::ExecutionContext );
|
||||
|
||||
// Rewrite the input parameters.
|
||||
input.sig.decl.inputs = parse_quote! {
|
||||
&self, at: &#block_id, #context_arg, params: Option<( #( #param_types ),* )>, params_encoded: Vec<u8>
|
||||
input.sig.inputs = parse_quote! {
|
||||
&self,
|
||||
at: &#block_id,
|
||||
context: #crate_::runtime_api::ExecutionContext,
|
||||
params: Option<( #( #param_types ),* )>,
|
||||
params_encoded: Vec<u8>,
|
||||
};
|
||||
|
||||
input.sig.ident = generate_method_runtime_api_impl_name(&self.impl_trait, &input.sig.ident);
|
||||
let ret_type = return_type_extract_type(&input.sig.decl.output);
|
||||
input.sig.ident = generate_method_runtime_api_impl_name(
|
||||
&self.impl_trait,
|
||||
&input.sig.ident,
|
||||
);
|
||||
let ret_type = return_type_extract_type(&input.sig.output);
|
||||
|
||||
// Generate the correct return type.
|
||||
input.sig.decl.output = parse_quote!(
|
||||
input.sig.output = parse_quote!(
|
||||
-> #crate_::error::Result<#crate_::runtime_api::NativeOrEncoded<#ret_type>>
|
||||
);
|
||||
|
||||
@@ -495,7 +495,7 @@ impl<'a> Fold for ApiRuntimeImplToApiRuntimeApiImpl<'a> {
|
||||
parse_quote!(
|
||||
{
|
||||
// Get the error to the user (if we have one).
|
||||
#( #error )*
|
||||
#error
|
||||
|
||||
self.call_api_at(
|
||||
|call_runtime_at, core_api, changes, initialized_block, recorder| {
|
||||
@@ -556,7 +556,7 @@ fn generate_api_impl_for_runtime_api(impls: &[ItemImpl]) -> Result<TokenStream>
|
||||
.segments
|
||||
.last()
|
||||
.ok_or_else(|| Error::new(impl_trait_path.span(), "Empty trait path not possible!"))?
|
||||
.into_value();
|
||||
.clone();
|
||||
let runtime_block = extract_runtime_block_ident(impl_trait_path)?;
|
||||
let (node_block, node_block_id) = generate_node_block_and_block_id_ty(&impl_.self_ty);
|
||||
let runtime_type = &impl_.self_ty;
|
||||
|
||||
@@ -15,9 +15,15 @@
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use proc_macro2::{TokenStream, Span};
|
||||
use syn::{Result, Ident, FnDecl, parse_quote, Type, Pat, spanned::Spanned, FnArg, Error};
|
||||
|
||||
use syn::{
|
||||
Result, Ident, Signature, parse_quote, Type, Pat, spanned::Spanned, FnArg, Error, token::And,
|
||||
};
|
||||
|
||||
use quote::quote;
|
||||
|
||||
use std::env;
|
||||
|
||||
use proc_macro_crate::crate_name;
|
||||
|
||||
/// Unwrap the given result, if it is an error, `compile_error!` will be generated.
|
||||
@@ -82,23 +88,33 @@ pub fn return_type_extract_type(rt: &syn::ReturnType) -> Type {
|
||||
}
|
||||
}
|
||||
|
||||
/// Fold the given `FnDecl` to make it usable on the client side.
|
||||
/// Replace the `_` (wild card) parameter names in the given signature with unique identifiers.
|
||||
pub fn replace_wild_card_parameter_names(input: &mut Signature) {
|
||||
let mut generated_pattern_counter = 0;
|
||||
input.inputs.iter_mut().for_each(|arg| if let FnArg::Typed(arg) = arg {
|
||||
arg.pat = Box::new(
|
||||
generate_unique_pattern((*arg.pat).clone(), &mut generated_pattern_counter),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// Fold the given `Signature` to make it usable on the client side.
|
||||
pub fn fold_fn_decl_for_client_side(
|
||||
mut input: FnDecl,
|
||||
input: &mut Signature,
|
||||
block_id: &TokenStream,
|
||||
crate_: &TokenStream
|
||||
) -> FnDecl {
|
||||
crate_: &TokenStream,
|
||||
) {
|
||||
replace_wild_card_parameter_names(input);
|
||||
|
||||
// Add `&self, at:& BlockId` as parameters to each function at the beginning.
|
||||
input.inputs.insert(0, parse_quote!( at: &#block_id ));
|
||||
input.inputs.insert(0, parse_quote!( __runtime_api_at_param__: &#block_id ));
|
||||
input.inputs.insert(0, parse_quote!( &self ));
|
||||
|
||||
// Wrap the output in a `Result`
|
||||
input.output = {
|
||||
let ty = return_type_extract_type(&input.output);
|
||||
parse_quote!( -> ::std::result::Result<#ty, #crate_::error::Error> )
|
||||
parse_quote!( -> std::result::Result<#ty, #crate_::error::Error> )
|
||||
};
|
||||
|
||||
input
|
||||
}
|
||||
|
||||
/// Generate an unique pattern based on the given counter, if the given pattern is a `_`.
|
||||
@@ -106,8 +122,8 @@ pub fn generate_unique_pattern(pat: Pat, counter: &mut u32) -> Pat {
|
||||
match pat {
|
||||
Pat::Wild(_) => {
|
||||
let generated_name = Ident::new(
|
||||
&format!("runtime_api_generated_name_{}", counter),
|
||||
pat.span()
|
||||
&format!("__runtime_api_generated_name_{}__", counter),
|
||||
pat.span(),
|
||||
);
|
||||
*counter += 1;
|
||||
|
||||
@@ -115,38 +131,31 @@ pub fn generate_unique_pattern(pat: Pat, counter: &mut u32) -> Pat {
|
||||
},
|
||||
_ => pat,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Extracts the name, the type and `&` or ``(if it is a reference or not)
|
||||
/// for each parameter in the given function declaration.
|
||||
pub fn extract_parameter_names_types_and_borrows(fn_decl: &FnDecl)
|
||||
-> Result<Vec<(Pat, Type, TokenStream)>>
|
||||
/// for each parameter in the given function signature.
|
||||
pub fn extract_parameter_names_types_and_borrows(sig: &Signature)
|
||||
-> Result<Vec<(Pat, Type, Option<And>)>>
|
||||
{
|
||||
let mut result = Vec::new();
|
||||
let mut generated_pattern_counter = 0;
|
||||
for input in fn_decl.inputs.iter() {
|
||||
for input in sig.inputs.iter() {
|
||||
match input {
|
||||
FnArg::Captured(arg) => {
|
||||
let (ty, borrow) = match &arg.ty {
|
||||
FnArg::Typed(arg) => {
|
||||
let (ty, borrow) = match &*arg.ty {
|
||||
Type::Reference(t) => {
|
||||
let ty = &t.elem;
|
||||
(parse_quote!( #ty ), quote!( & ))
|
||||
((*t.elem).clone(), Some(t.and_token))
|
||||
},
|
||||
t => { (t.clone(), quote!()) },
|
||||
t => { (t.clone(), None) },
|
||||
};
|
||||
|
||||
let name =
|
||||
generate_unique_pattern(arg.pat.clone(), &mut generated_pattern_counter);
|
||||
generate_unique_pattern((*arg.pat).clone(), &mut generated_pattern_counter);
|
||||
result.push((name, ty, borrow));
|
||||
},
|
||||
_ => {
|
||||
return Err(
|
||||
Error::new(
|
||||
input.span(),
|
||||
"Only function arguments with the following \
|
||||
pattern are accepted: `name: type`!"
|
||||
)
|
||||
)
|
||||
FnArg::Receiver(_) => {
|
||||
return Err(Error::new(input.span(), "`self` parameter not supported!"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user