Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(dis)allow multiple var args #1241

Merged
merged 7 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use random::*;

#[multiversx_sc::contract]
pub trait KittyOwnership {
#[allow_multiple_var_args]
#[init]
fn init(
&self,
Expand Down
3 changes: 3 additions & 0 deletions contracts/examples/lottery-esdt/src/lottery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub trait Lottery {
#[init]
fn init(&self) {}

#[allow_multiple_var_args]
#[endpoint]
fn start(
&self,
Expand All @@ -43,6 +44,7 @@ pub trait Lottery {
);
}

#[allow_multiple_var_args]
#[endpoint(createLotteryPool)]
fn create_lottery_pool(
&self,
Expand All @@ -69,6 +71,7 @@ pub trait Lottery {
);
}

#[allow_multiple_var_args]
#[allow(clippy::too_many_arguments)]
fn start_lottery(
&self,
Expand Down
2 changes: 2 additions & 0 deletions contracts/examples/multisig/src/multisig_propose.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ pub trait MultisigProposeModule: crate::multisig_state::MultisigStateModule {
/// Can send EGLD without calling anything.
/// Can call smart contract endpoints directly.
/// Doesn't really work with builtin functions.
#[allow_multiple_var_args]
#[endpoint(proposeTransferExecute)]
fn propose_transfer_execute(
&self,
Expand All @@ -92,6 +93,7 @@ pub trait MultisigProposeModule: crate::multisig_state::MultisigStateModule {
/// Can use ESDTTransfer/ESDTNFTTransfer/MultiESDTTransfer to send tokens, while also optionally calling endpoints.
/// Works well with builtin functions.
/// Cannot simply send EGLD directly without calling anything.
#[allow_multiple_var_args]
#[endpoint(proposeAsyncCall)]
fn propose_async_call(
&self,
Expand Down
1 change: 1 addition & 0 deletions contracts/examples/nft-minter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub trait NftMinter: nft_module::NftModule {
#[init]
fn init(&self) {}

#[allow_multiple_var_args]
#[allow(clippy::too_many_arguments)]
#[allow(clippy::redundant_closure)]
#[only_owner]
Expand Down
1 change: 1 addition & 0 deletions contracts/examples/ping-pong-egld/src/ping_pong.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub trait PingPong {
/// `duration_in_seconds` - how much time (in seconds) until contract expires.
/// `opt_activation_timestamp` - optionally specify the contract to only actvivate at a later date.
/// `max_funds` - optional funding cap, no more funds than this can be added to the contract.
#[allow_multiple_var_args]
#[init]
fn init(
&self,
Expand Down
1 change: 1 addition & 0 deletions contracts/examples/seed-nft-minter/src/seed_nft_minter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub trait SeedNftMinter:
self.init_distribution(distribution);
}

#[allow_multiple_var_args]
#[only_owner]
#[endpoint(createNft)]
fn create_nft(
Expand Down
1 change: 1 addition & 0 deletions contracts/feature-tests/basic-features/src/echo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ pub trait EchoTypes {
nz
}

#[allow_multiple_var_args]
#[view]
fn echo_some_args_ignore_others(
&self,
Expand Down
1 change: 1 addition & 0 deletions contracts/feature-tests/composability/vault/src/vault.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ pub trait Vault {
.unwrap_or_else(|_| sc_panic!("ESDT transfer failed"));
}

#[allow_multiple_var_args]
#[label("promises-endpoint")]
#[payable("*")]
#[endpoint]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub trait Lottery {
self.set_erc20_contract_address(&erc20_contract_address);
}

#[allow_multiple_var_args]
#[endpoint]
fn start(
&self,
Expand All @@ -45,6 +46,7 @@ pub trait Lottery {
)
}

#[allow_multiple_var_args]
#[endpoint(createLotteryPool)]
fn create_lottery_pool(
&self,
Expand All @@ -67,6 +69,7 @@ pub trait Lottery {
)
}

#[allow_multiple_var_args]
#[allow(clippy::too_many_arguments)]
fn start_lottery(
&self,
Expand Down
1 change: 1 addition & 0 deletions framework/base/src/abi/endpoint_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ pub struct EndpointAbi {
pub payable_in_tokens: &'static [&'static str],
pub inputs: Vec<InputAbi>,
pub outputs: OutputAbis,
pub allow_multiple_var_args: bool
}

impl EndpointAbi {
Expand Down
1 change: 1 addition & 0 deletions framework/base/src/external_view_contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,6 @@ pub fn external_view_contract_constructor_abi() -> EndpointAbi {
multi_arg: false,
}].to_vec(),
outputs: OutputAbis::new(),
allow_multiple_var_args: false
}
}
5 changes: 5 additions & 0 deletions framework/base/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,11 @@ macro_rules! only_owner {
};
}

#[macro_export]
macro_rules! allow_multiple_var_args {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for this.

Our proc-macro gets rid of annotations it processes. This also helps us easier detect cases where attributes are not properly processed, or we missed something.

If it doesn't work without it, it means we missed something.

() => {};
}

/// Converts usize to NonZeroUsize or returns SCError.
#[macro_export]
macro_rules! non_zero_usize {
Expand Down
5 changes: 5 additions & 0 deletions framework/derive/src/generate/abi_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ fn generate_endpoint_snippet(
only_admin: bool,
mutability: EndpointMutabilityMetadata,
endpoint_type: EndpointTypeMetadata,
allow_multiple_var_args: bool,
) -> proc_macro2::TokenStream {
let endpoint_docs = &m.docs;
let rust_method_name = m.name.to_string();
Expand Down Expand Up @@ -65,6 +66,7 @@ fn generate_endpoint_snippet(
inputs: multiversx_sc::types::heap::Vec::new(),
outputs: multiversx_sc::types::heap::Vec::new(),
labels: &[ #(#label_names),* ],
allow_multiple_var_args: #allow_multiple_var_args,
};
#(#input_snippets)*
#output_snippet
Expand All @@ -84,6 +86,7 @@ fn generate_endpoint_snippets(contract: &ContractTrait) -> Vec<proc_macro2::Toke
false,
EndpointMutabilityMetadata::Mutable,
EndpointTypeMetadata::Init,
m.is_allow_multiple_var_args(),
);
Some(quote! {
#endpoint_def
Expand All @@ -98,6 +101,7 @@ fn generate_endpoint_snippets(contract: &ContractTrait) -> Vec<proc_macro2::Toke
endpoint_metadata.only_admin,
endpoint_metadata.mutability.clone(),
EndpointTypeMetadata::Endpoint,
endpoint_metadata.allow_multiple_var_args,
);
Some(quote! {
#endpoint_def
Expand All @@ -112,6 +116,7 @@ fn generate_endpoint_snippets(contract: &ContractTrait) -> Vec<proc_macro2::Toke
false,
EndpointMutabilityMetadata::Mutable,
EndpointTypeMetadata::PromisesCallback,
m.is_allow_multiple_var_args(),
);
Some(quote! {
#endpoint_def
Expand Down
1 change: 1 addition & 0 deletions framework/derive/src/model/argument.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,5 @@ pub struct TraitProperties {
pub only_owner: bool,
pub only_admin: bool,
pub only_user_account: bool,
pub allow_multiple_var_args: bool
}
3 changes: 3 additions & 0 deletions framework/derive/src/model/endpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use super::{EndpointMutabilityMetadata, MethodPayableMetadata};
#[derive(Clone, Debug)]
pub struct InitMetadata {
pub payable: MethodPayableMetadata,
pub allow_multiple_var_args: bool
}

#[derive(Clone, Debug)]
Expand All @@ -13,11 +14,13 @@ pub struct EndpointMetadata {
pub only_admin: bool,
pub only_user_account: bool,
pub mutability: EndpointMutabilityMetadata,
pub allow_multiple_var_args: bool
}

#[derive(Clone, Debug)]
pub struct CallbackMetadata {
pub callback_name: syn::Ident,
pub allow_multiple_var_args: bool
}

/// Method visibility from the point of view of the smart contract
Expand Down
13 changes: 13 additions & 0 deletions framework/derive/src/model/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,17 @@ impl Method {
PublicRole::Private => MethodPayableMetadata::NotPayable,
}
}

pub fn is_allow_multiple_var_args(&self) -> bool {
match &self.public_role {
PublicRole::Init(init_metadata) => init_metadata.allow_multiple_var_args,
PublicRole::Endpoint(endpoint_metadata) => endpoint_metadata.allow_multiple_var_args,
PublicRole::Callback(callback_metadata)
| PublicRole::CallbackPromise(callback_metadata) => {
callback_metadata.allow_multiple_var_args
},
PublicRole::CallbackRaw => true,
PublicRole::Private => false,
}
}
}
1 change: 1 addition & 0 deletions framework/derive/src/parse/attributes/attr_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ pub(super) static ATTR_STORAGE_IS_EMPTY: &str = "storage_is_empty";
pub(super) static ATTR_STORAGE_CLEAR: &str = "storage_clear";
pub(super) static ATTR_PROXY: &str = "proxy";
pub(super) static ATTR_LABEL: &str = "label";
pub(super) static ATTR_ALLOW_MULTIPLE_VAR_ARGS: &str = "allow_multiple_var_args";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Run cargo fmt

4 changes: 4 additions & 0 deletions framework/derive/src/parse/attributes/endpoint_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ pub fn is_proxy(attr: &syn::Attribute) -> bool {
is_attribute_with_no_args(attr, ATTR_PROXY)
}

pub fn is_allow_multiple_var_args(attr: &syn::Attribute) -> bool {
is_attribute_with_no_args(attr, ATTR_ALLOW_MULTIPLE_VAR_ARGS)
}

#[derive(Clone, Debug)]
pub struct EndpointAttribute {
pub endpoint_name: Option<syn::Ident>,
Expand Down
4 changes: 4 additions & 0 deletions framework/derive/src/parse/attributes/trait_argument_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@ pub fn is_only_owner_prop(attr: &syn::Attribute) -> bool {
pub fn is_only_admin_prop(attr: &syn::Attribute) -> bool {
is_attribute_with_no_args(attr, PROP_ADMIN_OWNER)
}

pub fn is_allow_multiple_var_args_prop(attr: &syn::Attribute) -> bool {
is_attribute_with_no_args(attr, PROP_ALLOW_MULTIPLE_VAR_ARGS)
}
1 change: 1 addition & 0 deletions framework/derive/src/parse/attributes/trait_prop_names.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub(super) static PROP_ONLY_OWNER: &str = "only_owner";
pub(super) static PROP_ADMIN_OWNER: &str = "only_admin";
pub(super) static PROP_ALLOW_MULTIPLE_VAR_ARGS: &str = "allow_multiple_var_args";
24 changes: 21 additions & 3 deletions framework/derive/src/parse/endpoint_parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ use crate::model::{

use super::{
attributes::{
is_callback_raw, is_init, is_only_admin, is_only_owner, is_only_user_account,
CallbackAttribute, EndpointAttribute, ExternalViewAttribute, LabelAttribute,
OutputNameAttribute, PromisesCallbackAttribute, ViewAttribute,
is_allow_multiple_var_args, is_callback_raw, is_init, is_only_admin, is_only_owner,
is_only_user_account, CallbackAttribute, EndpointAttribute, ExternalViewAttribute,
LabelAttribute, OutputNameAttribute, PromisesCallbackAttribute, ViewAttribute,
},
MethodAttributesPass1,
};
Expand All @@ -27,13 +27,26 @@ pub fn process_init_attribute(
check_single_role(&*method);
method.public_role = PublicRole::Init(InitMetadata {
payable: pass_1_data.payable.clone(),
allow_multiple_var_args: pass_1_data.allow_multiple_var_args,
});
true
} else {
false
}
}

pub fn process_allow_multiple_var_args_attribute(
attr: &syn::Attribute,
pass_1_data: &mut MethodAttributesPass1,
) -> bool {
let is_allow_multiple_var_args = is_allow_multiple_var_args(attr);
if is_allow_multiple_var_args {
pass_1_data.allow_multiple_var_args = true;
}

is_allow_multiple_var_args
}

pub fn process_only_owner_attribute(
attr: &syn::Attribute,
pass_1_data: &mut MethodAttributesPass1,
Expand Down Expand Up @@ -86,6 +99,7 @@ pub fn process_endpoint_attribute(
only_admin: pass_1_data.only_admin,
only_user_account: pass_1_data.only_user_account,
mutability: EndpointMutabilityMetadata::Mutable,
allow_multiple_var_args: pass_1_data.allow_multiple_var_args,
});
})
.is_some()
Expand All @@ -110,6 +124,7 @@ pub fn process_view_attribute(
only_admin: pass_1_data.only_admin,
only_user_account: pass_1_data.only_user_account,
mutability: EndpointMutabilityMetadata::Readonly,
allow_multiple_var_args: pass_1_data.allow_multiple_var_args,
});
})
.is_some()
Expand All @@ -134,6 +149,7 @@ pub fn process_external_view_attribute(
only_admin: pass_1_data.only_admin,
only_user_account: pass_1_data.only_user_account,
mutability: EndpointMutabilityMetadata::Readonly,
allow_multiple_var_args: pass_1_data.allow_multiple_var_args,
});
})
.is_some()
Expand All @@ -159,6 +175,7 @@ pub fn process_callback_attribute(attr: &syn::Attribute, method: &mut Method) ->
};
method.public_role = PublicRole::Callback(CallbackMetadata {
callback_name: callback_ident,
allow_multiple_var_args: method.is_allow_multiple_var_args(),
});
})
.is_some()
Expand All @@ -174,6 +191,7 @@ pub fn process_promises_callback_attribute(attr: &syn::Attribute, method: &mut M
};
method.public_role = PublicRole::CallbackPromise(CallbackMetadata {
callback_name: callback_ident,
allow_multiple_var_args: method.is_allow_multiple_var_args(),
});
})
.is_some()
Expand Down
5 changes: 4 additions & 1 deletion framework/derive/src/parse/method_parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ use super::{
process_endpoint_attribute, process_external_view_attribute, process_init_attribute,
process_label_names_attribute, process_only_admin_attribute, process_only_owner_attribute,
process_only_user_account_attribute, process_output_names_attribute, process_payable_attribute,
process_promises_callback_attribute, process_view_attribute,
process_promises_callback_attribute, process_view_attribute, process_allow_multiple_var_args_attribute
};
pub struct MethodAttributesPass1 {
pub method_name: String,
pub payable: MethodPayableMetadata,
pub only_owner: bool,
pub only_admin: bool,
pub only_user_account: bool,
pub allow_multiple_var_args: bool
}

pub fn process_method(m: &syn::TraitItemMethod, trait_attributes: &TraitProperties) -> Method {
Expand All @@ -36,6 +37,7 @@ pub fn process_method(m: &syn::TraitItemMethod, trait_attributes: &TraitProperti
only_owner: trait_attributes.only_owner,
only_admin: trait_attributes.only_admin,
only_user_account: trait_attributes.only_user_account,
allow_multiple_var_args: trait_attributes.allow_multiple_var_args
};
let mut first_pass_unprocessed_attributes = Vec::new();

Expand Down Expand Up @@ -90,6 +92,7 @@ fn process_attribute_first_pass(
|| process_only_owner_attribute(attr, first_pass_data)
|| process_only_admin_attribute(attr, first_pass_data)
|| process_only_user_account_attribute(attr, first_pass_data)
|| process_allow_multiple_var_args_attribute(attr, first_pass_data)
}

fn process_attributes_second_pass(
Expand Down
12 changes: 12 additions & 0 deletions framework/derive/src/parse/trait_argument_parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ fn process_trait_attribute(
) -> bool {
process_only_owner_argument(attr, trait_arg_metadata)
|| process_only_admin_argument(attr, trait_arg_metadata)
|| process_allow_multiple_var_args_argument(attr, trait_arg_metadata)
}

fn process_only_owner_argument(attr: &syn::Attribute, arg_metadata: &mut TraitProperties) -> bool {
Expand All @@ -37,3 +38,14 @@ fn process_only_admin_argument(attr: &syn::Attribute, arg_metadata: &mut TraitPr
}
has_attr
}

fn process_allow_multiple_var_args_argument(
attr: &syn::Attribute,
arg_metadata: &mut TraitProperties,
) -> bool {
let has_attr = is_allow_multiple_var_args_prop(attr);
if has_attr {
arg_metadata.allow_multiple_var_args = true;
}
has_attr
}
Loading
Loading