From 75205189d5e33a33193fa76a29f7518a9797299d Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 21 Mar 2015 15:41:00 +0800 Subject: Move wildcard use to Path::resolve, add 'bool' type --- src/ast/path.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 13 deletions(-) (limited to 'src/ast/path.cpp') diff --git a/src/ast/path.cpp b/src/ast/path.cpp index 4f83ae34..338a0b15 100644 --- a/src/ast/path.cpp +++ b/src/ast/path.cpp @@ -56,9 +56,10 @@ typename ::std::vector >::const_iterator find_named(const ::std::vector< }); } +/// Resolve a path into a canonical form, and bind it to the target value void Path::resolve(const Crate& root_crate) { - DEBUG("*this = " << *this); + TRACE_FUNCTION_F("*this = "<< *this); if(m_class != ABSOLUTE) throw ParseError::BugCheck("Calling Path::resolve on non-absolute path"); DEBUG("m_crate = '" << m_crate << "'"); @@ -102,18 +103,7 @@ void Path::resolve(const Crate& root_crate) continue; } } - - // Start searching for: - // - Re-exports - { - auto& imp = mod->imports(); - auto it = find_named(imp, node.name()); - if( it != imp.end() ) - { - DEBUG("Re-exported path " << it->data); - throw ParseError::Todo("Path::resolve() re-export"); - } - } + // Type Aliases { auto& items = mod->type_aliases(); @@ -232,6 +222,55 @@ void Path::resolve(const Crate& root_crate) } } + // - Re-exports + // > Comes last, as it's a potentially expensive operation + { + for( const auto& imp : mod->imports() ) + { + if( !imp.is_pub ) + { + // not public, ignore + } + else if( imp.name == node.name() ) + { + // replace nodes 0:i with the source path + DEBUG("Re-exported path " << imp.data); + AST::Path newpath = imp.data; + for( unsigned int j = i+1; j < m_nodes.size(); j ++ ) + { + newpath.m_nodes.push_back( m_nodes[j] ); + } + DEBUG("- newpath = " << newpath); + // TODO: This should check for recursion somehow + newpath.resolve(root_crate); + + *this = newpath; + DEBUG("Alias resolved, *this = " << *this); + return ; + } + 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 + } + } + } + throw ParseError::Generic("Unable to find component '" + node.name() + "'"); } -- cgit v1.2.3