src5_rs/core/parser/
cairo_struct.rs

1// Module for handling Cairo structs
2use cairo_lang_compiler::db::RootDatabase;
3use cairo_lang_syntax::node::kind::SyntaxKind;
4use cairo_lang_syntax::node::SyntaxNode;
5
6use super::ast::get_syntax_tree;
7use super::utils::find_children;
8
9#[derive(Debug)]
10pub struct CairoStruct {
11    pub name: String,
12    pub generics: Vec<String>,
13    pub members_types: Vec<SyntaxNode>,
14}
15
16pub fn get_corelib_structs(db: &RootDatabase) -> Vec<CairoStruct> {
17    // Get the syntax tree
18    let tree = get_syntax_tree(db, CORELIB_STRUCTS.into());
19
20    get_cairo_structs_no_corelib(db, &tree)
21}
22
23pub fn get_cairo_structs(db: &RootDatabase, syntax_tree: &SyntaxNode) -> Vec<CairoStruct> {
24    let mut cairo_structs = get_cairo_structs_no_corelib(db, syntax_tree);
25    // Include corelib structs
26    cairo_structs.extend(get_corelib_structs(db));
27    cairo_structs
28}
29
30pub fn get_cairo_structs_no_corelib(
31    db: &RootDatabase,
32    syntax_tree: &SyntaxNode,
33) -> Vec<CairoStruct> {
34    let mut cairo_structs = Vec::new();
35    for node in syntax_tree.descendants(db) {
36        if SyntaxKind::ItemStruct == node.kind(db) {
37            // Look up the Struct name
38            let id_node = find_children(db, &node, SyntaxKind::TerminalIdentifier).unwrap();
39            let struct_name = id_node.get_text_without_trivia(db);
40            let mut struct_members_types = Vec::new();
41            let mut struct_generics = Vec::new();
42
43            // Look up the Struct members types
44            let members_node = find_children(db, &node, SyntaxKind::MemberList).unwrap();
45            for node in members_node.descendants(db) {
46                if node.kind(db) == SyntaxKind::TypeClause {
47                    struct_members_types.push(node);
48                }
49            }
50            // Look up the Struct generics
51            if let Some(child) = find_children(db, &node, SyntaxKind::WrappedGenericParamList) {
52                for node in child.descendants(db) {
53                    if node.kind(db) == SyntaxKind::GenericParamType {
54                        let generic_type = node.get_text_without_trivia(db);
55                        struct_generics.push(generic_type);
56                    }
57                }
58            }
59            cairo_structs.push(CairoStruct {
60                name: struct_name,
61                generics: struct_generics,
62                members_types: struct_members_types,
63            });
64        }
65    }
66    cairo_structs
67}
68
69const CORELIB_STRUCTS: &str = "
70struct Span<T> {
71    snapshot: @Array<T>
72}
73struct Call {
74    to: ContractAddress,
75    selector: felt252,
76    calldata: Span<felt252>
77}
78struct EthAddress {
79    address: felt252,
80}
81struct ExecutionInfo {
82    block_info: Box<BlockInfo>,
83    tx_info: Box<TxInfo>,
84    caller_address: ContractAddress,
85    contract_address: ContractAddress,
86    entry_point_selector: felt252,
87}
88struct BlockInfo {
89    block_number: u64,
90    block_timestamp: u64,
91    sequencer_address: ContractAddress,
92}
93struct TxInfo {
94    version: felt252,
95    account_contract_address: ContractAddress,
96    max_fee: u128,
97    signature: Span<felt252>,
98    transaction_hash: felt252,
99    chain_id: felt252,
100    nonce: felt252,
101}
102struct u256 {
103    low: u128,
104    high: u128,
105}
106struct u512 {
107    limb0: u128,
108    limb1: u128,
109    limb2: u128,
110    limb3: u128,
111}
112struct Panic {}
113struct PoseidonBuiltinState {
114    s0: felt252,
115    s1: felt252,
116    s2: felt252,
117}
118struct ByteArray {
119    data: Array<bytes31>,
120    pending_word: felt252,
121    pending_word_len: usize,
122}
123";