/// Resolve an event. We should only be resolving events for emit statements
Resolve an event. We should only be resolving events for emit statements
Resolve an event . We should only be resolving events for emit statements
pub fn resolve_event(
        &mut self,
        file_no: usize,
        contract_no: Option<usize>,
        expr: &pt::Expression,
        diagnostics: &mut Vec<ast::Diagnostic>,
    ) -> Result<Vec<usize>, ()> {
        let (namespace, id, dimensions) =
            self.expr_to_type(file_no, contract_no, expr, diagnostics)?;
        if !dimensions.is_empty() {
            diagnostics.push(ast::Diagnostic::decl_error(
                expr.loc(),
                "array type found where event type expected".to_string(),
            ));
            return Err(());
        }
        let id = match id {
            pt::Expression::Variable(id) => id,
            _ => {
                diagnostics.push(ast::Diagnostic::decl_error(
                    expr.loc(),
                    "expression found where event type expected".to_string(),
                ));
                return Err(());
            }
        };
        // if we are resolving an event name without namespace (so no explicit contract name
        // or import symbol), then we should look both in the current contract and global scope
        if namespace.is_empty() {
            let mut events = Vec::new();
            // If we're in a contract, then event can be defined in current contract or its bases
            if let Some(contract_no) = contract_no {
                for contract_no in visit_bases(contract_no, self).into_iter().rev() {
                    match self
                        .symbols
                        .get(&(file_no, Some(contract_no), id.name.to_owned()))
                    {
                        None => (),
                        Some(ast::Symbol::Event(ev)) => {
                            for (_, event_no) in ev {
                                events.push(*event_no);
                            }
                        }
                        sym => {
                            let error = ast::Namespace::wrong_symbol(sym, &id);
                            diagnostics.push(error);
                            return Err(());
                        }
                    }
                }
            }
            return match self.symbols.get(&(file_no, None, id.name.to_owned())) {
                None if events.is_empty() => {
                    diagnostics.push(ast::Diagnostic::decl_error(
                        id.loc,
                        format!("event ‘{}’ not found", id.name),
                    ));
                    Err(())
                }
                None => Ok(events),
                Some(ast::Symbol::Event(ev)) => {
                    for (_, event_no) in ev {
                        events.push(*event_no);
                    }
                    Ok(events)
                }
                sym => {
                    let error = ast::Namespace::wrong_symbol(sym, &id);
                    diagnostics.push(error);
                    Err(())
                }
            };
        }
        let s = self.resolve_namespace(namespace, file_no, contract_no, &id, diagnostics)?;
        if let Some(ast::Symbol::Event(events)) = s {
            Ok(events.iter().map(|(_, event_no)| *event_no).collect())
        } else {
            let error = ast::Namespace::wrong_symbol(s, &id);
            diagnostics.push(error);
            Err(())
        }
    }
pub fn resolve_event ( & mut self , file_no : usize , contract_no : Option < usize > , expr : & pt :: Expression , diagnostics : & mut Vec < ast :: Diagnostic > , ) -> Result < Vec < usize > , ( ) > { let ( namespace , id , dimensions ) = self . expr_to_type ( file_no , contract_no , expr , diagnostics ) ? ; if ! dimensions . is_empty ( ) { diagnostics . push ( ast :: Diagnostic :: decl_error ( expr . loc ( ) , " " . to_string ( ) , ) ) ; return Err ( ( ) ) ; } let id = match id { pt :: Expression :: Variable ( id ) => id , _ => { diagnostics . push ( ast :: Diagnostic :: decl_error ( expr . loc ( ) , " " . to_string ( ) , ) ) ; return Err ( ( ) ) ; } } ; // if we are resolving an event name without namespace (so no explicit contract name // or import symbol), then we should look both in the current contract and global scope if namespace . is_empty ( ) { let mut events = Vec :: new ( ) ; // If we're in a contract, then event can be defined in current contract or its bases if let Some ( contract_no ) = contract_no { for contract_no in visit_bases ( contract_no , self ) . into_iter ( ) . rev ( ) { match self . symbols . get ( & ( file_no , Some ( contract_no ) , id . name . to_owned ( ) ) ) { None => ( ) , Some ( ast :: Symbol :: Event ( ev ) ) => { for ( _ , event_no ) in ev { events . push ( * event_no ) ; } } sym => { let error = ast :: Namespace :: wrong_symbol ( sym , & id ) ; diagnostics . push ( error ) ; return Err ( ( ) ) ; } } } } return match self . symbols . get ( & ( file_no , None , id . name . to_owned ( ) ) ) { None if events . is_empty ( ) => { diagnostics . push ( ast :: Diagnostic :: decl_error ( id . loc , format ! ( " d am ), ) ) ; Err ( ( ) ) } None => Ok ( events ) , Some ( ast :: Symbol :: Event ( ev ) ) => { for ( _ , event_no ) in ev { events . push ( * event_no ) ; } Ok ( events ) } sym => { let error = ast :: Namespace :: wrong_symbol ( sym , & id ) ; diagnostics . push ( error ) ; Err ( ( ) ) } } ; } let s = self . resolve_namespace ( namespace , file_no , contract_no , & id , diagnostics ) ? ; if let Some ( ast :: Symbol :: Event ( events ) ) = s { Ok ( events . iter ( ) . map ( | ( _ , event_no ) | * event_no ) . collect ( ) ) } else { let error = ast :: Namespace :: wrong_symbol ( s , & id ) ; diagnostics . push ( error ) ; Err ( ( ) ) } }
Resolve an event.
Resolve an event .
&mut self
file_no
usize
contract_no
Option<usize>
expr
&pt::Expression
diagnostics
&mut Vec<ast::Diagnostic>