From 4ead75dea44e61502c8257161ff6b86fcc835adf Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 5 Jan 2019 15:09:30 +0800 Subject: Resolve Use - Handle partial shadowing of items/imports --- src/resolve/use.cpp | 55 +++++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 27 deletions(-) (limited to 'src/resolve/use.cpp') diff --git a/src/resolve/use.cpp b/src/resolve/use.cpp index cde52de1..5fe7ee5c 100644 --- a/src/resolve/use.cpp +++ b/src/resolve/use.cpp @@ -334,10 +334,6 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path TODO(span, "Import of macro - " << des_item_name); } } - if( rv.has_binding() ) - { - return rv; - } // Imports for( const auto& imp : mod.items() ) @@ -352,14 +348,19 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path DEBUG("- Named import " << imp_e.name << " = " << imp_e.path); if( !imp_e.path.m_bindings.has_binding() ) { DEBUG(" > Needs resolve"); - // TODO: Handle possibility of recursion - //out_path = imp_e.path; - return Resolve_Use_GetBinding(sp2, crate, Resolve_Use_AbsolutisePath(sp2, mod.path(), imp_e.path), parent_modules); + static ::std::vector s_mods; + if( ::std::find(s_mods.begin(), s_mods.end(), &mod) == s_mods.end() ) + { + s_mods.push_back(&mod); + rv.merge_from( Resolve_Use_GetBinding(sp2, crate, Resolve_Use_AbsolutisePath(sp2, mod.path(), imp_e.path), parent_modules) ); + s_mods.pop_back(); + } } else { //out_path = imp_e.path; - return imp_e.path.m_bindings.clone(); + rv.merge_from( imp_e.path.m_bindings.clone() ); } + continue ; } if( imp.is_pub && imp_e.name == "" ) @@ -393,25 +394,19 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path TU_ARMA(Crate, e) { assert(e.crate_); const ::HIR::Module& hmod = e.crate_->m_hir->m_root_module; - auto rv = Resolve_Use_GetBinding__ext(sp2, crate, AST::Path("", { AST::PathNode(des_item_name,{}) }), hmod, 0); - if( rv.has_binding() ) { - return mv$(rv); + auto imp_rv = Resolve_Use_GetBinding__ext(sp2, crate, AST::Path("", { AST::PathNode(des_item_name,{}) }), hmod, 0); + if( imp_rv.has_binding() ) { + rv.merge_from( imp_rv ); } } TU_ARMA(Module, e) { if( e.module_ ) { // TODO: Prevent infinite recursion? - auto rv = Resolve_Use_GetBinding_Mod(span, crate, *e.module_, des_item_name, {}); - if( rv.has_binding() ) { - return mv$(rv); - } + rv.merge_from( Resolve_Use_GetBinding_Mod(span, crate, *e.module_, des_item_name, {}) ); } else if( e.hir ) { const ::HIR::Module& hmod = *e.hir; - auto rv = Resolve_Use_GetBinding__ext(sp2, crate, AST::Path("", { AST::PathNode(des_item_name,{}) }), hmod, 0); - if( rv.has_binding() ) { - return mv$(rv); - } + rv.merge_from( Resolve_Use_GetBinding__ext(sp2, crate, AST::Path("", { AST::PathNode(des_item_name,{}) }), hmod, 0) ); } else { BUG(span, "NULL module for binding on glob of " << imp_e.path); @@ -425,12 +420,13 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path for(const auto& var : enm.variants()) { if( var.m_name == des_item_name ) { - ::AST::Path::Bindings rv; + ::AST::Path::Bindings tmp_rv; if( var.m_data.is_Struct() ) - rv.type = ::AST::PathBinding_Type::make_EnumVar({ &enm, i }); + tmp_rv.type = ::AST::PathBinding_Type::make_EnumVar({ &enm, i }); else - rv.value = ::AST::PathBinding_Value::make_EnumVar({ &enm, i }); - return rv; + tmp_rv.value = ::AST::PathBinding_Value::make_EnumVar({ &enm, i }); + rv.merge_from(tmp_rv); + break; } i ++; } @@ -440,14 +436,15 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path auto idx = enm.find_variant(des_item_name); if( idx != SIZE_MAX ) { - ::AST::Path::Bindings rv; + ::AST::Path::Bindings tmp_rv; if( enm.m_data.is_Data() && enm.m_data.as_Data()[idx].is_struct ) { - rv.type = ::AST::PathBinding_Type::make_EnumVar({ nullptr, static_cast(idx), &enm }); + tmp_rv.type = ::AST::PathBinding_Type::make_EnumVar({ nullptr, static_cast(idx), &enm }); } else { - rv.value = ::AST::PathBinding_Value::make_EnumVar({ nullptr, static_cast(idx), &enm }); + tmp_rv.value = ::AST::PathBinding_Value::make_EnumVar({ nullptr, static_cast(idx), &enm }); } - return rv; + rv.merge_from(tmp_rv); + break; } } } break; @@ -458,6 +455,10 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path } } } + if( rv.has_binding() ) + { + return rv; + } if( mod.path().nodes().size() > 0 && mod.path().nodes().back().name()[0] == '#' ) { assert( parent_modules.size() > 0 ); -- cgit v1.2.3