diff options
| author | John Hodge <tpg@mutabah.net> | 2016-08-29 16:07:28 +0800 | 
|---|---|---|
| committer | John Hodge <tpg@mutabah.net> | 2016-08-29 16:07:28 +0800 | 
| commit | 4c5e8ffbd413772859739e8cad57f925ba85dad8 (patch) | |
| tree | d22427268aeee7a91b88ee1746845d7a1b74032d | |
| parent | a8da316a2646428acb780e889b322edf5f00549e (diff) | |
| download | mrust-4c5e8ffbd413772859739e8cad57f925ba85dad8.tar.gz | |
AST Resolve - Prelude handling
| -rw-r--r-- | src/ast/ast.hpp | 3 | ||||
| -rw-r--r-- | src/ast/path.cpp | 17 | ||||
| -rw-r--r-- | src/expand/mod.cpp | 8 | ||||
| -rw-r--r-- | src/expand/std_prelude.cpp | 9 | ||||
| -rw-r--r-- | src/resolve/index.cpp | 39 | ||||
| -rw-r--r-- | src/resolve/use.cpp | 168 | 
6 files changed, 130 insertions, 114 deletions
| diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 362af210..9cf9b236 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -523,13 +523,14 @@ private:      ::std::vector< Named<MacroRulesPtr> >  m_macros;
  public:
 +    bool    m_insert_prelude = true;    // Set to false by `#[no_prelude]` handler
      char    m_index_populated = 0;  // 0 = no, 1 = partial, 2 = complete
 -    // TODO: Add "namespace" list (separate to types)
      struct IndexEnt {
          bool is_pub;    // Used as part of glob import checking
          bool is_import; // Set if this item has a path that isn't `mod->path() + name`
          ::AST::Path path;
      };
 +    // TODO: Add "namespace" list (separate to types)
      ::std::unordered_map< ::std::string, IndexEnt >    m_namespace_items;
      ::std::unordered_map< ::std::string, IndexEnt >    m_type_items;
      ::std::unordered_map< ::std::string, IndexEnt >    m_value_items;
 diff --git a/src/ast/path.cpp b/src/ast/path.cpp index 58eadf24..132f0bb8 100644 --- a/src/ast/path.cpp +++ b/src/ast/path.cpp @@ -169,23 +169,6 @@ AST::Path::Path(const Path& x):      )      memcpy(&m_binding, &x.m_binding, sizeof(PathBinding)); -    //TU_MATCH(PathBinding, (x.m_binding), (ent), -    //(Unbound, m_binding = PathBinding::make_Unbound({}); ), -    //(Module,  os << "Module";    ), -    //(Trait,     os << "Trait";   ), -    //(Struct,    os << "Struct";  ), -    //(Enum,      os << "Enum";    ), -    //(Static,    os << "Static";  ), -    //(Function,  os << "Function";), -    //(EnumVar,  os << "EnumVar(" << i.idx << ")"; ), -    //(TypeAlias, os << "TypeAlias";), -    //(StructMethod, os << "StructMethod"; ), -    //(TraitMethod,  os << "TraitMethod";  ), -    // -    //(TypeParameter, os << "TypeParameter(" << i.level << " # " << i.idx << ")"; ), -    //(Variable, os << "Variable(" << i.slot << ")"; ) -    //) -          //DEBUG("clone, x = " << x << ", this = " << *this );  } diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index be7e17b0..2fc7b18a 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -567,6 +567,10 @@ void Expand_Mod(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> mo      for( const auto& mi: mod.macro_imports_res() )          DEBUG("- Imports '" << mi.name << "'"); +    if( mod.m_insert_prelude && crate.m_prelude_path != AST::Path() ) { +        mod.add_alias(false, ::AST::UseStmt(Span(), crate.m_prelude_path), "", {}); +    } +          // TODO: Have the AST representation of a module include the definition order,      //  mixing macro invocations, general items, use statements, and `impl`s @@ -869,7 +873,7 @@ void Expand(::AST::Crate& crate)      switch( crate.m_load_std )      {      case ::AST::Crate::LOAD_STD: -        if( crate.m_prelude_path != AST::Path() ) +        if( crate.m_prelude_path == AST::Path() )              crate.m_prelude_path = AST::Path("std", {AST::PathNode("prelude"), AST::PathNode("v1")});          crate.load_extern_crate("std");          crate.m_extern_crates.at("std").with_all_macros([&](const auto& name, const auto& mac) { @@ -878,7 +882,7 @@ void Expand(::AST::Crate& crate)          crate.m_root_module.add_ext_crate(false, "std", "std", ::AST::MetaItems {});          break;      case ::AST::Crate::LOAD_CORE: -        if( crate.m_prelude_path != AST::Path() ) +        if( crate.m_prelude_path == AST::Path() )              crate.m_prelude_path = AST::Path("core", {AST::PathNode("prelude")});          crate.load_extern_crate("core");          crate.m_extern_crates.at("core").with_all_macros([&](const auto& name, const auto& mac) { diff --git a/src/expand/std_prelude.cpp b/src/expand/std_prelude.cpp index b7493570..a46740a7 100644 --- a/src/expand/std_prelude.cpp +++ b/src/expand/std_prelude.cpp @@ -41,6 +41,15 @@ class Decorator_NoPrelude:  {  public:      AttrStage stage() const override { return AttrStage::EarlyPre; } +     +    void handle(const Span& sp, const AST::MetaItem& mi, ::AST::Crate& crate, const AST::Path& path, AST::Module& mod, AST::Item&i) const override { +        if( i.is_Module() ) { +            i.as_Module().m_insert_prelude = false; +        } +        else { +            ERROR(sp, E0000, "Invalid use of #[no_prelude] on non-module"); +        } +    }  }; diff --git a/src/resolve/index.cpp b/src/resolve/index.cpp index 6de86a2e..2890f247 100644 --- a/src/resolve/index.cpp +++ b/src/resolve/index.cpp @@ -231,28 +231,37 @@ void Resolve_Index_Module_Wildcard(AST::Module& mod, bool handle_pub)                  ),              (Module,                  DEBUG("Glob mod " << i.data.path); -                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 == 1 ) +                if( !e.module_ )                  { -                    // TODO: Handle wildcard import of a module with a public wildcard import -                    TODO(sp, "Handle wildcard import of module with a wildcard (" << e.module_->path() << " by " << mod.path() << ")"); -                    //Resolve_Index_Module( *e.module_ ); +                    ASSERT_BUG(sp, e.hir, "Glob import but module pointer not set - " << i.data.path); +                    TODO(sp, "Glob import from HIR module - " << i.data.path);                  } -                for(const auto& vi : e.module_->m_type_items) { -                    if( vi.second.is_pub ) { -                        _add_item_type( sp, mod, vi.first, i.is_pub, vi.second.path, false ); +                else +                { +                    if( e.module_ == &mod ) { +                        ERROR(sp, E0000, "Glob import of self");                      } -                } -                for(const auto& vi : e.module_->m_value_items) { -                    if( vi.second.is_pub ) { -                        _add_item_value( sp, mod, vi.first, i.is_pub, vi.second.path, false ); +                    // 1. Begin indexing of this module if it is not already indexed +                    if( e.module_->m_index_populated == 1 ) +                    { +                        // TODO: Handle wildcard import of a module with a public wildcard import +                        TODO(sp, "Handle wildcard import of module with a wildcard (" << e.module_->path() << " by " << mod.path() << ")"); +                        //Resolve_Index_Module( *e.module_ ); +                    } +                    for(const auto& vi : e.module_->m_type_items) { +                        if( vi.second.is_pub ) { +                            _add_item_type( sp, mod, vi.first, i.is_pub, vi.second.path, false ); +                        } +                    } +                    for(const auto& vi : e.module_->m_value_items) { +                        if( vi.second.is_pub ) { +                            _add_item_value( sp, mod, vi.first, i.is_pub, vi.second.path, false ); +                        }                      }                  }                  ),              (Enum, +                ASSERT_BUG(sp, e.enum_, "Glob import but enum pointer not set - " << i.data.path);                  DEBUG("Glob enum " << i.data.path);                  unsigned int idx = 0;                  for( const auto& ev : e.enum_->variants() ) { diff --git a/src/resolve/use.cpp b/src/resolve/use.cpp index 57679f8b..f977f0d1 100644 --- a/src/resolve/use.cpp +++ b/src/resolve/use.cpp @@ -302,8 +302,96 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path      }  } +::AST::PathBinding Resolve_Use_GetBinding__ext(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path,  const AST::ExternCrate& ec, unsigned int start) +{ +    const auto& nodes = path.nodes(); +    const ::HIR::Module* hmod = &ec.m_hir->m_root_module; +    for(unsigned int i = start; i < nodes.size() - 1; i ++) +    { +        auto it = hmod->m_mod_items.find(nodes[i].name()); +        if( it == hmod->m_mod_items.end() ) { +            // BZZT! +            ERROR(span, E0000, "Unable to find path component " << nodes[i].name() << " in " << path); +        } +        TU_MATCH_DEF( ::HIR::TypeItem, (it->second->ent), (e), +        ( +            ERROR(span, E0000, "Unexpected item type in import"); +            ), +        (Module, +            hmod = &e; +            ), +        (Enum, +            i += 1; +            if( i != nodes.size() - 1 ) { +                ERROR(span, E0000, "Encountered enum at unexpected location in import"); +            } +            const auto& name = nodes[i].name(); +             +            auto it2 = ::std::find_if( e.m_variants.begin(), e.m_variants.end(), [&](const auto& x){ return x.first == name; } ); +            if( it2 == e.m_variants.end() ) { +                ERROR(span, E0000, "Unable to find variant " << path); +            } +            return ::AST::PathBinding::make_EnumVar({ nullptr, static_cast<unsigned int>(it2 - e.m_variants.begin()) }); +            ) +        ) +    } +    auto it = hmod->m_mod_items.find(nodes.back().name()); +    if( it != hmod->m_mod_items.end() ) { +        TU_MATCHA( (it->second->ent), (e), +        (Import, +            TODO(span, "Recurse to get binding for an import"); +            ), +        (Module, +            return ::AST::PathBinding::make_Module({nullptr, &e}); +            ), +        (TypeAlias, +            return ::AST::PathBinding::make_TypeAlias({nullptr}); +            ), +        (Enum, +            return ::AST::PathBinding::make_Enum({nullptr}); +            ), +        (Struct, +            return ::AST::PathBinding::make_Struct({nullptr}); +            ), +        (Trait, +            return ::AST::PathBinding::make_Trait({nullptr}); +            ) +        ) +    } +    auto it2 = hmod->m_value_items.find(nodes.back().name()); +    if( it2 != hmod->m_value_items.end() ) { +        TU_MATCHA( (it2->second->ent), (e), +        (Import, +            TODO(span, "Recurse to get binding for an import"); +            ), +        (Constant, +            return ::AST::PathBinding::make_Static({ nullptr }); +            ), +        (Static, +            return ::AST::PathBinding::make_Static({ nullptr }); +            ), +        (StructConstant, +            return ::AST::PathBinding::make_Struct({ nullptr }); +            ), +        (Function, +            return ::AST::PathBinding::make_Function({ nullptr }); +            ), +        (StructConstructor, +            return ::AST::PathBinding::make_Struct({ nullptr }); +            ) +        ) +    } +     +    TODO(span, "Get binding within an extern crate"); +} +  ::AST::PathBinding Resolve_Use_GetBinding(const Span& span, const ::AST::Crate& crate, const ::AST::Path& path, slice< const ::AST::Module* > parent_modules)  { +    if( path.m_class.is_Absolute() && path.m_class.as_Absolute().crate != "" ) { +        const auto& path_abs = path.m_class.as_Absolute(); +         +        return Resolve_Use_GetBinding__ext(span, crate, path,  crate.m_extern_crates.at( path_abs.crate ), 0); +    }      const AST::Module* mod = &crate.m_root_module;      const auto& nodes = path.nodes();      for( unsigned int i = 0; i < nodes.size()-1; i ++ ) @@ -314,85 +402,7 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path              ERROR(span, E0000, "Unexpected item type in import");              ),          (Crate, -            const ::HIR::Module* hmod = &e.crate_->m_hir->m_root_module; -            i ++; -            for(; i < nodes.size() - 1; i ++) -            { -                auto it = hmod->m_mod_items.find(nodes[i].name()); -                if( it == hmod->m_mod_items.end() ) { -                    // BZZT! -                    ERROR(span, E0000, "Unable to find path component " << nodes[i].name() << " in " << path); -                } -                TU_MATCH_DEF( ::HIR::TypeItem, (it->second->ent), (e), -                ( -                    ERROR(span, E0000, "Unexpected item type in import"); -                    ), -                (Module, -                    hmod = &e; -                    ), -                (Enum, -                    i += 1; -                    if( i != nodes.size() - 1 ) { -                        ERROR(span, E0000, "Encountered enum at unexpected location in import"); -                    } -                    const auto& name = nodes[i].name(); -                     -                    auto it2 = ::std::find_if( e.m_variants.begin(), e.m_variants.end(), [&](const auto& x){ return x.first == name; } ); -                    if( it2 == e.m_variants.end() ) { -                        ERROR(span, E0000, "Unable to find variant " << path); -                    } -                    return ::AST::PathBinding::make_EnumVar({ nullptr, static_cast<unsigned int>(it2 - e.m_variants.begin()) }); -                    ) -                ) -            } -            auto it = hmod->m_mod_items.find(nodes[i].name()); -            if( it != hmod->m_mod_items.end() ) { -                TU_MATCHA( (it->second->ent), (e), -                (Import, -                    TODO(span, "Recurse to get binding for an import"); -                    ), -                (Module, -                    return ::AST::PathBinding::make_Module({nullptr, &e}); -                    ), -                (TypeAlias, -                    return ::AST::PathBinding::make_TypeAlias({nullptr}); -                    ), -                (Enum, -                    return ::AST::PathBinding::make_Enum({nullptr}); -                    ), -                (Struct, -                    return ::AST::PathBinding::make_Struct({nullptr}); -                    ), -                (Trait, -                    return ::AST::PathBinding::make_Trait({nullptr}); -                    ) -                ) -            } -            auto it2 = hmod->m_value_items.find(nodes[i].name()); -            if( it2 != hmod->m_value_items.end() ) { -                TU_MATCHA( (it2->second->ent), (e), -                (Import, -                    TODO(span, "Recurse to get binding for an import"); -                    ), -                (Constant, -                    return ::AST::PathBinding::make_Static({ nullptr }); -                    ), -                (Static, -                    return ::AST::PathBinding::make_Static({ nullptr }); -                    ), -                (StructConstant, -                    return ::AST::PathBinding::make_Struct({ nullptr }); -                    ), -                (Function, -                    return ::AST::PathBinding::make_Function({ nullptr }); -                    ), -                (StructConstructor, -                    return ::AST::PathBinding::make_Struct({ nullptr }); -                    ) -                ) -            } -             -            TODO(span, "Get binding within an extern crate"); +            return Resolve_Use_GetBinding__ext(span, crate, path,  *e.crate_, i+1);              ),          (Enum,              const auto& enum_ = *e.enum_; | 
