diff options
-rw-r--r-- | src/ast/ast.hpp | 1 | ||||
-rw-r--r-- | src/resolve/index.cpp | 88 |
2 files changed, 83 insertions, 6 deletions
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index c86efe0f..c27beecf 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -547,6 +547,7 @@ private: ::std::vector< Named<MacroRules> > m_macros;
public:
+ char m_index_populated = 0; // 0 = no, 1 = partial, 2 = complete
::std::unordered_map< ::std::string, ::std::pair<bool, PathBinding> > m_type_items;
::std::unordered_map< ::std::string, ::std::pair<bool, PathBinding> > m_value_items;
diff --git a/src/resolve/index.cpp b/src/resolve/index.cpp index 4b6964fb..697e98f1 100644 --- a/src/resolve/index.cpp +++ b/src/resolve/index.cpp @@ -5,23 +5,30 @@ #include <ast/crate.hpp> #include <main_bindings.hpp> -void _add_item(AST::Module& mod, bool is_type, const ::std::string& name, bool is_pub, ::AST::PathBinding ir) +void _add_item(AST::Module& mod, bool is_type, const ::std::string& name, bool is_pub, ::AST::PathBinding ir, bool error_on_collision) { DEBUG("Add " << (is_type ? "type" : "value") << " item '" << name << "': " << ir); auto& list = (is_type ? mod.m_type_items : mod.m_value_items); if( false == list.insert( ::std::make_pair(name, ::std::make_pair(is_pub, mv$(ir))) ).second ) { - ERROR(Span(), E0000, "Duplicate definition of name '" << name << "' in " << (is_type ? "type" : "value") << " scope (" << mod.path() << ")"); + if( error_on_collision ) + { + ERROR(Span(), E0000, "Duplicate definition of name '" << name << "' in " << (is_type ? "type" : "value") << " scope (" << mod.path() << ")"); + } + else + { + DEBUG("Name collision " << mod.path() << ", ignored"); + } } } -void _add_item_type(AST::Module& mod, const ::std::string& name, bool is_pub, ::AST::PathBinding ir) +void _add_item_type(AST::Module& mod, const ::std::string& name, bool is_pub, ::AST::PathBinding ir, bool error_on_collision=true) { - _add_item(mod, true, name, is_pub, mv$(ir)); + _add_item(mod, true, name, is_pub, mv$(ir), error_on_collision); } -void _add_item_value(AST::Module& mod, const ::std::string& name, bool is_pub, ::AST::PathBinding ir) +void _add_item_value(AST::Module& mod, const ::std::string& name, bool is_pub, ::AST::PathBinding ir, bool error_on_collision=true) { - _add_item(mod, false, name, is_pub, mv$(ir)); + _add_item(mod, false, name, is_pub, mv$(ir), error_on_collision); } void Resolve_Index_Module(AST::Module& mod) @@ -66,6 +73,7 @@ void Resolve_Index_Module(AST::Module& mod) ) } + // Named imports for( const auto& i : mod.imports() ) { if( i.name != "" ) @@ -104,7 +112,75 @@ void Resolve_Index_Module(AST::Module& mod) ) } } + mod.m_index_populated = 1; + + // Glob/wildcard imports + for( const auto& i : mod.imports() ) + { + if( i.name == "" ) + { + const auto& sp = i.data.sp; + const auto& b = i.data.path.binding(); + TU_MATCH_DEF(::AST::PathBinding, (b), (e), + ( + BUG(sp, "Glob import of invalid type encountered"); + ), + (Unbound, + BUG(sp, "Import left unbound"); + ), + (Variable, + BUG(sp, "Import was bound to variable"); + ), + (TypeParameter, + BUG(sp, "Import was bound to type parameter"); + ), + (TraitMethod, + BUG(sp, "Import was bound to trait method"); + ), + (StructMethod, + BUG(sp, "Import was bound to struct method"); + ), + + (Module, + if( e.module_ == &mod ) { + ERROR(sp, E0000, "Glob import of self"); + } + // 1. Begin indexing of this module if it is not already indexed + if( !e.module_->m_index_populated ) + { + TODO(sp, "Handle glob import of module not yet indexed"); + //Resolve_Index_Module( *e.module_ ); + } + for(const auto& vi : e.module_->m_type_items) { + if( vi.second.first ) { + _add_item_type( mod, vi.first, i.is_pub, vi.second.second.clone(), false ); + } + } + for(const auto& vi : e.module_->m_value_items) { + if( vi.second.first ) { + _add_item_value( mod, vi.first, i.is_pub, vi.second.second.clone(), false ); + } + } + ), + (Enum, + unsigned int idx = 0; + for( const auto& ev : e.enum_->variants() ) { + if( ev.m_data.is_Struct() ) { + _add_item_type ( mod, ev.m_name, i.is_pub, ::AST::PathBinding::make_EnumVar({e.enum_, idx}), false ); + } + else { + _add_item_value( mod, ev.m_name, i.is_pub, ::AST::PathBinding::make_EnumVar({e.enum_, idx}), false ); + } + + idx += 1; + } + ) + ) + } + } + mod.m_index_populated = 2; + // Handle child modules for( auto& i : mod.items() ) { TU_MATCH_DEF(AST::Item, (i.data), (e), |