diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/crate.cpp | 9 | ||||
-rw-r--r-- | src/ast/crate.hpp | 3 | ||||
-rw-r--r-- | src/expand/macro_rules.cpp | 86 |
3 files changed, 62 insertions, 36 deletions
diff --git a/src/ast/crate.cpp b/src/ast/crate.cpp index a663e300..ea1bbf1c 100644 --- a/src/ast/crate.cpp +++ b/src/ast/crate.cpp @@ -67,7 +67,14 @@ ExternCrate::ExternCrate(const ::std::string& path) m_hir = HIR_Deserialise(path); } -const MacroRules* ExternCrate::find_macro_rules(const ::std::string& name) +void ExternCrate::with_all_macros(::std::function<void(const ::std::string& , const MacroRules&)> cb) const +{ + for(const auto& m : m_hir->m_exported_macros) + { + cb(m.first, m.second); + } +} +const MacroRules* ExternCrate::find_macro_rules(const ::std::string& name) const { auto i = m_hir->m_exported_macros.find(name); if(i != m_hir->m_exported_macros.end()) diff --git a/src/ast/crate.hpp b/src/ast/crate.hpp index 1b4c5645..e598c568 100644 --- a/src/ast/crate.hpp +++ b/src/ast/crate.hpp @@ -62,7 +62,8 @@ public: ExternCrate(const ExternCrate&) = delete; ExternCrate(ExternCrate&&) = default; - const MacroRules* find_macro_rules(const ::std::string& name); + void with_all_macros(::std::function<void(const ::std::string& , const MacroRules&)> cb) const; + const MacroRules* find_macro_rules(const ::std::string& name) const; }; } // namespace AST diff --git a/src/expand/macro_rules.cpp b/src/expand/macro_rules.cpp index 4f5d33cf..359b9865 100644 --- a/src/expand/macro_rules.cpp +++ b/src/expand/macro_rules.cpp @@ -3,6 +3,7 @@ #include "../ast/expr.hpp" #include "../ast/ast.hpp" #include "../parse/common.hpp" +#include <ast/crate.hpp> #include "macro_rules.hpp" #include <macro_rules/macro_rules.hpp> @@ -33,49 +34,66 @@ class CMacroUseHandler: void handle(const Span& sp, const AST::MetaItem& mi, ::AST::Crate& crate, const AST::Path& path, AST::Module& mod, AST::Item& i) const override { TRACE_FUNCTION_F("path=" << path); - if( !i.is_Module() ) - ERROR(sp, E0000, "Use of #[macro_use] on non-module"); - const auto& submod = i.as_Module(); - - if( mi.has_sub_items() ) - { - for( const auto& si : mi.items() ) + TU_IFLET( ::AST::Item, i, None, e, + // Just ignore + ) + else TU_IFLET( ::AST::Item, i, Crate, ec_name, + const auto& ec = crate.m_extern_crates.at(ec_name.name); + if( mi.has_sub_items() ) { - const auto& name = si.name(); - for( const auto& mr : submod.macros() ) + TODO(sp, "Named import from extern crate"); + } + else + { + ec.with_all_macros([&](const auto& name, const auto& mac) { + mod.add_macro_import( name, mac ); + }); + } + ) + else TU_IFLET( ::AST::Item, i, Module, submod, + if( mi.has_sub_items() ) + { + for( const auto& si : mi.items() ) { - if( mr.name == name ) { - DEBUG("Imported " << mr.name); - mod.add_macro_import( mr.name, *mr.data ); - goto _good; + const auto& name = si.name(); + for( const auto& mr : submod.macros() ) + { + if( mr.name == name ) { + DEBUG("Imported " << mr.name); + mod.add_macro_import( mr.name, *mr.data ); + goto _good; + } } - } - for( const auto& mri : submod.macro_imports_res() ) - { - if( mri.name == name ) { - DEBUG("Imported " << mri.name << " (propagate)"); - mod.add_macro_import( mri.name, *mri.data ); - goto _good; + for( const auto& mri : submod.macro_imports_res() ) + { + if( mri.name == name ) { + DEBUG("Imported " << mri.name << " (propagate)"); + mod.add_macro_import( mri.name, *mri.data ); + goto _good; + } } + ERROR(sp, E0000, "Couldn't find macro " << name); + _good: + (void)0; } - ERROR(sp, E0000, "Couldn't find macro " << name); - _good: - (void)0; } - } - else - { - for( const auto& mr : submod.macros() ) - { - DEBUG("Imported " << mr.name); - mod.add_macro_import( mr.name, *mr.data ); - } - for( const auto& mri : submod.macro_imports_res() ) + else { - DEBUG("Imported " << mri.name << " (propagate)"); - mod.add_macro_import( mri.name, *mri.data ); + for( const auto& mr : submod.macros() ) + { + DEBUG("Imported " << mr.name); + mod.add_macro_import( mr.name, *mr.data ); + } + for( const auto& mri : submod.macro_imports_res() ) + { + DEBUG("Imported " << mri.name << " (propagate)"); + mod.add_macro_import( mri.name, *mri.data ); + } } + ) + else { + ERROR(sp, E0000, "Use of #[macro_use] on non-module/crate - " << i.tag_str()); } } |