/// Resolve the type name with the namespace to a symbol
Resolve the type name with the namespace to a symbol
Resolve the type name with the namespace to a symbol
fn resolve_namespace(
        &self,
        mut namespace: Vec<&pt::Identifier>,
        file_no: usize,
        mut contract_no: Option<usize>,
        id: &pt::Identifier,
        diagnostics: &mut Vec<Diagnostic>,
    ) -> Result<Option<&ast::Symbol>, ()> {
        // The leading part of the namespace can be import variables
        let mut import_file_no = file_no;
        while !namespace.is_empty() {
            if let Some(ast::Symbol::Import(_, file_no)) =
                self.symbols
                    .get(&(import_file_no, None, namespace[0].name.clone()))
            {
                import_file_no = *file_no;
                namespace.remove(0);
                contract_no = None;
            } else {
                break;
            }
        }
        if let Some(contract_name) = namespace.get(0) {
            contract_no =
                match self
                    .symbols
                    .get(&(import_file_no, None, contract_name.name.clone()))
                {
                    None => {
                        diagnostics.push(ast::Diagnostic::decl_error(
                            id.loc,
                            format!("contract type ‘{}’ not found", id.name),
                        ));
                        return Err(());
                    }
                    Some(ast::Symbol::Contract(_, n)) => {
                        if namespace.len() > 1 {
                            diagnostics.push(ast::Diagnostic::decl_error(
                                id.loc,
                                format!("‘{}’ not found", namespace[1].name),
                            ));
                            return Err(());
                        };
                        Some(*n)
                    }
                    Some(ast::Symbol::Function(_)) => {
                        diagnostics.push(ast::Diagnostic::decl_error(
                            id.loc,
                            format!("‘{}’ is a function", id.name),
                        ));
                        return Err(());
                    }
                    Some(ast::Symbol::Variable(_, _, _)) => {
                        diagnostics.push(ast::Diagnostic::decl_error(
                            id.loc,
                            format!("‘{}’ is a contract variable", id.name),
                        ));
                        return Err(());
                    }
                    Some(ast::Symbol::Event(_)) => {
                        diagnostics.push(ast::Diagnostic::decl_error(
                            id.loc,
                            format!("‘{}’ is an event", id.name),
                        ));
                        return Err(());
                    }
                    Some(ast::Symbol::Struct(_, _)) => {
                        diagnostics.push(ast::Diagnostic::decl_error(
                            id.loc,
                            format!("‘{}’ is a struct", id.name),
                        ));
                        return Err(());
                    }
                    Some(ast::Symbol::Enum(_, _)) => {
                        diagnostics.push(ast::Diagnostic::decl_error(
                            id.loc,
                            format!("‘{}’ is an enum variable", id.name),
                        ));
                        return Err(());
                    }
                    Some(ast::Symbol::Import(_, _)) => unreachable!(),
                };
        }
        let mut s = self
            .symbols
            .get(&(import_file_no, contract_no, id.name.to_owned()));
        if let Some(contract_no) = contract_no {
            // check bases contracts
            if s.is_none() {
                if let Some(sym) = self.resolve_base_contract(contract_no, &id) {
                    s = Some(sym);
                }
            }
            // try global scope
            if s.is_none() {
                s = self
                    .symbols
                    .get(&(import_file_no, None, id.name.to_owned()));
            }
        }
        Ok(s)
    }
fn resolve_namespace ( & self , mut namespace : Vec < & pt :: Identifier > , file_no : usize , mut contract_no : Option < usize > , id : & pt :: Identifier , diagnostics : & mut Vec < Diagnostic > , ) -> Result < Option < & ast :: Symbol > , ( ) > { // The leading part of the namespace can be import variables let mut import_file_no = file_no ; while ! namespace . is_empty ( ) { if let Some ( ast :: Symbol :: Import ( _ , file_no ) ) = self . symbols . get ( & ( import_file_no , None , namespace [ 0 ] . name . clone ( ) ) ) { import_file_no = * file_no ; namespace . remove ( 0 ) ; contract_no = None ; } else { break ; } } if let Some ( contract_name ) = namespace . get ( 0 ) { contract_no = match self . symbols . get ( & ( import_file_no , None , contract_name . name . clone ( ) ) ) { None => { diagnostics . push ( ast :: Diagnostic :: decl_error ( id . loc , format ! ( " d am ), ) ) ; return Err ( ( ) ) ; } Some ( ast :: Symbol :: Contract ( _ , n ) ) => { if namespace . len ( ) > 1 { diagnostics . push ( ast :: Diagnostic :: decl_error ( id . loc , format ! ( " a space[1]. n a m ), ) ) ; return Err ( ( ) ) ; } ; Some ( * n ) } Some ( ast :: Symbol :: Function ( _ ) ) => { diagnostics . push ( ast :: Diagnostic :: decl_error ( id . loc , format ! ( " d am ), ) ) ; return Err ( ( ) ) ; } Some ( ast :: Symbol :: Variable ( _ , _ , _ ) ) => { diagnostics . push ( ast :: Diagnostic :: decl_error ( id . loc , format ! ( " d am ), ) ) ; return Err ( ( ) ) ; } Some ( ast :: Symbol :: Event ( _ ) ) => { diagnostics . push ( ast :: Diagnostic :: decl_error ( id . loc , format ! ( " d am ), ) ) ; return Err ( ( ) ) ; } Some ( ast :: Symbol :: Struct ( _ , _ ) ) => { diagnostics . push ( ast :: Diagnostic :: decl_error ( id . loc , format ! ( " d am ), ) ) ; return Err ( ( ) ) ; } Some ( ast :: Symbol :: Enum ( _ , _ ) ) => { diagnostics . push ( ast :: Diagnostic :: decl_error ( id . loc , format ! ( " d am ), ) ) ; return Err ( ( ) ) ; } Some ( ast :: Symbol :: Import ( _ , _ ) ) => unreachable ! ( ) , } ; } let mut s = self . symbols . get ( & ( import_file_no , contract_no , id . name . to_owned ( ) ) ) ; if let Some ( contract_no ) = contract_no { // check bases contracts if s . is_none ( ) { if let Some ( sym ) = self . resolve_base_contract ( contract_no , & id ) { s = Some ( sym ) ; } } // try global scope if s . is_none ( ) { s = self . symbols . get ( & ( import_file_no , None , id . name . to_owned ( ) ) ) ; } } Ok ( s ) }
Resolve the type name with the namespace to a symbol
Resolve the type name with the namespace to a symbol
&self
namespace
Vec<&pt::Identifier>
file_no
usize
contract_no
Option<usize>
id
&pt::Identifier
diagnostics
&mut Vec<Diagnostic>