From 802c2c5d616d537ed8becea81c2ee6b48ae8f078 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Mon, 23 Mar 2015 15:00:02 +0800 Subject: Move item lookup from AST::Path to AST::Module --- src/ast/ast.cpp | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) (limited to 'src/ast/ast.cpp') diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 42052c5e..a695c6f5 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -491,6 +491,130 @@ void Module::iterate_functions(fcn_visitor_t *visitor, const Crate& crate) } } +template +typename ::std::vector >::const_iterator find_named(const ::std::vector >& vec, const ::std::string& name) +{ + return ::std::find_if(vec.begin(), vec.end(), [&name](const Item& x) { + return x.name == name; + }); +} + +Module::ItemRef Module::find_item(const ::std::string& needle) const +{ + TRACE_FUNCTION_F("needle = " << needle); + // Sub-modules + { + auto& sms = submods(); + auto it = ::std::find_if(sms.begin(), sms.end(), [&needle](const ::std::pair& x) { + return x.first.name() == needle; + }); + if( it != sms.end() ) { + return ItemRef(it->first); + } + } + + // External crates + { + auto& crates = this->extern_crates(); + auto it = find_named(crates, needle); + if( it != crates.end() ) { + return ItemRef(it->data); + } + } + + // Type Aliases + { + auto& items = this->type_aliases(); + auto it = find_named(items, needle); + if( it != items.end() ) { + return ItemRef(it->data); + } + } + + // Functions + { + auto& items = this->functions(); + auto it = find_named(items, needle); + if( it != items.end() ) { + return ItemRef(it->data); + } + } + + // Traits + { + auto& items = this->traits(); + auto it = find_named(items, needle); + if( it != items.end() ) { + return ItemRef(it->data); + } + } + + // Structs + { + auto& items = this->structs(); + auto it = find_named(items, needle); + if( it != items.end() ) { + return ItemRef(it->data); + } + } + + // Enums + { + auto& items = this->enums(); + auto it = find_named(items, needle); + if( it != items.end() ) { + return ItemRef(it->data); + } + } + + // Statics + { + auto& items = this->statics(); + auto it = find_named(items, needle); + if( it != items.end() ) { + return ItemRef(it->data); + } + } + + // - Re-exports + // > Comes last, as it's a potentially expensive operation + { + for( const auto& imp : this->imports() ) + { + if( !imp.is_pub ) + { + // not public, ignore + } + else if( imp.name == needle ) + { + return ItemRef(imp); + } + else if( imp.name == "" ) + { + // Loop avoidance, don't check this + //if( &imp.data == this ) + // continue ; + // + //if( !imp.data.is_bound() ) + //{ + // // not yet bound, so run resolution (recursion) + // DEBUG("Recursively resolving pub wildcard use " << imp.data); + // //imp.data.resolve(root_crate); + // throw ParseError::Todo("Path::resolve() wildcard re-export call resolve"); + //} + + throw ParseError::Todo("Path::resolve() wildcard re-export"); + } + else + { + // Can't match, ignore + } + } + } + + return Module::ItemRef(); +} + SERIALISE_TYPE(TypeAlias::, "AST_TypeAlias", { s << m_params; s << m_type; -- cgit v1.2.3