From 7d8da72abbea1a972cdcae1d933a9e5589686c39 Mon Sep 17 00:00:00 2001 From: Tomasz Kulik Date: Sat, 20 Apr 2024 17:00:04 +0200 Subject: [PATCH] feat: Remove types forwarding to interface's assoc --- .../contracts/cw1-subkeys/src/contract.rs | 2 +- .../contracts/cw1-whitelist/src/contract.rs | 2 +- examples/contracts/cw20-base/src/contract.rs | 2 +- .../generic_contract/src/bin/schema.rs | 4 +- .../generic_contract/src/contract.rs | 28 +-- .../src/custom_and_generic.rs | 32 ++-- .../contracts/generic_contract/src/cw1.rs | 31 +-- .../contracts/generic_contract/src/generic.rs | 32 ++-- .../generics_forwarded/src/bin/schema.rs | 6 +- .../generics_forwarded/src/contract.rs | 32 ++-- .../src/custom_and_generic.rs | 36 ++-- .../contracts/generics_forwarded/src/cw1.rs | 35 ++-- .../generics_forwarded/src/generic.rs | 36 ++-- sylvia-derive/src/input.rs | 7 +- sylvia-derive/src/interfaces.rs | 48 ++--- sylvia-derive/src/message.rs | 177 ++++++++++-------- sylvia-derive/src/multitest.rs | 28 ++- sylvia-derive/src/querier.rs | 2 +- sylvia-derive/src/utils.rs | 27 +-- sylvia/tests/api.rs | 4 +- sylvia/tests/multitest.rs | 4 +- sylvia/tests/querier.rs | 2 +- 22 files changed, 285 insertions(+), 292 deletions(-) diff --git a/examples/contracts/cw1-subkeys/src/contract.rs b/examples/contracts/cw1-subkeys/src/contract.rs index 30deacb4..131c887d 100644 --- a/examples/contracts/cw1-subkeys/src/contract.rs +++ b/examples/contracts/cw1-subkeys/src/contract.rs @@ -36,7 +36,7 @@ pub struct Cw1SubkeysContract<'a> { #[sv::error(ContractError)] #[sv::messages(cw1 as Cw1)] #[sv::messages(whitelist as Whitelist)] -impl Cw1SubkeysContract<'_> { +impl<'abcd> Cw1SubkeysContract<'abcd> { pub const fn new() -> Self { Self { whitelist: Cw1WhitelistContract::new(), diff --git a/examples/contracts/cw1-whitelist/src/contract.rs b/examples/contracts/cw1-whitelist/src/contract.rs index a1738d31..a991b06e 100644 --- a/examples/contracts/cw1-whitelist/src/contract.rs +++ b/examples/contracts/cw1-whitelist/src/contract.rs @@ -22,7 +22,7 @@ pub struct Cw1WhitelistContract<'a> { #[sv::error(ContractError)] #[sv::messages(cw1 as Cw1)] #[sv::messages(whitelist as Whitelist)] -impl Cw1WhitelistContract<'_> { +impl<'asdf> Cw1WhitelistContract<'asdf> { pub const fn new() -> Self { Self { admins: Map::new("admins"), diff --git a/examples/contracts/cw20-base/src/contract.rs b/examples/contracts/cw20-base/src/contract.rs index 8979c729..c594fe26 100644 --- a/examples/contracts/cw20-base/src/contract.rs +++ b/examples/contracts/cw20-base/src/contract.rs @@ -78,7 +78,7 @@ pub struct Cw20Base<'a> { #[sv::messages(cw20_allowances as Allowances)] #[sv::messages(cw20_marketing as Marketing)] #[sv::messages(cw20_minting as Minting)] -impl Cw20Base<'_> { +impl<'abcd> Cw20Base<'abcd> { pub const fn new() -> Self { Self { token_info: Item::new("token_info"), diff --git a/examples/contracts/generic_contract/src/bin/schema.rs b/examples/contracts/generic_contract/src/bin/schema.rs index 5cb3b229..6cd3cfdc 100644 --- a/examples/contracts/generic_contract/src/bin/schema.rs +++ b/examples/contracts/generic_contract/src/bin/schema.rs @@ -7,7 +7,7 @@ fn main() { write_api! { instantiate: InstantiateMsg, - execute: ContractExecMsg, - query: ContractQueryMsg, + execute: ContractExecMsg, + query: ContractQueryMsg, } } diff --git a/examples/contracts/generic_contract/src/contract.rs b/examples/contracts/generic_contract/src/contract.rs index cf97a4ad..fa4aaac1 100644 --- a/examples/contracts/generic_contract/src/contract.rs +++ b/examples/contracts/generic_contract/src/contract.rs @@ -194,7 +194,7 @@ where #[cfg(test)] mod tests { use super::sv::mt::CodeId; - use super::{SvCustomMsg, SvCustomQuery}; + use super::{GenericContract, SvCustomMsg, SvCustomQuery}; use crate::contract::sv::mt::GenericContractProxy; use cw_multi_test::IntoBech32; use sylvia::multitest::App; @@ -204,18 +204,20 @@ mod tests { let app = App::>::custom(|_, _, _| {}); #[allow(clippy::type_complexity)] let code_id: CodeId< - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - String, + GenericContract< + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + String, + >, _, > = CodeId::store_code(&app); diff --git a/examples/contracts/generic_contract/src/custom_and_generic.rs b/examples/contracts/generic_contract/src/custom_and_generic.rs index ba635625..001cb74a 100644 --- a/examples/contracts/generic_contract/src/custom_and_generic.rs +++ b/examples/contracts/generic_contract/src/custom_and_generic.rs @@ -2,7 +2,7 @@ use cosmwasm_std::{CosmosMsg, Response, StdError, StdResult}; use custom_and_generic::CustomAndGeneric; use sylvia::types::{ExecCtx, QueryCtx, SudoCtx}; -use crate::contract::{SvCustomMsg, SvCustomQuery}; +use crate::contract::{GenericContract, SvCustomMsg, SvCustomQuery}; impl< InstantiateT, @@ -18,7 +18,7 @@ impl< MigrateT, FieldT, > CustomAndGeneric - for crate::contract::GenericContract< + for GenericContract< InstantiateT, Exec1T, Exec2T, @@ -104,7 +104,7 @@ impl< #[cfg(test)] mod tests { - use super::{SvCustomMsg, SvCustomQuery}; + use super::{GenericContract, SvCustomMsg, SvCustomQuery}; use crate::contract::sv::mt::CodeId; use custom_and_generic::sv::mt::CustomAndGenericProxy; use cw_multi_test::IntoBech32; @@ -114,18 +114,20 @@ mod tests { fn proxy_methods() { let app = App::>::custom(|_, _, _| {}); let code_id = CodeId::< - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - String, + GenericContract< + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + String, + >, _, >::store_code(&app); diff --git a/examples/contracts/generic_contract/src/cw1.rs b/examples/contracts/generic_contract/src/cw1.rs index fddbacf0..fff63bbd 100644 --- a/examples/contracts/generic_contract/src/cw1.rs +++ b/examples/contracts/generic_contract/src/cw1.rs @@ -1,3 +1,4 @@ +use crate::contract::GenericContract; use cosmwasm_std::{CosmosMsg, Response, StdError, StdResult}; use cw1::{CanExecuteResp, Cw1}; use sylvia::types::{ExecCtx, QueryCtx}; @@ -16,7 +17,7 @@ impl< MigrateT, FieldT, > Cw1 - for crate::contract::GenericContract< + for GenericContract< InstantiateT, Exec1T, Exec2T, @@ -50,7 +51,7 @@ impl< #[cfg(test)] mod tests { use crate::contract::sv::mt::CodeId; - use crate::contract::{SvCustomMsg, SvCustomQuery}; + use crate::contract::{GenericContract, SvCustomMsg, SvCustomQuery}; use cosmwasm_std::{CosmosMsg, Empty}; use cw1::sv::mt::Cw1Proxy; use cw_multi_test::IntoBech32; @@ -60,18 +61,20 @@ mod tests { fn proxy_methods() { let app = App::>::custom(|_, _, _| {}); let code_id = CodeId::< - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - String, + GenericContract< + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + String, + >, _, >::store_code(&app); diff --git a/examples/contracts/generic_contract/src/generic.rs b/examples/contracts/generic_contract/src/generic.rs index 4c073c85..59541e16 100644 --- a/examples/contracts/generic_contract/src/generic.rs +++ b/examples/contracts/generic_contract/src/generic.rs @@ -3,7 +3,7 @@ use generic::Generic; use serde::Deserialize; use sylvia::types::{CustomMsg, ExecCtx, QueryCtx, SudoCtx}; -use crate::contract::SvCustomMsg; +use crate::contract::{GenericContract, SvCustomMsg}; impl< InstantiateT, @@ -19,7 +19,7 @@ impl< MigrateT, FieldT, > Generic - for crate::contract::GenericContract< + for GenericContract< InstantiateT, Exec1T, Exec2T, @@ -117,7 +117,7 @@ where #[cfg(test)] mod tests { use crate::contract::sv::mt::CodeId; - use crate::contract::{SvCustomMsg, SvCustomQuery}; + use crate::contract::{GenericContract, SvCustomMsg, SvCustomQuery}; use cosmwasm_std::CosmosMsg; use cw_multi_test::IntoBech32; use generic::sv::mt::GenericProxy; @@ -128,18 +128,20 @@ mod tests { let app = App::>::custom(|_, _, _| {}); #[allow(clippy::type_complexity)] let code_id: CodeId< - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - String, + GenericContract< + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + String, + >, _, > = CodeId::store_code(&app); diff --git a/examples/contracts/generics_forwarded/src/bin/schema.rs b/examples/contracts/generics_forwarded/src/bin/schema.rs index 3295c812..deec2b7b 100644 --- a/examples/contracts/generics_forwarded/src/bin/schema.rs +++ b/examples/contracts/generics_forwarded/src/bin/schema.rs @@ -3,7 +3,7 @@ use cosmwasm_schema::write_api; #[cfg(not(tarpaulin_include))] fn main() { use generics_forwarded::contract::sv::{ContractExecMsg, ContractQueryMsg, InstantiateMsg}; - use generics_forwarded::contract::SvCustomMsg; + use generics_forwarded::contract::{SvCustomMsg, SvCustomQuery}; write_api! { instantiate: InstantiateMsg, @@ -18,7 +18,7 @@ fn main() { // This potentially could be done with some type alias, not sure how it would affect the // schema. // execute: ::ContractExec, - execute: ContractExecMsg, - query: ContractQueryMsg, + execute: ContractExecMsg, + query: ContractQueryMsg, } } diff --git a/examples/contracts/generics_forwarded/src/contract.rs b/examples/contracts/generics_forwarded/src/contract.rs index 6e7d4f59..b815d98e 100644 --- a/examples/contracts/generics_forwarded/src/contract.rs +++ b/examples/contracts/generics_forwarded/src/contract.rs @@ -204,7 +204,7 @@ where #[cfg(test)] mod tests { use super::sv::mt::CodeId; - use super::{SvCustomMsg, SvCustomQuery}; + use super::{GenericsForwardedContract, SvCustomMsg, SvCustomQuery}; use crate::contract::sv::mt::GenericsForwardedContractProxy; use cw_multi_test::IntoBech32; use sylvia::multitest::App; @@ -214,20 +214,22 @@ mod tests { let app = App::>::custom(|_, _, _| {}); #[allow(clippy::type_complexity)] let code_id: CodeId< - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomQuery, - String, + GenericsForwardedContract< + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomQuery, + String, + >, _, > = CodeId::store_code(&app); diff --git a/examples/contracts/generics_forwarded/src/custom_and_generic.rs b/examples/contracts/generics_forwarded/src/custom_and_generic.rs index 32271367..2d2996a8 100644 --- a/examples/contracts/generics_forwarded/src/custom_and_generic.rs +++ b/examples/contracts/generics_forwarded/src/custom_and_generic.rs @@ -3,7 +3,7 @@ use custom_and_generic::CustomAndGeneric; use serde::Deserialize; use sylvia::types::{CustomMsg, CustomQuery, ExecCtx, QueryCtx, SudoCtx}; -use crate::contract::SvCustomMsg; +use crate::contract::{GenericsForwardedContract, SvCustomMsg}; use crate::error::ContractError; impl< @@ -22,7 +22,7 @@ impl< CustomQueryT, FieldT, > CustomAndGeneric - for crate::contract::GenericsForwardedContract< + for GenericsForwardedContract< InstantiateT, Exec1T, Exec2T, @@ -126,7 +126,7 @@ where #[cfg(test)] mod tests { use crate::contract::sv::mt::CodeId; - use crate::contract::{SvCustomMsg, SvCustomQuery}; + use crate::contract::{GenericsForwardedContract, SvCustomMsg, SvCustomQuery}; use cosmwasm_std::CosmosMsg; use custom_and_generic::sv::mt::CustomAndGenericProxy; use cw_multi_test::IntoBech32; @@ -136,20 +136,22 @@ mod tests { fn proxy_methods() { let app = App::>::custom(|_, _, _| {}); let code_id = CodeId::< - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomQuery, - String, + GenericsForwardedContract< + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomQuery, + String, + >, _, >::store_code(&app); diff --git a/examples/contracts/generics_forwarded/src/cw1.rs b/examples/contracts/generics_forwarded/src/cw1.rs index 0111c87c..a4ddc172 100644 --- a/examples/contracts/generics_forwarded/src/cw1.rs +++ b/examples/contracts/generics_forwarded/src/cw1.rs @@ -5,6 +5,7 @@ use serde::de::DeserializeOwned; use serde::Deserialize; use sylvia::types::{CustomQuery, ExecCtx, QueryCtx}; +use crate::contract::GenericsForwardedContract; use crate::error::ContractError; impl< @@ -23,7 +24,7 @@ impl< CustomQueryT, FieldT, > Cw1 - for crate::contract::GenericsForwardedContract< + for GenericsForwardedContract< InstantiateT, Exec1T, Exec2T, @@ -74,7 +75,7 @@ where #[cfg(test)] mod tests { use crate::contract::sv::mt::CodeId; - use crate::contract::{SvCustomMsg, SvCustomQuery}; + use crate::contract::{GenericsForwardedContract, SvCustomMsg, SvCustomQuery}; use cosmwasm_std::{CosmosMsg, Empty}; use cw1::sv::mt::Cw1Proxy; use cw_multi_test::IntoBech32; @@ -84,20 +85,22 @@ mod tests { fn proxy_methods() { let app = App::>::custom(|_, _, _| {}); let code_id = CodeId::< - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomQuery, - String, + GenericsForwardedContract< + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomQuery, + String, + >, _, >::store_code(&app); diff --git a/examples/contracts/generics_forwarded/src/generic.rs b/examples/contracts/generics_forwarded/src/generic.rs index 28f943f4..c5817544 100644 --- a/examples/contracts/generics_forwarded/src/generic.rs +++ b/examples/contracts/generics_forwarded/src/generic.rs @@ -3,7 +3,7 @@ use generic::Generic; use serde::Deserialize; use sylvia::types::{CustomMsg, CustomQuery, ExecCtx, QueryCtx, SudoCtx}; -use crate::contract::SvCustomMsg; +use crate::contract::{GenericsForwardedContract, SvCustomMsg}; use crate::error::ContractError; impl< @@ -22,7 +22,7 @@ impl< CustomQueryT, FieldT, > Generic - for crate::contract::GenericsForwardedContract< + for GenericsForwardedContract< InstantiateT, Exec1T, Exec2T, @@ -124,7 +124,7 @@ where #[cfg(test)] mod tests { use crate::contract::sv::mt::CodeId; - use crate::contract::{SvCustomMsg, SvCustomQuery}; + use crate::contract::{GenericsForwardedContract, SvCustomMsg, SvCustomQuery}; use cosmwasm_std::CosmosMsg; use cw_multi_test::IntoBech32; use generic::sv::mt::GenericProxy; @@ -135,20 +135,22 @@ mod tests { let app = App::>::custom(|_, _, _| {}); #[allow(clippy::type_complexity)] let code_id: CodeId< - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomMsg, - SvCustomQuery, - String, + GenericsForwardedContract< + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomMsg, + SvCustomQuery, + String, + >, _, > = CodeId::store_code(&app); diff --git a/sylvia-derive/src/input.rs b/sylvia-derive/src/input.rs index 0dccfd98..dbf79105 100644 --- a/sylvia-derive/src/input.rs +++ b/sylvia-derive/src/input.rs @@ -200,14 +200,13 @@ impl<'a> ImplInput<'a> { item, generics, custom, - interfaces, .. } = self; let multitest_helpers = self.emit_multitest_helpers(); let querier = ContractQuerier::new(item).emit(); let messages = self.emit_messages(); - let contract_api = ContractApi::new(item, generics, custom, interfaces).emit(); + let contract_api = ContractApi::new(item, generics, custom).emit(); quote! { pub mod sv { @@ -264,16 +263,12 @@ impl<'a> ImplInput<'a> { } fn emit_glue_msg(&self, msg_ty: MsgType) -> TokenStream { - let Self { generics, item, .. } = self; - let where_clause = &item.generics.where_clause; - let variants = MsgVariants::new(item.as_variants(), msg_ty, generics, where_clause); GlueMessage::new( self.item, msg_ty, &self.error, &self.custom, &self.interfaces, - variants, ) .emit() } diff --git a/sylvia-derive/src/interfaces.rs b/sylvia-derive/src/interfaces.rs index fefc45c2..841cf3aa 100644 --- a/sylvia-derive/src/interfaces.rs +++ b/sylvia-derive/src/interfaces.rs @@ -1,7 +1,7 @@ use proc_macro2::{Ident, TokenStream}; use quote::quote; use syn::spanned::Spanned; -use syn::{GenericArgument, ItemImpl}; +use syn::{ItemImpl, Type}; use crate::crate_module; use crate::parser::attributes::msg::MsgType; @@ -18,26 +18,19 @@ impl Interfaces { Self { interfaces } } - pub fn emit_glue_message_variants(&self, msg_ty: &MsgType) -> Vec { - let sylvia = crate_module(); - + pub fn emit_glue_message_variants( + &self, + msg_ty: &MsgType, + contract: &Type, + ) -> Vec { self.interfaces .iter() .map(|interface| { let ContractMessageAttr { - module, - variant, - generics, - .. + module, variant, .. } = interface; - let generics = if !generics.is_empty() { - quote! { < #generics > } - } else { - quote! {} - }; - let interface_enum = - quote! { <#module ::sv::Api #generics as #sylvia ::types::InterfaceApi> }; + let interface_enum = quote! { < #contract as #module ::sv::InterfaceMessagesApi> }; let type_name = msg_ty.as_accessor_name(); quote! { #variant ( #interface_enum :: #type_name) } @@ -83,25 +76,21 @@ impl Interfaces { .collect() } - pub fn emit_response_schemas_calls(&self, msg_ty: &MsgType) -> Vec { - let sylvia = crate_module(); - + pub fn emit_response_schemas_calls( + &self, + msg_ty: &MsgType, + contract: &Type, + ) -> Vec { self.interfaces .iter() .map(|interface| { let ContractMessageAttr { - module, generics, .. + module, .. } = interface; - let generics = if !generics.is_empty() { - quote! { < #generics > } - } else { - quote! {} - }; - let type_name = msg_ty.as_accessor_name(); quote! { - <#module ::sv::Api #generics as #sylvia ::types::InterfaceApi> :: #type_name :: response_schemas_impl() + <#contract as #module ::sv::InterfaceMessagesApi> :: #type_name :: response_schemas_impl() } }) .collect() @@ -130,11 +119,4 @@ impl Interfaces { } }).collect() } - - pub fn as_generic_args(&self) -> Vec<&GenericArgument> { - self.interfaces - .iter() - .flat_map(|interface| &interface.generics) - .collect() - } } diff --git a/sylvia-derive/src/message.rs b/sylvia-derive/src/message.rs index a2dd3825..e521cd9d 100644 --- a/sylvia-derive/src/message.rs +++ b/sylvia-derive/src/message.rs @@ -9,12 +9,10 @@ use crate::parser::{ use crate::strip_generics::StripGenerics; use crate::strip_self_path::StripSelfPath; use crate::utils::{ - as_where_clause, emit_bracketed_generics, extract_return_type, filter_generics, filter_wheres, - process_fields, + as_where_clause, emit_bracketed_generics, extract_return_type, filter_wheres, process_fields, }; use crate::variant_descs::{AsVariantDescs, VariantDescs}; use convert_case::{Case, Casing}; -use itertools::Itertools; use proc_macro2::{Span, TokenStream}; use proc_macro_error::emit_error; use quote::{quote, ToTokens}; @@ -910,7 +908,6 @@ pub struct GlueMessage<'a> { error: &'a ContractErrorAttr, custom: &'a Custom, interfaces: &'a Interfaces, - variants: MsgVariants<'a, GenericParam>, } impl<'a> GlueMessage<'a> { @@ -920,7 +917,6 @@ impl<'a> GlueMessage<'a> { error: &'a ContractErrorAttr, custom: &'a Custom, interfaces: &'a Interfaces, - variants: MsgVariants<'a, GenericParam>, ) -> Self { GlueMessage { source, @@ -929,7 +925,6 @@ impl<'a> GlueMessage<'a> { error, custom, interfaces, - variants, } } @@ -942,54 +937,27 @@ impl<'a> GlueMessage<'a> { error, custom, interfaces, - variants, + .. } = self; let generics: Vec<_> = source.generics.params.iter().collect(); - let interface_generic_args = interfaces.as_generic_args(); - let interface_used_generics = filter_generics(&generics, &interface_generic_args); - let used_generics = variants.used_generics(); - - let wrapper_generics: Vec<_> = interface_used_generics - .iter() - .chain(used_generics.iter()) - .unique() - .copied() - .collect(); - - let unused_generics: Vec<_> = variants - .unused_generics() - .iter() - .filter(|unused| !wrapper_generics.iter().any(|used| used == *unused)) - .collect(); - let full_where_clause = &source.generics.where_clause; - let wrapper_predicates = filter_wheres(full_where_clause, &generics, &wrapper_generics); - let wrapper_where_clause = if !wrapper_predicates.is_empty() { - quote! { where #(#wrapper_predicates,)* } - } else { - quote! {} + let bracketed_wrapper_generics = match generics.is_empty() { + true => quote! {}, + false => quote! { < #(#generics,)* > }, }; - let unused_generics = emit_bracketed_generics(&unused_generics); - let bracketed_used_generics = emit_bracketed_generics(used_generics); - let bracketed_wrapper_generics = emit_bracketed_generics(&wrapper_generics); - let contract_enum_name = msg_ty.emit_msg_wrapper_name(); - let enum_name = msg_ty.emit_msg_name(); + let enum_name = msg_ty.as_accessor_name(); let contract_name = StripGenerics.fold_type((*contract).clone()); - let variants = interfaces.emit_glue_message_variants(msg_ty); + let variants = interfaces.emit_glue_message_variants(msg_ty, contract); let ep_name = msg_ty.emit_ep_name(); let messages_fn_name = Ident::new(&format!("{}_messages", ep_name), contract.span()); - let contract_variant = quote! { #contract_name ( #enum_name #bracketed_used_generics ) }; + let contract_variant = + quote! { #contract_name ( <#contract as #sylvia ::types::ContractApi> :: #enum_name ) }; let mut messages_call = interfaces.emit_messages_call(msg_ty); - let prefixed_used_generics = if !used_generics.is_empty() { - quote! { :: #bracketed_used_generics } - } else { - quote! {} - }; messages_call.push(quote! { &#messages_fn_name() }); let variants_cnt = messages_call.len(); @@ -1014,15 +982,15 @@ impl<'a> GlueMessage<'a> { let ctx_type = msg_ty.emit_ctx_type(&custom.query_or_default()); let ret_type = msg_ty.emit_result_type(&custom.msg_or_default(), &error.error); - let mut response_schemas_calls = interfaces.emit_response_schemas_calls(msg_ty); + let mut response_schemas_calls = interfaces.emit_response_schemas_calls(msg_ty, contract); response_schemas_calls - .push(quote! {#enum_name #prefixed_used_generics :: response_schemas_impl()}); + .push(quote! {<#contract as #sylvia ::types::ContractApi> :: #enum_name ::response_schemas_impl()}); let response_schemas = match msg_ty { MsgType::Query => { quote! { #[cfg(not(target_arch = "wasm32"))] - impl #bracketed_wrapper_generics #sylvia ::cw_schema::QueryResponses for #contract_enum_name #bracketed_wrapper_generics #wrapper_where_clause { + impl #bracketed_wrapper_generics #sylvia ::cw_schema::QueryResponses for #contract_enum_name #bracketed_wrapper_generics #full_where_clause { fn response_schemas_impl() -> std::collections::BTreeMap { let responses = [#(#response_schemas_calls),*]; responses.into_iter().flatten().collect() @@ -1037,15 +1005,58 @@ impl<'a> GlueMessage<'a> { quote! { #[allow(clippy::derive_partial_eq_without_eq)] - #[derive(#sylvia ::serde::Serialize, Clone, Debug, PartialEq, #sylvia ::schemars::JsonSchema)] + #[derive(#sylvia ::serde::Serialize, Clone, Debug, PartialEq)] #[serde(rename_all="snake_case", untagged)] - pub enum #contract_enum_name #bracketed_wrapper_generics #wrapper_where_clause { + pub enum #contract_enum_name #bracketed_wrapper_generics #full_where_clause { #(#variants,)* #contract_variant } - impl #bracketed_wrapper_generics #contract_enum_name #bracketed_wrapper_generics #wrapper_where_clause { - pub fn dispatch #unused_generics ( + impl #bracketed_wrapper_generics #sylvia ::schemars::JsonSchema for #contract_enum_name #bracketed_wrapper_generics #full_where_clause { + fn schema_name() -> std::string::String { + { + let res = format!( + "{0}", + std::any::type_name::() + ); + res + } + } + + fn json_schema( + gen: &mut #sylvia ::schemars::gen::SchemaGenerator, + ) -> #sylvia ::schemars::schema::Schema { + todo!() + // TODO (tkulik): + // schemars::schema::Schema::Object(schemars::schema::SchemaObject { + // subschemas: Some( + // Box::new(schemars::schema::SubschemaValidation { + // any_of: Some( + // <[_]>::into_vec( + // #[rustc_box] + // ::alloc::boxed::Box::new([ + // gen + // .subschema_for::< + // ::Sudo, + // >(), + // gen + // .subschema_for::< + // ::Sudo, + // >(), + // gen.subschema_for::(), + // ]), + // ), + // ), + // ..Default::default() + // }), + // ), + // ..Default::default() + // }) + } + } + + impl #bracketed_wrapper_generics #contract_enum_name #bracketed_wrapper_generics #full_where_clause { + pub fn dispatch ( self, contract: &#contract, ctx: #ctx_type, @@ -1064,7 +1075,7 @@ impl<'a> GlueMessage<'a> { #response_schemas - impl<'de, #(#wrapper_generics,)* > serde::Deserialize<'de> for #contract_enum_name #bracketed_wrapper_generics #wrapper_where_clause { + impl<'de, #(#generics,)* > serde::Deserialize<'de> for #contract_enum_name #bracketed_wrapper_generics #full_where_clause { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { @@ -1114,16 +1125,10 @@ pub struct ContractApi<'a> { sudo_variants: MsgVariants<'a, GenericParam>, generics: &'a [&'a GenericParam], custom: &'a Custom, - interfaces: &'a Interfaces, } impl<'a> ContractApi<'a> { - pub fn new( - source: &'a ItemImpl, - generics: &'a [&'a GenericParam], - custom: &'a Custom, - interfaces: &'a Interfaces, - ) -> Self { + pub fn new(source: &'a ItemImpl, generics: &'a [&'a GenericParam], custom: &'a Custom) -> Self { let exec_variants = MsgVariants::new( source.as_variants(), MsgType::Exec, @@ -1168,7 +1173,6 @@ impl<'a> ContractApi<'a> { sudo_variants, generics, custom, - interfaces, } } @@ -1183,7 +1187,7 @@ impl<'a> ContractApi<'a> { sudo_variants, generics, custom, - interfaces, + .. } = self; let where_clause = &source.generics.where_clause; @@ -1194,34 +1198,12 @@ impl<'a> ContractApi<'a> { let migrate_generics = &migrate_variants.used_generics; let sudo_generics = &sudo_variants.used_generics; - let interface_generics = interfaces.as_generic_args(); - let interface_generics = filter_generics(generics, &interface_generics); - - let contract_exec_generics: Vec<_> = interface_generics - .iter() - .chain(exec_generics.iter()) - .unique() - .collect(); - let contract_query_generics: Vec<_> = interface_generics - .iter() - .chain(query_generics.iter()) - .unique() - .collect(); - let contract_sudo_generics: Vec<_> = interface_generics - .iter() - .chain(sudo_generics.iter()) - .unique() - .collect(); - let bracket_generics = emit_bracketed_generics(generics); let exec_bracketed_generics = emit_bracketed_generics(exec_generics); let query_bracketed_generics = emit_bracketed_generics(query_generics); let sudo_bracketed_generics = emit_bracketed_generics(sudo_generics); let instantiate_bracketed_generics = emit_bracketed_generics(instantiate_generics); let migrate_bracketed_generics = emit_bracketed_generics(migrate_generics); - let contract_exec_bracketed_generics = emit_bracketed_generics(&contract_exec_generics); - let contract_query_bracketed_generics = emit_bracketed_generics(&contract_query_generics); - let contract_sudo_bracketed_generics = emit_bracketed_generics(&contract_sudo_generics); let migrate_type = if migrate_variants.variants().count() != 0 { quote! { type Migrate = MigrateMsg #migrate_bracketed_generics; } @@ -1232,9 +1214,9 @@ impl<'a> ContractApi<'a> { quote! { impl #bracket_generics #sylvia ::types::ContractApi for #contract_name #where_clause { - type ContractExec = ContractExecMsg #contract_exec_bracketed_generics; - type ContractQuery = ContractQueryMsg #contract_query_bracketed_generics; - type ContractSudo = ContractSudoMsg #contract_sudo_bracketed_generics; + type ContractExec = ContractExecMsg #bracket_generics; + type ContractQuery = ContractQueryMsg #bracket_generics; + type ContractSudo = ContractSudoMsg #bracket_generics; type Exec = ExecMsg #exec_bracketed_generics; type Query = QueryMsg #query_bracketed_generics; type Sudo = SudoMsg #sudo_bracketed_generics; @@ -1274,6 +1256,7 @@ impl<'a> InterfaceApi<'a> { associated_types, } = self; + let interface_name = &source.ident; let generics: Vec<_> = associated_types .without_special() .map(ItemType::as_name) @@ -1308,6 +1291,19 @@ impl<'a> InterfaceApi<'a> { let query_bracketed_generics = emit_bracketed_generics(query_generics); let sudo_bracketed_generics = emit_bracketed_generics(sudo_generics); + let exec_bracketed_generics2 = match exec_generics.is_empty() { + true => quote! {}, + false => quote! { < #(:: #exec_generics,)* > }, + }; + let query_bracketed_generics2 = match query_generics.is_empty() { + true => quote! {}, + false => quote! { < #(:: #query_generics,)* > }, + }; + let sudo_bracketed_generics2 = match sudo_generics.is_empty() { + true => quote! {}, + false => quote! { < #(:: #sudo_generics ,)* > }, + }; + let phantom = if !generics.is_empty() { quote! { _phantom: std::marker::PhantomData<( #(#generics,)* )>, @@ -1317,6 +1313,21 @@ impl<'a> InterfaceApi<'a> { }; quote! { + pub trait InterfaceMessagesApi { + type Exec; + type Query; + type Sudo; + type Querier<'querier>; + } + + impl InterfaceMessagesApi for Contract { + type Exec = ExecMsg #exec_bracketed_generics2; + type Query = QueryMsg #query_bracketed_generics2; + type Sudo = SudoMsg #sudo_bracketed_generics2; + type Querier<'querier> = #sylvia ::types::BoundQuerier<'querier, #custom_query, Contract >; + } + + pub struct Api #bracket_generics { #phantom } diff --git a/sylvia-derive/src/multitest.rs b/sylvia-derive/src/multitest.rs index 67b5abf2..6383e5ef 100644 --- a/sylvia-derive/src/multitest.rs +++ b/sylvia-derive/src/multitest.rs @@ -180,7 +180,7 @@ impl<'a> ContractMtHelpers<'a> { use super::*; use #sylvia ::cw_multi_test::Executor; - pub trait #trait_name <'app, MtApp, #(#generic_params,)* > + pub trait #trait_name <'app, #(#generic_params,)* MtApp > #where_clause { #( #exec_methods_declarations )* @@ -189,8 +189,8 @@ impl<'a> ContractMtHelpers<'a> { #( #sudo_methods_declarations )* } - impl<'app, BankT, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, #(#generic_params,)* > - #trait_name <'app, #mt_app, #(#generic_params,)* > + impl<'app, #(#generic_params,)* BankT, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT > + #trait_name <'app, #(#generic_params,)* #mt_app > for #sylvia ::multitest::Proxy <'app, #mt_app, #contract_name > where CustomT: #sylvia ::cw_multi_test::Module, @@ -229,6 +229,15 @@ impl<'a> ContractMtHelpers<'a> { .. } = self; + let generic_params_lifetimes_replaced = + generic_params.iter().cloned().cloned().map(|generic| { + if let GenericParam::Lifetime(_) = generic { + parse_quote! { '_ } + } else { + generic + } + }); + let fields_names = instantiate_variants .get_only_variant() .map(MsgVariant::as_fields_names) @@ -247,6 +256,7 @@ impl<'a> ContractMtHelpers<'a> { .map(|where_clause| &where_clause.predicates); let contract = get_ident_from_type(contract_name); + let contract123 = get_ident_from_type(contract_name); let contract = if !generic_params.is_empty() { quote! { #contract ::< #(#generic_params,)* > } } else { @@ -327,14 +337,14 @@ impl<'a> ContractMtHelpers<'a> { quote! { #impl_contract - pub struct CodeId<'app, #(#generic_params,)* MtApp> { + pub struct CodeId<'app, Contract, MtApp> { code_id: u64, app: &'app #sylvia ::multitest::App, - _phantom: std::marker::PhantomData<( #(#generic_params,)* )>, + _phantom: std::marker::PhantomData, } - impl<'app, BankT, ApiT, StorageT, CustomT, StakingT, DistrT, IbcT, GovT, #(#generic_params,)* > CodeId<'app, #(#generic_params,)* #mt_app > + impl<'app, #(#generic_params,)* BankT, ApiT, StorageT, CustomT, StakingT, DistrT, IbcT, GovT > CodeId<'app, #contract, #mt_app > where BankT: #sylvia ::cw_multi_test::Bank, ApiT: #sylvia ::cw_std::Api, @@ -349,7 +359,7 @@ impl<'a> ContractMtHelpers<'a> { pub fn store_code(app: &'app #sylvia ::multitest::App< #mt_app >) -> Self { let code_id = app .app_mut() - .store_code(Box::new(#contract ::new())); + .store_code(Box::new( #contract123:: < #(#generic_params_lifetimes_replaced),* > ::new() )); Self { code_id, app, _phantom: std::marker::PhantomData::default() } } @@ -363,7 +373,7 @@ impl<'a> ContractMtHelpers<'a> { &self, #(#fields,)* ) -> InstantiateProxy<'_, 'app, #(#generic_params,)* #mt_app > { let msg = #instantiate_msg {#(#fields_names,)*}; - InstantiateProxy::< #(#generic_params,)* _> { + InstantiateProxy::<'_, 'app, #(#generic_params,)* _> { code_id: self, funds: &[], label: "Contract", @@ -375,7 +385,7 @@ impl<'a> ContractMtHelpers<'a> { } pub struct InstantiateProxy<'proxy, 'app, #(#generic_params,)* MtApp> { - code_id: &'proxy CodeId <'app, #(#generic_params,)* MtApp>, + code_id: &'proxy CodeId <'app, #contract, MtApp>, funds: &'proxy [#sylvia ::cw_std::Coin], label: &'proxy str, admin: Option, diff --git a/sylvia-derive/src/querier.rs b/sylvia-derive/src/querier.rs index 8558d0cb..9fe41a31 100644 --- a/sylvia-derive/src/querier.rs +++ b/sylvia-derive/src/querier.rs @@ -141,7 +141,7 @@ impl<'a> ContractQuerier<'a> { #(#methods_declaration)* } - impl <'a, C: #sylvia ::cw_std::CustomQuery, #(#generics,)*> Querier #bracketed_generics for #sylvia ::types::BoundQuerier<'a, C, #contract_name > #where_clause { + impl <'a, #(#generics,)* C: #sylvia ::cw_std::CustomQuery> Querier #bracketed_generics for #sylvia ::types::BoundQuerier<'a, C, #contract_name > #where_clause { #(#types_implementation)* #(#methods_impl)* diff --git a/sylvia-derive/src/utils.rs b/sylvia-derive/src/utils.rs index 02b82a45..1e6996ee 100644 --- a/sylvia-derive/src/utils.rs +++ b/sylvia-derive/src/utils.rs @@ -4,8 +4,8 @@ use quote::{quote, ToTokens}; use syn::spanned::Spanned; use syn::visit::Visit; use syn::{ - parse_quote, FnArg, GenericArgument, GenericParam, Path, PathArguments, ReturnType, Signature, - Type, WhereClause, WherePredicate, + parse_quote, FnArg, GenericArgument, Path, PathArguments, ReturnType, Signature, Type, + WhereClause, WherePredicate, }; use crate::check_generics::{CheckGenerics, GetPath}; @@ -35,29 +35,6 @@ pub fn filter_wheres<'a, Generic: GetPath + PartialEq>( .unwrap_or_default() } -/// Filters generic arguments, which are a concrete types, -/// from the generic parameters -/// -/// f.e. -/// impl MyTrait for MyContract -/// -/// where generic parameters are `[A, B, C]` and generic arguments are `[A, B, D]` -/// should return us the `[A, B]`. -pub fn filter_generics<'a>( - generic_params: &'a [&'a GenericParam], - generic_args: &'a [&'a GenericArgument], -) -> Vec<&'a GenericParam> { - generic_params - .iter() - .filter(|param| { - generic_args - .iter() - .any(|arg| param.get_path() == arg.get_path()) - }) - .copied() - .collect() -} - pub fn process_fields<'s, Generic>( sig: &'s Signature, generics_checker: &mut CheckGenerics, diff --git a/sylvia/tests/api.rs b/sylvia/tests/api.rs index e742d439..ba2b3ebe 100644 --- a/sylvia/tests/api.rs +++ b/sylvia/tests/api.rs @@ -89,7 +89,7 @@ mod tests { SvCustomMsg ); - let _: crate::sv::ContractExecMsg = = = = ::store_code(&app); + let code_id = sv::mt::CodeId::, _>::store_code(&app); let _: sylvia::multitest::Proxy<_, SomeContract> = code_id .instantiate(Empty {}) @@ -48,7 +48,7 @@ fn instantiate_with_salt() { fn code_info() { let app = App::default(); - let code_id = sv::mt::CodeId::::store_code(&app); + let code_id = sv::mt::CodeId::, _>::store_code(&app); let _: CodeInfoResponse = code_id.code_info().unwrap(); let _: CodeInfoResponse = app.code_info(code_id.code_id()).unwrap(); diff --git a/sylvia/tests/querier.rs b/sylvia/tests/querier.rs index 917ad90f..fe39632d 100644 --- a/sylvia/tests/querier.rs +++ b/sylvia/tests/querier.rs @@ -95,7 +95,7 @@ pub struct CounterContract<'a> { #[contract] #[sv::messages(counter)] -impl CounterContract<'_> { +impl<'asdf> CounterContract<'asdf> { #[allow(clippy::new_without_default)] pub fn new() -> Self { Self {