/// Try to resolve expression as an enum value. An enum can be prefixed
/// with import symbols, contract namespace before the enum type
Try to resolve expression as an enum value. An enum can be prefixed
with import symbols, contract namespace before the enum type
Try to resolve expression as an enum value . An enum can be prefixed with import symbols contract namespace before the enum type
fn enum_value(
    loc: &pt::Loc,
    expr: &pt::Expression,
    id: &pt::Identifier,
    file_no: usize,
    contract_no: Option<usize>,
    ns: &Namespace,
    diagnostics: &mut Vec<Diagnostic>,
) -> Result<Option<Expression>, ()> {
    let mut namespace = Vec::new();
    let mut expr = expr;
    // the first element of the path is the deepest in the parse tree,
    // so walk down and add to a list
    while let pt::Expression::MemberAccess(_, member, name) = expr {
        namespace.push(name);
        expr = member.as_ref();
    }
    if let pt::Expression::Variable(name) = expr {
        namespace.push(name);
    } else {
        return Ok(None);
    }
    // The leading part of the namespace can be import variables
    let mut file_no = file_no;
    // last element in our namespace vector is first element
    while let Some(name) = namespace.last().map(|f| f.name.clone()) {
        if let Some(Symbol::Import(_, import_file_no)) = ns.symbols.get(&(file_no, None, name)) {
            file_no = *import_file_no;
            namespace.pop();
        } else {
            break;
        }
    }
    if namespace.is_empty() {
        return Ok(None);
    }
    let mut contract_no = contract_no;
    if let Some(no) = ns.resolve_contract(file_no, namespace.last().unwrap()) {
        contract_no = Some(no);
        namespace.pop();
    }
    if namespace.len() != 1 {
        return Ok(None);
    }
    if let Some(e) = ns.resolve_enum(file_no, contract_no, namespace[0]) {
        match ns.enums[e].values.get(&id.name) {
            Some((_, val)) => Ok(Some(Expression::NumberLiteral(
                *loc,
                Type::Enum(e),
                BigInt::from_usize(*val).unwrap(),
            ))),
            None => {
                diagnostics.push(Diagnostic::error(
                    id.loc,
                    format!("enum {} does not have value {}", ns.enums[e], id.name),
                ));
                Err(())
            }
        }
    } else {
        Ok(None)
    }
}
fn enum_value ( loc : & pt :: Loc , expr : & pt :: Expression , id : & pt :: Identifier , file_no : usize , contract_no : Option < usize > , ns : & Namespace , diagnostics : & mut Vec < Diagnostic > , ) -> Result < Option < Expression > , ( ) > { let mut namespace = Vec :: new ( ) ; let mut expr = expr ; // the first element of the path is the deepest in the parse tree, // so walk down and add to a list while let pt :: Expression :: MemberAccess ( _ , member , name ) = expr { namespace . push ( name ) ; expr = member . as_ref ( ) ; } if let pt :: Expression :: Variable ( name ) = expr { namespace . push ( name ) ; } else { return Ok ( None ) ; } // The leading part of the namespace can be import variables let mut file_no = file_no ; // last element in our namespace vector is first element while let Some ( name ) = namespace . last ( ) . map ( | f | f . name . clone ( ) ) { if let Some ( Symbol :: Import ( _ , import_file_no ) ) = ns . symbols . get ( & ( file_no , None , name ) ) { file_no = * import_file_no ; namespace . pop ( ) ; } else { break ; } } if namespace . is_empty ( ) { return Ok ( None ) ; } let mut contract_no = contract_no ; if let Some ( no ) = ns . resolve_contract ( file_no , namespace . last ( ) . unwrap ( ) ) { contract_no = Some ( no ) ; namespace . pop ( ) ; } if namespace . len ( ) != 1 { return Ok ( None ) ; } if let Some ( e ) = ns . resolve_enum ( file_no , contract_no , namespace [ 0 ] ) { match ns . enums [ e ] . values . get ( & id . name ) { Some ( ( _ , val ) ) => Ok ( Some ( Expression :: NumberLiteral ( * loc , Type :: Enum ( e ) , BigInt :: from_usize ( * val ) . unwrap ( ) , ) ) ) , None => { diagnostics . push ( Diagnostic :: error ( id . loc , format ! ( " " ns enums [ e ] id name ) , ) ) ; Err ( ( ) ) } } } else { Ok ( None ) } }
Try to resolve expression as an enum value.
Try to resolve expression as an enum value .
loc
&pt::Loc
expr
&pt::Expression
id
&pt::Identifier
file_no
usize
contract_no
Option<usize>
ns
&Namespace
diagnostics
&mut Vec<Diagnostic>