Skip to content

Commit

Permalink
[refactor] hyperledger-iroha#3934: Migrate iroha_wasm_derive and `i…
Browse files Browse the repository at this point in the history
…roha_validator_derive` to syn 2.0

Signed-off-by: Nikita Strygin <dcnick3@users.noreply.github.com>
  • Loading branch information
DCNick3 committed Nov 10, 2023
1 parent e9c6fe4 commit aaa0ad9
Show file tree
Hide file tree
Showing 13 changed files with 716 additions and 212 deletions.
10 changes: 7 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions smart_contract/derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ workspace = true
proc-macro = true

[dependencies]
syn.workspace = true
quote.workspace = true
proc-macro2.workspace = true
iroha_macro_utils = { workspace = true }

syn2 = { workspace = true }
manyhow = { workspace = true }
quote = { workspace = true }
proc-macro2 = { workspace = true }
30 changes: 19 additions & 11 deletions smart_contract/derive/src/entrypoint.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
//! Macro for writing smart contract entrypoint

use proc_macro::TokenStream;
#![allow(clippy::str_to_string)]

use iroha_macro_utils::Emitter;
use manyhow::emit;
use proc_macro2::TokenStream;
use quote::quote;
use syn::{parse_macro_input, parse_quote};
use syn2::parse_quote;

mod export {
pub const SMART_CONTRACT_MAIN: &str = "_iroha_smart_contract_main";
}

#[allow(clippy::needless_pass_by_value)]
pub fn impl_entrypoint(_attr: TokenStream, item: TokenStream) -> TokenStream {
let syn::ItemFn {
pub fn impl_entrypoint(emitter: &mut Emitter, item: syn2::ItemFn) -> TokenStream {
let syn2::ItemFn {
attrs,
vis,
sig,
mut block,
} = parse_macro_input!(item);
} = item;

assert!(
syn::ReturnType::Default == sig.output,
"Smart contract `main()` function must not have a return type"
);
if sig.output != syn2::ReturnType::Default {
emit!(
emitter,
"Smart contract entrypoint must not have a return type"
);
}

let fn_name = &sig.ident;

Expand All @@ -33,7 +39,10 @@ pub fn impl_entrypoint(_attr: TokenStream, item: TokenStream) -> TokenStream {
),
);

let main_fn_name = syn::Ident::new(export::SMART_CONTRACT_MAIN, proc_macro2::Span::call_site());
let main_fn_name = syn2::Ident::new(
export::SMART_CONTRACT_MAIN,
proc_macro2::Span::call_site(),
);

quote! {
/// Smart contract entrypoint
Expand All @@ -51,5 +60,4 @@ pub fn impl_entrypoint(_attr: TokenStream, item: TokenStream) -> TokenStream {
#vis #sig
#block
}
.into()
}
22 changes: 20 additions & 2 deletions smart_contract/derive/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! Macros for writing smart contracts.

use proc_macro::TokenStream;
use iroha_macro_utils::Emitter;
use manyhow::{emit, manyhow};
use proc_macro2::TokenStream;

mod entrypoint;

Expand All @@ -23,7 +25,23 @@ mod entrypoint;
/// todo!()
/// }
/// ```
#[manyhow]
#[proc_macro_attribute]
pub fn main(attr: TokenStream, item: TokenStream) -> TokenStream {
entrypoint::impl_entrypoint(attr, item)
let mut emitter = Emitter::new();

if !attr.is_empty() {
emit!(
emitter,
"Smart contract entrypoint does not accept attributes"
);
}

let Some(item) = emitter.handle(syn2::parse2(item)) else {
return emitter.finish_token_stream();
};

let result = entrypoint::impl_entrypoint(&mut emitter, item);

emitter.finish_token_stream_with(result)
}
15 changes: 7 additions & 8 deletions smart_contract/executor/derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@ workspace = true
proc-macro = true

[dependencies]
iroha_data_model.workspace = true
iroha_macro_utils.workspace = true
syn = { workspace = true, features = ["full", "derive"] }
syn2 = { workspace = true, features = ["full", "derive"] }
quote.workspace = true
proc-macro2.workspace = true
manyhow.workspace = true
darling.workspace = true
iroha_macro_utils = { workspace = true }

syn2 = { workspace = true }
manyhow = { workspace = true }
darling = { workspace = true }
quote = { workspace = true }
proc-macro2 = { workspace = true }
54 changes: 22 additions & 32 deletions smart_contract/executor/derive/src/conversion.rs
Original file line number Diff line number Diff line change
@@ -1,76 +1,66 @@
//! Module with conversion derive macros implementation

use super::*;
use proc_macro2::TokenStream;
use quote::quote;
use syn2::DeriveInput;

/// [`derive_ref_into_asset_owner`](crate::derive_ref_into_asset_owner) macro implementation
pub fn impl_derive_ref_into_asset_owner(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);

pub fn impl_derive_ref_into_asset_owner(input: &DeriveInput) -> TokenStream {
impl_from(
&input.ident,
&input.generics,
&syn::parse_quote!(::iroha_executor::permission::asset::Owner),
&syn::parse_quote!(asset_id),
&syn2::parse_quote!(::iroha_executor::permission::asset::Owner),
&syn2::parse_quote!(asset_id),
)
.into()
}

/// [`derive_ref_into_asset_definition_creator`](crate::derive_ref_into_asset_definition_creator)
/// macro implementation
pub fn impl_derive_ref_into_asset_definition_owner(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);

pub fn impl_derive_ref_into_asset_definition_owner(input: &DeriveInput) -> TokenStream {
impl_from(
&input.ident,
&input.generics,
&syn::parse_quote!(::iroha_executor::permission::asset_definition::Owner),
&syn::parse_quote!(asset_definition_id),
&syn2::parse_quote!(::iroha_executor::permission::asset_definition::Owner),
&syn2::parse_quote!(asset_definition_id),
)
.into()
}

/// [`derive_ref_into_account_owner`](crate::derive_ref_into_account_owner) macro implementation
pub fn impl_derive_ref_into_account_owner(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);

pub fn impl_derive_ref_into_account_owner(input: &DeriveInput) -> TokenStream {
impl_from(
&input.ident,
&input.generics,
&syn::parse_quote!(::iroha_executor::permission::account::Owner),
&syn::parse_quote!(account_id),
&syn2::parse_quote!(::iroha_executor::permission::account::Owner),
&syn2::parse_quote!(account_id),
)
.into()
}

/// [`derive_ref_into_domain_owner`](crate::derive_ref_into_domain_owner) macro implementation
pub fn impl_derive_ref_into_domain_owner(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);

pub fn impl_derive_ref_into_domain_owner(input: &DeriveInput) -> TokenStream {
impl_from(
&input.ident,
&input.generics,
&syn::parse_quote!(::iroha_executor::permission::domain::Owner),
&syn::parse_quote!(domain_id),
&syn2::parse_quote!(::iroha_executor::permission::domain::Owner),
&syn2::parse_quote!(domain_id),
)
.into()
}

fn impl_from(
ident: &syn::Ident,
generics: &syn::Generics,
pass_condition_type: &syn::Type,
field: &syn::Ident,
) -> proc_macro2::TokenStream {
ident: &syn2::Ident,
generics: &syn2::Generics,
pass_condition_type: &syn2::Type,
field: &syn2::Ident,
) -> TokenStream {
use quote::ToTokens;

let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();

let mut generics: proc_macro2::TokenStream = syn::parse_str("<'token, ").unwrap();
let mut generics: TokenStream = syn2::parse_str("<'token, ").unwrap();

let impl_generics_tokens = impl_generics.into_token_stream();
if impl_generics_tokens.is_empty() {
generics.extend(core::iter::once(proc_macro2::TokenTree::Punct(
syn::parse_str(">").unwrap(),
syn2::parse_str(">").unwrap(),
)));
} else {
generics.extend(impl_generics_tokens.into_iter().skip(1));
Expand Down
Loading

0 comments on commit aaa0ad9

Please sign in to comment.