use ink_analyzer_macro::FromAST;
use ra_ap_syntax::{AstNode, SourceFile};
use crate::traits::FromAST;
use crate::tree::utils;
use crate::{ChainExtension, Contract, InkE2ETest, InkTest, StorageItem, TraitDefinition};
#[derive(Debug, Clone, PartialEq, Eq, FromAST)]
pub struct InkFile {
contracts: Vec<Contract>,
trait_definitions: Vec<TraitDefinition>,
chain_extensions: Vec<ChainExtension>,
storage_items: Vec<StorageItem>,
tests: Vec<InkTest>,
e2e_tests: Vec<InkE2ETest>,
ast: SourceFile,
}
impl From<SourceFile> for InkFile {
fn from(file: SourceFile) -> Self {
Self {
contracts: utils::ink_closest_descendants(file.syntax()).collect(),
trait_definitions: utils::ink_contract_peekable_quasi_closest_descendants(
file.syntax(),
)
.collect(),
chain_extensions: utils::ink_contract_peekable_quasi_closest_descendants(file.syntax())
.collect(),
storage_items: utils::ink_contract_peekable_quasi_closest_descendants(file.syntax())
.collect(),
tests: utils::ink_closest_descendants(file.syntax()).collect(),
e2e_tests: utils::ink_closest_descendants(file.syntax()).collect(),
ast: file,
}
}
}
impl InkFile {
pub fn parse(code: &str) -> Self {
Self::from(SourceFile::parse(code).tree())
}
pub fn contracts(&self) -> &[Contract] {
&self.contracts
}
pub fn trait_definitions(&self) -> &[TraitDefinition] {
&self.trait_definitions
}
pub fn chain_extensions(&self) -> &[ChainExtension] {
&self.chain_extensions
}
pub fn storage_items(&self) -> &[StorageItem] {
&self.storage_items
}
pub fn tests(&self) -> &[InkTest] {
&self.tests
}
pub fn e2e_tests(&self) -> &[InkE2ETest] {
&self.e2e_tests
}
}
#[cfg(test)]
mod tests {
use super::*;
use test_utils::quote_as_str;
#[test]
fn parse_works() {
let file = InkFile::parse(quote_as_str! {
#[ink::contract]
mod my_contract {
}
#[ink::trait_definition]
pub trait MyTrait {
}
#[ink::chain_extension]
pub trait MyChainExtension {
}
#[ink::storage_item]
struct MyStorageItem {
}
#[ink::storage_item]
struct MyStorageItem2 {
}
#[cfg(test)]
mod tests {
#[ink::test]
fn it_works {
}
#[ink::test]
fn it_works2 {
}
}
});
assert_eq!(file.contracts().len(), 1);
assert_eq!(file.trait_definitions().len(), 1);
assert_eq!(file.chain_extensions().len(), 1);
assert_eq!(file.storage_items().len(), 2);
assert_eq!(file.tests().len(), 2);
}
}