pub fn add_external_functions(contract_no: usize, ns: &mut Namespace) {
    let mut call_list = CallList::default();

    for var in &ns.contracts[contract_no].variables {
        if let Some(init) = &var.initializer {
            init.recurse(&mut call_list, check_expression);
        }
    }

    for function_no in ns.contracts[contract_no].all_functions.keys() {
        let func = &ns.functions[*function_no];

        for stmt in &func.body {
            stmt.recurse(&mut call_list, check_statement);
        }
    }

    // we've now collected all the functions which are called.
    while !call_list.solidity.is_empty() {
        let mut new_call_list = CallList::default();

        for function_no in &call_list.solidity {
            let func = &ns.functions[*function_no];

            for stmt in &func.body {
                stmt.recurse(&mut new_call_list, check_statement);
            }
        }

        // add functions to contract functions list
        for function_no in &call_list.solidity {
            ns.contracts[contract_no]
                .all_functions
                .insert(*function_no, usize::MAX);
        }

        for yul_function_no in &call_list.yul {
            ns.contracts[contract_no]
                .yul_functions
                .push(*yul_function_no);
        }

        call_list.solidity.clear();
        call_list.yul.clear();

        for function_no in &new_call_list.solidity {
            if !ns.contracts[contract_no]
                .all_functions
                .contains_key(function_no)
            {
                call_list.solidity.insert(*function_no);
            }
        }

        for yul_func_no in &new_call_list.yul {
            ns.contracts[contract_no].yul_functions.push(*yul_func_no);
        }
    }

    // now that we have the final list of functions, we can populate the list
    // of events this contract emits
    let mut send_events = Vec::new();

    for function_no in ns.contracts[contract_no].all_functions.keys() {
        let func = &ns.functions[*function_no];

        for event_no in &func.emits_events {
            if !send_events.contains(event_no) {
                send_events.push(*event_no);
            }
        }
    }

    ns.contracts[contract_no].sends_events = send_events;
}
/// After generating the AST for a contract, we should have a list of
/// all the functions a contract calls in `all_functions`. This should
/// include any libraries and global functions
After generating the AST for a contract, we should have a list of
all the functions a contract calls in `all_functions`. This should
include any libraries and global functions
After generating the AST for a contract we should have a list of all the functions a contract calls in ` all_functions ` . This should include any libraries and global functions
pub fn add_external_functions(contract_no: usize, ns: &mut Namespace) {
    let mut call_list = CallList::default();
    for var in &ns.contracts[contract_no].variables {
        if let Some(init) = &var.initializer {
            init.recurse(&mut call_list, check_expression);
        }
    }
    for function_no in ns.contracts[contract_no].all_functions.keys() {
        let func = &ns.functions[*function_no];
        for stmt in &func.body {
            stmt.recurse(&mut call_list, check_statement);
        }
    }
    // we've now collected all the functions which are called.
    while !call_list.solidity.is_empty() {
        let mut new_call_list = CallList::default();
        for function_no in &call_list.solidity {
            let func = &ns.functions[*function_no];
            for stmt in &func.body {
                stmt.recurse(&mut new_call_list, check_statement);
            }
        }
        // add functions to contract functions list
        for function_no in &call_list.solidity {
            ns.contracts[contract_no]
                .all_functions
                .insert(*function_no, usize::MAX);
        }
        for yul_function_no in &call_list.yul {
            ns.contracts[contract_no]
                .yul_functions
                .push(*yul_function_no);
        }
        call_list.solidity.clear();
        call_list.yul.clear();
        for function_no in &new_call_list.solidity {
            if !ns.contracts[contract_no]
                .all_functions
                .contains_key(function_no)
            {
                call_list.solidity.insert(*function_no);
            }
        }
        for yul_func_no in &new_call_list.yul {
            ns.contracts[contract_no].yul_functions.push(*yul_func_no);
        }
    }
    // now that we have the final list of functions, we can populate the list
    // of events this contract emits
    let mut send_events = Vec::new();
    for function_no in ns.contracts[contract_no].all_functions.keys() {
        let func = &ns.functions[*function_no];
        for event_no in &func.emits_events {
            if !send_events.contains(event_no) {
                send_events.push(*event_no);
            }
        }
    }
    ns.contracts[contract_no].sends_events = send_events;
}
pub fn add_external_functions ( contract_no : usize , ns : & mut Namespace ) { let mut call_list = CallList :: default ( ) ; for var in & ns . contracts [ contract_no ] . variables { if let Some ( init ) = & var . initializer { init . recurse ( & mut call_list , check_expression ) ; } } for function_no in ns . contracts [ contract_no ] . all_functions . keys ( ) { let func = & ns . functions [ * function_no ] ; for stmt in & func . body { stmt . recurse ( & mut call_list , check_statement ) ; } } // we've now collected all the functions which are called. while ! call_list . solidity . is_empty ( ) { let mut new_call_list = CallList :: default ( ) ; for function_no in & call_list . solidity { let func = & ns . functions [ * function_no ] ; for stmt in & func . body { stmt . recurse ( & mut new_call_list , check_statement ) ; } } // add functions to contract functions list for function_no in & call_list . solidity { ns . contracts [ contract_no ] . all_functions . insert ( * function_no , usize :: MAX ) ; } for yul_function_no in & call_list . yul { ns . contracts [ contract_no ] . yul_functions . push ( * yul_function_no ) ; } call_list . solidity . clear ( ) ; call_list . yul . clear ( ) ; for function_no in & new_call_list . solidity { if ! ns . contracts [ contract_no ] . all_functions . contains_key ( function_no ) { call_list . solidity . insert ( * function_no ) ; } } for yul_func_no in & new_call_list . yul { ns . contracts [ contract_no ] . yul_functions . push ( * yul_func_no ) ; } } // now that we have the final list of functions, we can populate the list // of events this contract emits let mut send_events = Vec :: new ( ) ; for function_no in ns . contracts [ contract_no ] . all_functions . keys ( ) { let func = & ns . functions [ * function_no ] ; for event_no in & func . emits_events { if ! send_events . contains ( event_no ) { send_events . push ( * event_no ) ; } } } ns . contracts [ contract_no ] . sends_events = send_events ; }
After generating the AST for a contract, we should have a list of
all the functions a contract calls in `all_functions`.
After generating the AST for a contract we should have a list of all the functions a contract calls in ` all_functions ` .
contract_no
usize
ns
&mut Namespace
contract_no
usize
ns
&mut Namespace