use ra_ap_syntax::ast;
use crate::{Constructor, Error, Event, InkE2ETest, InkImpl, InkTest, Message, Storage};
#[ink_analyzer_macro::entity(macro_kind = Contract)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Contract {
ast: ast::Module,
storage: Option<Storage>,
events: Vec<Event>,
errors: Vec<Error>,
#[initializer(call = crate::tree::utils::ink_impl_closest_descendants)]
impls: Vec<InkImpl>,
#[initializer(call = crate::tree::utils::ink_callable_closest_descendants)]
constructors: Vec<Constructor>,
#[initializer(call = crate::tree::utils::ink_callable_closest_descendants)]
messages: Vec<Message>,
tests: Vec<InkTest>,
e2e_tests: Vec<InkE2ETest>,
}
impl_has_ink_environment!(Contract, Env);
impl Contract {
impl_pub_ast_type_getter!(module, Module);
impl_pub_ink_arg_getter!(keep_attr_arg, KeepAttr, keep_attr);
}
#[cfg(test)]
mod tests {
use super::*;
use crate::test_utils::*;
use crate::traits::{HasInkEnvironment, InkEntity};
use test_utils::quote_as_str;
#[test]
fn cast_works() {
let node = parse_first_syntax_node(quote_as_str! {
#[ink::contract(env=crate::MyEnvironment, keep_attr="foo,bar")]
mod MyContract {
#[ink(storage)]
pub struct MyContract {}
#[ink(event)]
pub struct MyEvent {
}
#[ink(event, anonymous)]
pub struct MyEvent2 {
}
#[ink::error]
pub struct Error;
impl MyContract {
#[ink(constructor, payable, default, selector=_)]
pub fn my_constructor() -> Self {}
#[ink(message, payable, default, selector=_)]
pub fn my_message(&self) {}
}
impl MyTrait for MyContract {
#[ink(constructor, payable, default, selector=1)]
fn my_constructor() -> Self {}
#[ink(message, payable, default, selector=1)]
fn my_message(&self) {}
}
impl ::my_full::long_path::MyTrait for MyContract {
#[ink(constructor, payable, default, selector=0x2)]
fn my_constructor() -> Self {}
#[ink(message, payable, default, selector=0x2)]
fn my_message(&self) {}
}
impl relative_path::MyTrait for MyContract {
#[ink(constructor)]
fn my_constructor() -> Self {}
#[ink(message)]
fn my_message(&self) {}
}
#[ink(namespace="my_namespace")]
impl MyContract {
#[ink(constructor)]
pub fn my_constructor() -> Self {}
#[ink(message)]
pub fn my_message(&self) {}
}
#[ink(impl)]
impl MyContract {
#[ink(constructor)]
pub fn my_constructor() -> Self {}
#[ink(message)]
pub fn my_message(&self) {}
}
#[ink(impl, namespace="my_namespace")]
impl MyContract {
#[ink(constructor)]
pub fn my_constructor() -> Self {}
#[ink(message)]
pub fn my_message(&self) {}
}
#[ink(impl)]
impl MyContract {
}
#[cfg(test)]
mod tests {
#[ink::test]
fn it_works {
}
#[ink::test]
fn it_works2 {
}
}
}
#[derive(Clone)]
pub struct MyEnvironment;
impl ink::env::Environment for MyEnvironment {
const MAX_EVENT_TOPICS: usize = 3;
type AccountId = [u8; 16];
type Balance = u128;
type Hash = [u8; 32];
type Timestamp = u64;
type BlockNumber = u32;
type ChainExtension = ::ink::env::NoChainExtension;
}
});
let contract = Contract::cast(node).unwrap();
assert!(contract.env_arg().is_some());
assert!(contract.environment().is_some());
assert!(contract.keep_attr_arg().is_some());
assert!(contract.storage().is_some());
assert_eq!(contract.events().len(), 2);
assert_eq!(contract.errors().len(), 1);
assert_eq!(contract.impls().len(), 8);
assert_eq!(contract.constructors().len(), 7);
assert_eq!(contract.messages().len(), 7);
assert_eq!(contract.tests().len(), 2);
assert!(contract.module().is_some());
}
}