--- a/crates/evm-coder-macros/src/lib.rs
+++ b/crates/evm-coder-macros/src/lib.rs
@@ -22,7 +22,7 @@
use sha3::{Digest, Keccak256};
use syn::{
DeriveInput, GenericArgument, Ident, ItemImpl, Pat, Path, PathArguments,
- PathSegment, Type, parse_macro_input, spanned::Spanned, Attribute, parse::Parse,
+ PathSegment, Type, parse_macro_input, spanned::Spanned,
};
mod solidity_interface;
@@ -241,7 +241,7 @@
/// Event(#[indexed] uint32),
/// }
///
-/// #[solidity_interface(name = "MyContract", is(SuperContract), inline_is(InlineContract))]
+/// #[solidity_interface(name = MyContract, is(SuperContract), inline_is(InlineContract))]
/// impl Contract {
/// /// Multiply two numbers
/// #[weight(200 + a + b)]
--- a/crates/evm-coder-macros/src/solidity_interface.rs
+++ b/crates/evm-coder-macros/src/solidity_interface.rs
@@ -989,26 +989,24 @@
#solidity_functions,
)*),
};
- if is_impl {
- tc.collect("/// @dev common stubs holder\ncontract Dummy {\n\tuint8 dummy;\n\tstring stub_error = \"this contract is implemented in native\";\n}\ncontract ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool) {\n\t\trequire(false, stub_error);\n\t\tinterfaceID;\n\t\treturn true;\n\t}\n}\n".into());
- } else {
- tc.collect("/// @dev common stubs holder\ninterface Dummy {\n}\ninterface ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n".into());
- }
- #(
- #solidity_generators
- )*
- #(
- #solidity_event_generators
- )*
let mut out = string::new();
- // In solidity interface usage (is) should be preceeded by interface definition
- // HACK: this comment helps to sort it in a set
if #solidity_name.starts_with("Inline") {
out.push_str("/// @dev inlined interface\n");
}
let _ = interface.format(is_impl, &mut out, tc);
tc.collect(out);
+ #(
+ #solidity_event_generators
+ )*
+ #(
+ #solidity_generators
+ )*
+ if is_impl {
+ tc.collect("/// @dev common stubs holder\ncontract Dummy {\n\tuint8 dummy;\n\tstring stub_error = \"this contract is implemented in native\";\n}\ncontract ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool) {\n\t\trequire(false, stub_error);\n\t\tinterfaceID;\n\t\treturn true;\n\t}\n}\n".into());
+ } else {
+ tc.collect("/// @dev common stubs holder\ninterface Dummy {\n}\ninterface ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n".into());
+ }
}
}
impl #gen_ref ::evm_coder::Call for #call_name #gen_ref {
--- a/crates/evm-coder/src/solidity.rs
+++ b/crates/evm-coder/src/solidity.rs
@@ -14,26 +14,31 @@
// You should have received a copy of the GNU General Public License
// along with Unique Network. If not, see .
+//! Implementation detail of [`evm_coder::solidity_interface`] macro code-generation
+
#[cfg(not(feature = "std"))]
use alloc::{
string::String,
vec::Vec,
- collections::{BTreeSet, BTreeMap},
+ collections::BTreeMap,
format,
};
#[cfg(feature = "std")]
-use std::collections::{BTreeSet, BTreeMap};
+use std::collections::BTreeMap;
use core::{
fmt::{self, Write},
marker::PhantomData,
cell::{Cell, RefCell},
+ cmp::Reverse,
};
use impl_trait_for_tuples::impl_for_tuples;
use crate::types::*;
#[derive(Default)]
pub struct TypeCollector {
- structs: RefCell>,
+ /// Code => id
+ /// id ordering is required to perform topo-sort on the resulting data
+ structs: RefCell>,
anonymous: RefCell, usize>>,
id: Cell,
}
@@ -42,7 +47,8 @@
Self::default()
}
pub fn collect(&self, item: string) {
- self.structs.borrow_mut().insert(item);
+ let id = self.next_id();
+ self.structs.borrow_mut().insert(item, id);
}
pub fn next_id(&self) -> usize {
let v = self.id.get();
@@ -66,8 +72,10 @@
self.anonymous.borrow_mut().insert(names, id);
format!("Tuple{}", id)
}
- pub fn finish(self) -> BTreeSet {
- self.structs.into_inner()
+ pub fn finish(self) -> Vec {
+ let mut data = self.structs.into_inner().into_iter().collect::>();
+ data.sort_by_key(|(_, id)| Reverse(*id));
+ data.into_iter().map(|(code, _)| code).collect()
}
}