summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-09-26 16:05:59 +0800
committerJohn Hodge <tpg@mutabah.net>2016-09-26 16:05:59 +0800
commitcf0bc71ad1bd5a9bc1c9ee19305aec0e31641986 (patch)
tree83ed832002ed45c2137ab71e22f6897d48ea79aa /src
parentc7ab799892231de0bc91b16637c2f0fce11f3536 (diff)
downloadmrust-cf0bc71ad1bd5a9bc1c9ee19305aec0e31641986.tar.gz
AST - Move module-level macro invocations into the Item list
Diffstat (limited to 'src')
-rw-r--r--src/ast/ast.cpp3
-rw-r--r--src/ast/ast.hpp4
-rw-r--r--src/expand/mod.cpp39
3 files changed, 39 insertions, 7 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp
index 885ea677..7b92be33 100644
--- a/src/ast/ast.cpp
+++ b/src/ast/ast.cpp
@@ -271,6 +271,9 @@ void Module::add_ext_crate(bool is_public, ::std::string ext_name, ::std::string
void Module::add_alias(bool is_public, UseStmt us, ::std::string name, MetaItems attrs) {
this->add_item( is_public, mv$(name), Item(mv$(us)), mv$(attrs) );
}
+void Module::add_macro_invocation(MacroInvocation item) {
+ this->add_item( false, "", Item( mv$(item) ), ::AST::MetaItems {} );
+}
void Module::add_macro(bool is_exported, ::std::string name, MacroRulesPtr macro) {
m_macros.push_back( Named<MacroRulesPtr>( mv$(name), mv$(macro), is_exported ) );
}
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp
index 533832e2..1b5a04d0 100644
--- a/src/ast/ast.hpp
+++ b/src/ast/ast.hpp
@@ -517,6 +517,7 @@ public:
void add_item(bool is_pub, ::std::string name, Item it, MetaItems attrs);
void add_ext_crate(bool is_public, ::std::string ext_name, ::std::string imp_name, MetaItems attrs);
void add_alias(bool is_public, UseStmt path, ::std::string name, MetaItems attrs);
+ void add_macro_invocation(MacroInvocation item);
void add_impl(Impl impl) {
m_impls.emplace_back( mv$(impl) );
@@ -528,9 +529,6 @@ public:
void add_macro_import(::std::string name, const MacroRules& mr) {
m_macro_import_res.push_back( NamedNS<const MacroRules*>( mv$(name), &mr, false ) );
}
- void add_macro_invocation(MacroInvocation item) {
- m_macro_invocations.push_back( mv$(item) );
- }
diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp
index bb79a0bc..791d0206 100644
--- a/src/expand/mod.cpp
+++ b/src/expand/mod.cpp
@@ -614,8 +614,10 @@ void Expand_Mod(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> mo
// 3. General items
DEBUG("Items");
- for( auto& i : mod.items() )
+ for( unsigned int idx = 0; idx < mod.items().size(); idx ++ )
{
+ auto& i = mod.items()[idx];
+
DEBUG("- " << i.name << " (" << ::AST::Item::tag_to_str(i.data.tag()) << ") :: " << i.data.attrs);
::AST::Path path = modpath + i.name;
@@ -627,7 +629,33 @@ void Expand_Mod(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> mo
// Skip, nothing
),
(MacroInv,
- TODO(i.data.span, "Macro invocation in item list");
+ // Move out of the module to avoid invalidation if a new macro invocation is added
+ auto mi_owned = mv$(e);
+
+ auto& attrs = mi_owned.attrs();
+ Expand_Attrs(attrs, stage_pre(is_early), [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, mi_owned); });
+
+ auto ttl = Expand_Macro(is_early, crate, modstack, mod, mi_owned);
+
+ if( ! ttl.get() )
+ {
+ Expand_Attrs(attrs, stage_post(is_early), [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, mi_owned); });
+ // - Return ownership to the list
+ if( mi_owned.name() == "" ) {
+ mod.items()[idx].data = AST::Item();
+ }
+ else {
+ mod.items()[idx].data = AST::Item( mv$(mi_owned) );
+ }
+ }
+ else
+ {
+ // Re-parse tt
+ assert(ttl.get());
+ Parse_ModRoot_Items(*ttl, mod);
+ // - Any new macro invocations ends up at the end of the list and handled
+ mod.items()[idx].data = AST::Item();
+ }
),
(Use,
// No inner expand.
@@ -749,8 +777,11 @@ void Expand_Mod(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> mo
)
Expand_Attrs(attrs, stage_post(is_early), crate, path, mod, i.data);
- if( i.data.attrs.m_items.size() == 0 )
- i.data.attrs = mv$(attrs);
+
+ // TODO: When would this _not_ be empty?
+ auto& i2 = mod.items()[idx];
+ if( i2.data.attrs.m_items.size() == 0 )
+ i2.data.attrs = mv$(attrs);
}
// IGNORE m_anon_modules, handled as part of expressions