Skip to content

Commit 8a30e33

Browse files
authored
Merge pull request #2068 from CosmWasm/aw/cosmwasm-derive-configurable
Make crate used in `entry_point` configurable
2 parents 66028ce + 9629722 commit 8a30e33

File tree

16 files changed

+132
-7
lines changed

16 files changed

+132
-7
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@ and this project adheres to
1111
- cosmwasm-vm: Add `secp256r1_verify` and `secp256r1_recover_pubkey` imports for
1212
ECDSA signature verification over secp256r1. ([#1983], [#2057], [#2058])
1313
- cosmwasm-vm: Add metrics for the pinned memory cache ([#2059])
14+
- cosmwasm-derive: The crate used in the expansion can now be renamed ([#2068])
1415

1516
[#1983]: https://github.com/CosmWasm/cosmwasm/pull/1983
1617
[#2057]: https://github.com/CosmWasm/cosmwasm/pull/2057
1718
[#2058]: https://github.com/CosmWasm/cosmwasm/pull/2058
19+
[#2068]: https://github.com/CosmWasm/cosmwasm/pull/2068
1820

1921
### Changed
2022

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contracts/burner/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contracts/crypto-verify/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contracts/cyberpunk/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contracts/empty/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contracts/floaty/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contracts/hackatom/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contracts/ibc-reflect-send/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contracts/ibc-reflect/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contracts/queue/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contracts/reflect/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contracts/staking/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contracts/virus/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/derive/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ proc-macro = true
1515
default = []
1616

1717
[dependencies]
18+
proc-macro2 = "1.0.79"
1819
quote = "1.0.35"
1920
syn = { version = "2", features = ["full"] }
2021

packages/derive/src/lib.rs

Lines changed: 116 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,50 @@
1-
use proc_macro::TokenStream;
2-
use quote::{format_ident, quote};
3-
use syn::parse_macro_input;
1+
use proc_macro2::TokenStream;
2+
use quote::{format_ident, quote, ToTokens};
3+
use syn::{
4+
parse::{Parse, ParseStream},
5+
parse_quote,
6+
punctuated::Punctuated,
7+
Token,
8+
};
9+
10+
macro_rules! maybe {
11+
($result:expr) => {{
12+
match { $result } {
13+
Ok(val) => val,
14+
Err(err) => return err.into_compile_error(),
15+
}
16+
}};
17+
}
18+
19+
struct Options {
20+
crate_path: syn::Path,
21+
}
22+
23+
impl Default for Options {
24+
fn default() -> Self {
25+
Self {
26+
crate_path: parse_quote!(::cosmwasm_std),
27+
}
28+
}
29+
}
30+
31+
impl Parse for Options {
32+
fn parse(input: ParseStream) -> syn::Result<Self> {
33+
let mut ret = Self::default();
34+
let attrs = Punctuated::<syn::MetaNameValue, Token![,]>::parse_terminated(input)?;
35+
36+
for kv in attrs {
37+
if kv.path.is_ident("crate") {
38+
let path_as_string: syn::LitStr = syn::parse2(kv.value.to_token_stream())?;
39+
ret.crate_path = path_as_string.parse()?
40+
} else {
41+
return Err(syn::Error::new_spanned(kv, "Unknown attribute"));
42+
}
43+
}
44+
45+
Ok(ret)
46+
}
47+
}
448

549
/// This attribute macro generates the boilerplate required to call into the
650
/// contract-specific logic from the entry-points to the Wasm module.
@@ -50,9 +94,17 @@ use syn::parse_macro_input;
5094
/// where `InstantiateMsg`, `ExecuteMsg`, and `QueryMsg` are contract defined
5195
/// types that implement `DeserializeOwned + JsonSchema`.
5296
#[proc_macro_attribute]
53-
pub fn entry_point(_attr: TokenStream, mut item: TokenStream) -> TokenStream {
97+
pub fn entry_point(
98+
attr: proc_macro::TokenStream,
99+
item: proc_macro::TokenStream,
100+
) -> proc_macro::TokenStream {
101+
entry_point_impl(attr.into(), item.into()).into()
102+
}
103+
104+
fn entry_point_impl(attr: TokenStream, mut item: TokenStream) -> TokenStream {
54105
let cloned = item.clone();
55-
let function = parse_macro_input!(cloned as syn::ItemFn);
106+
let function: syn::ItemFn = maybe!(syn::parse2(cloned));
107+
let Options { crate_path } = maybe!(syn::parse2(attr));
56108

57109
// The first argument is `deps`, the rest is region pointers
58110
let args = function.sig.inputs.len() - 1;
@@ -68,11 +120,68 @@ pub fn entry_point(_attr: TokenStream, mut item: TokenStream) -> TokenStream {
68120
mod #wasm_export { // new module to avoid conflict of function name
69121
#[no_mangle]
70122
extern "C" fn #fn_name(#( #decl_args : u32 ),*) -> u32 {
71-
cosmwasm_std::#do_call(&super::#fn_name, #( #call_args ),*)
123+
#crate_path::#do_call(&super::#fn_name, #( #call_args ),*)
72124
}
73125
}
74126
};
75127

76-
item.extend(TokenStream::from(new_code));
128+
item.extend(new_code);
77129
item
78130
}
131+
132+
#[cfg(test)]
133+
mod test {
134+
use proc_macro2::TokenStream;
135+
use quote::quote;
136+
137+
use crate::entry_point_impl;
138+
139+
#[test]
140+
fn default_expansion() {
141+
let code = quote! {
142+
fn instantiate(deps: DepsMut, env: Env) -> Response {
143+
// Logic here
144+
}
145+
};
146+
147+
let actual = entry_point_impl(TokenStream::new(), code);
148+
let expected = quote! {
149+
fn instantiate(deps: DepsMut, env: Env) -> Response { }
150+
151+
#[cfg(target_arch = "wasm32")]
152+
mod __wasm_export_instantiate {
153+
#[no_mangle]
154+
extern "C" fn instantiate(ptr_0: u32) -> u32 {
155+
::cosmwasm_std::do_instantiate(&super::instantiate, ptr_0)
156+
}
157+
}
158+
};
159+
160+
assert_eq!(actual.to_string(), expected.to_string());
161+
}
162+
163+
#[test]
164+
fn renamed_expansion() {
165+
let attribute = quote!(crate = "::my_crate::cw_std");
166+
let code = quote! {
167+
fn instantiate(deps: DepsMut, env: Env) -> Response {
168+
// Logic here
169+
}
170+
};
171+
172+
let actual = entry_point_impl(attribute, code);
173+
let expected = quote! {
174+
fn instantiate(deps: DepsMut, env: Env) -> Response { }
175+
176+
#[cfg(target_arch = "wasm32")]
177+
mod __wasm_export_instantiate {
178+
#[no_mangle]
179+
extern "C" fn instantiate(ptr_0: u32) -> u32 {
180+
::my_crate::cw_std::do_instantiate(&super::instantiate, ptr_0)
181+
}
182+
}
183+
};
184+
185+
assert_eq!(actual.to_string(), expected.to_string());
186+
}
187+
}

0 commit comments

Comments
 (0)