From d5b39c4fcf80a1e84aee6080351dc990c0aa8963 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Thu, 31 Mar 2016 11:10:05 +0800 Subject: AST - Put spans on imports --- src/ast/ast.cpp | 21 ++++++++++++++++----- src/ast/ast.hpp | 25 ++++++++++++++++++++++--- src/ast/attrs.hpp | 2 +- src/ast/item.hpp | 4 ++-- src/convert/resolve.cpp | 24 ++++++++++++------------ src/dump_as_rust.cpp | 2 +- src/parse/root.cpp | 20 ++++++++++---------- src/resolve/use.cpp | 25 ++++++++++++------------- 8 files changed, 76 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index ea709be4..5d314756 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -239,6 +239,17 @@ SERIALISE_TYPE(Impl::, "AST_Impl", { } } +::std::ostream& operator<<(::std::ostream& os, const UseStmt& x) +{ + return os; +} + +SERIALISE_TYPE_A(UseStmt::, "AST_UseStmt", { + //s.item(sp); + s.item(attrs); + s.item(path); +}) + SERIALISE_TYPE_A(MacroInvocation::, "AST_MacroInvocation", { s.item(m_attrs); @@ -275,9 +286,9 @@ void Module::add_item(bool is_pub, ::std::string name, Item it, MetaItems attrs) void Module::add_ext_crate(bool is_public, ::std::string ext_name, ::std::string imp_name, MetaItems attrs) { this->add_item( is_public, imp_name, Item::make_Crate({mv$(ext_name)}), mv$(attrs) ); } -void Module::add_alias(bool is_public, Path path, ::std::string name, MetaItems attrs) { - // TODO: Attributes on aliases / imports - m_imports.push_back( Named( move(name), move(path), is_public) ); +void Module::add_alias(bool is_public, UseStmt us, ::std::string name, MetaItems attrs) { + us.attrs = mv$(attrs); + m_imports.push_back( Named( mv$(name), mv$(us), is_public) ); } void Module::add_typealias(bool is_public, ::std::string name, TypeAlias alias, MetaItems attrs) { this->add_item( is_public, name, Item::make_Type({mv$(alias)}), mv$(attrs) ); @@ -391,7 +402,7 @@ Module::ItemRef Module::find_item(const ::std::string& needle, bool allow_leaves //if( &imp.data == this ) // continue ; // - const auto& binding = imp.data.binding(); + const auto& binding = imp.data.path.binding(); if( binding.is_Unbound() ) { // not yet bound, so run resolution (recursion) @@ -403,7 +414,7 @@ Module::ItemRef Module::find_item(const ::std::string& needle, bool allow_leaves TU_MATCH_DEF(AST::PathBinding, (binding), (info), // - any other type - error ( - DEBUG("ERROR: Import of invalid class : " << imp.data); + DEBUG("ERROR: Import of invalid class : " << imp.data.path); throw ParseError::Generic("Wildcard import of non-module/enum"); ), (Unbound, diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index fd72552a..08e4b6a1 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -435,6 +435,25 @@ private: Impl make_concrete(const ::std::vector& types) const; }; +struct UseStmt: + public Serialisable +{ + Span sp; + ::AST::Path path; + ::AST::MetaItems attrs; + + UseStmt(UseStmt&&) = default; + UseStmt(){} + UseStmt(Span sp, Path p): + sp(sp), + path(p) + { + } + + friend ::std::ostream& operator<<(::std::ostream& os, const UseStmt& x); + + SERIALISABLE_PROTOTYPES(); +}; typedef void fcn_visitor_t(const AST::Crate& crate, const AST::Module& mod, Function& fcn); @@ -442,7 +461,7 @@ typedef void fcn_visitor_t(const AST::Crate& crate, const AST::Module& mod, Func class Module: public Serialisable { - typedef ::std::vector< Named > itemlist_use_t; + typedef ::std::vector< Named > itemlist_use_t; ::AST::Path m_my_path; @@ -484,7 +503,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, Path path, ::std::string name, MetaItems attrs); + void add_alias(bool is_public, UseStmt path, ::std::string name, MetaItems attrs); void add_typealias(bool is_public, ::std::string name, TypeAlias alias, MetaItems attrs); void add_static(bool is_public, ::std::string name, Static item, MetaItems attrs); void add_trait(bool is_public, ::std::string name, Trait item, MetaItems attrs); @@ -559,7 +578,7 @@ public: _(AST::Struct, Struct) _(AST::Enum, Enum) _(AST::Static, Static) - _(AST::Named, Use) + _(AST::Named, Use) #undef _ }; ItemRef find_item(const ::std::string& needle, bool allow_leaves = true, bool ignore_private_wildcard = true) const; diff --git a/src/ast/attrs.hpp b/src/ast/attrs.hpp index 6a6cdaa7..82cf2154 100644 --- a/src/ast/attrs.hpp +++ b/src/ast/attrs.hpp @@ -14,7 +14,7 @@ public: ::std::vector m_items; MetaItems() {} - MetaItems(MetaItems&&) = default; + MetaItems(MetaItems&&) noexcept = default; MetaItems& operator=(MetaItems&&) = default; MetaItems(const MetaItems&) = delete; MetaItems(::std::vector items): diff --git a/src/ast/item.hpp b/src/ast/item.hpp index 7b5437c4..22fd44c9 100644 --- a/src/ast/item.hpp +++ b/src/ast/item.hpp @@ -16,7 +16,7 @@ struct NamedNS NamedNS(): is_pub(false) {} - NamedNS(NamedNS&&) noexcept = default; + NamedNS(NamedNS&&) = default; NamedNS(const NamedNS&) = default; NamedNS(::std::string name, T data, bool is_pub): name( ::std::move(name) ), @@ -38,7 +38,7 @@ struct Named: Named(): NamedNS() {} - Named(Named&&) noexcept = default; + Named(Named&&) = default; Named(const Named&) = default; Named(::std::string name, T data, bool is_pub): NamedNS( ::std::move(name), ::std::move(data), is_pub ) diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp index cfe77e84..ebfe2998 100644 --- a/src/convert/resolve.cpp +++ b/src/convert/resolve.cpp @@ -180,12 +180,12 @@ private: ret.push_back( ::std::pair(trait_path, t) ); } for( const auto& i : m_module->imports() ) { - if( i.data.binding().is_Trait() ) + if( i.data.path.binding().is_Trait() ) { - auto& t = *i.data.binding().as_Trait().trait_; + auto& t = *i.data.path.binding().as_Trait().trait_; DEBUG("(use) t = " << i.data); - ::std::pair tr(i.data, t); + ::std::pair tr(i.data.path, t); ret.push_back( tr ); } } @@ -520,14 +520,14 @@ bool lookup_path_in_module(const Span& span, const AST::Crate& crate, const AST: { DEBUG("Wildcard import found, " << imp.data << " + " << path); // Wildcard path, prefix entirely with the path - path = imp.data + path; + path = imp.data.path + path; //path.resolve( crate ); return true; } else { DEBUG("Named import found, " << imp.data << " + " << path << " [1..]"); - path = AST::Path::add_tailing(imp.data, path); + path = AST::Path::add_tailing(imp.data.path, path); //path.resolve( crate ); return true; } @@ -979,7 +979,7 @@ void CPathResolver::handle_path_abs(const Span& span, AST::Path& path, CASTItera // Re-export (Use, const auto& imp = item; - AST::Path newpath = imp.data; + AST::Path newpath = imp.data.path; auto& newnodes = newpath.m_class.as_Absolute().nodes; DEBUG("Re-exported path " << imp.data); if( imp.name == "" ) @@ -1743,17 +1743,17 @@ void ResolvePaths_HandleModule_Use(const AST::Crate& crate, const AST::Path& mod ::std::vector new_imports; for( auto& imp : mod.imports() ) { - const Span span = Span(); + const Span& span = imp.data.sp; DEBUG("p = " << imp.data); - absolutise_path(span, crate, mod, modpath, imp.data); + absolutise_path(span, crate, mod, modpath, imp.data.path); - resolve_path(span, crate, imp.data); + resolve_path(span, crate, imp.data.path); DEBUG("Resolved import : " << imp.data); // If wildcard, make sure it's sane if( imp.name == "" ) { - TU_MATCH_DEF(AST::PathBinding, (imp.data.binding()), (info), + TU_MATCH_DEF(AST::PathBinding, (imp.data.path.binding()), (info), ( throw ParseError::Generic("Wildcard imports are only allowed on modules and enums"); ), @@ -1772,7 +1772,7 @@ void ResolvePaths_HandleModule_Use(const AST::Crate& crate, const AST::Path& mod // new_imp.resolve(crate, false); //} // TODO: Get attributes from the source import - mod.add_alias(false, new_imp, new_imp[new_imp.size()-1].name(), ::AST::MetaItems()); + mod.add_alias(false, ::AST::UseStmt(Span(), new_imp), new_imp[new_imp.size()-1].name(), ::AST::MetaItems()); } for(auto& item : mod.items()) { @@ -1801,7 +1801,7 @@ void SetCrateName_Mod(const AST::Crate& crate, ::std::string name, AST::Module& // Imports 'use' statements for(auto& imp : mod.imports()) { - imp.data.set_crate(name); + imp.data.path.set_crate(name); // - Disable expectation of type parameters //imp.data.resolve(crate, false); } diff --git a/src/dump_as_rust.cpp b/src/dump_as_rust.cpp index 45ca55e0..f72b2df5 100644 --- a/src/dump_as_rust.cpp +++ b/src/dump_as_rust.cpp @@ -551,7 +551,7 @@ void RustPrinter::handle_module(const AST::Module& mod) { m_os << "::*"; } - else if( i.data.nodes().back().name() != i.name ) + else if( i.data.path.nodes().back().name() != i.name ) { m_os << " as " << i.name; } diff --git a/src/parse/root.cpp b/src/parse/root.cpp index fd90ed5d..4aba4874 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -1079,11 +1079,11 @@ void Parse_ExternBlock(TokenStream& lex, AST::Module& mod, ::std::string abi, :: } } -void Parse_Use_Wildcard(AST::Path base_path, ::std::function fcn) +void Parse_Use_Wildcard(Span sp, AST::Path base_path, ::std::function fcn) { - fcn( mv$(base_path), ""); // HACK! Empty path indicates wilcard import + fcn( AST::UseStmt(mv$(sp), mv$(base_path)), "" ); // HACK! Empty path indicates wilcard import } -void Parse_Use_Set(TokenStream& lex, const AST::Path& base_path, ::std::function fcn) +void Parse_Use_Set(TokenStream& lex, const ProtoSpan& ps, const AST::Path& base_path, ::std::function fcn) { TRACE_FUNCTION; @@ -1110,12 +1110,12 @@ void Parse_Use_Set(TokenStream& lex, const AST::Path& base_path, ::std::function else { lex.putback(tok); } - fcn(mv$(path), mv$(name)); + fcn(AST::UseStmt(lex.end_span(ps), mv$(path)), mv$(name)); } while( GET_TOK(tok, lex) == TOK_COMMA ); lex.putback(tok); } -void Parse_Use(TokenStream& lex, ::std::function fcn) +void Parse_Use(TokenStream& lex, ::std::function fcn) { TRACE_FUNCTION; @@ -1156,7 +1156,7 @@ void Parse_Use(TokenStream& lex, ::std::function } break; case TOK_BRACE_OPEN: - Parse_Use_Set(lex, path, fcn); + Parse_Use_Set(lex, span_start, path, fcn); GET_CHECK_TOK(tok, lex, TOK_BRACE_CLOSE); return; default: @@ -1174,11 +1174,11 @@ void Parse_Use(TokenStream& lex, ::std::function switch( tok.type() ) { case TOK_BRACE_OPEN: - Parse_Use_Set(lex, mv$(path), fcn); + Parse_Use_Set(lex, span_start, mv$(path), fcn); GET_CHECK_TOK(tok, lex, TOK_BRACE_CLOSE); break ; case TOK_STAR: - Parse_Use_Wildcard( mv$(path), fcn ); + Parse_Use_Wildcard( lex.end_span(span_start), mv$(path), fcn ); break ; default: throw ParseError::Unexpected(lex, tok); @@ -1204,7 +1204,7 @@ void Parse_Use(TokenStream& lex, ::std::function name = path.nodes().back().name(); } - fcn(path, name); + fcn( AST::UseStmt(lex.end_span(span_start), mv$(path)), name); } @@ -1271,7 +1271,7 @@ void Parse_Mod_Item(TokenStream& lex, bool file_controls_dir, const ::std::strin { // `use ...` case TOK_RWORD_USE: - Parse_Use(lex, [&mod,is_public,&file_path,&meta_items](AST::Path p, std::string s) { + Parse_Use(lex, [&mod,is_public,&file_path,&meta_items](AST::UseStmt p, std::string s) { DEBUG(file_path << " - use " << p << " as '" << s << "'"); mod.add_alias(is_public, mv$(p), s, meta_items.clone()); }); diff --git a/src/resolve/use.cpp b/src/resolve/use.cpp index 77304c1e..43bd074f 100644 --- a/src/resolve/use.cpp +++ b/src/resolve/use.cpp @@ -59,21 +59,21 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path TRACE_FUNCTION_F("path = " << path << ", mod.path() = " << mod.path()); for(auto& use_stmt : mod.imports()) { - const Span span; - use_stmt.data = Resolve_Use_AbsolutisePath(span, path, mv$(use_stmt.data)); - if( !use_stmt.data.m_class.is_Absolute() ) + const Span& span = use_stmt.data.sp; + use_stmt.data.path = Resolve_Use_AbsolutisePath(span, path, mv$(use_stmt.data.path)); + if( !use_stmt.data.path.m_class.is_Absolute() ) BUG(span, "Use path is not absolute after absolutisation"); // TODO: Is this a valid assertion? - if( use_stmt.data.crate() != "" ) + if( use_stmt.data.path.crate() != "" ) BUG(span, "Use path crate was set before resolve"); - use_stmt.data.bind( Resolve_Use_GetBinding(span, crate, use_stmt.data) ); + use_stmt.data.path.bind( Resolve_Use_GetBinding(span, crate, use_stmt.data.path) ); // - If doing a glob, ensure the item type is valid if( use_stmt.name == "" ) { - TU_MATCH_DEF(::AST::PathBinding, (use_stmt.data.binding()), (e), + TU_MATCH_DEF(::AST::PathBinding, (use_stmt.data.path.binding()), (e), ( ERROR(span, E0000, "Wildcard import of invalid item type"); ), @@ -140,27 +140,26 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path // Imports for( const auto& imp : mod.imports() ) { + const Span& sp2 = imp.data.sp; if( imp.name == des_item_name ) { DEBUG("- Named import " << imp.name << " = " << imp.data); - if( imp.data.binding().is_Unbound() ) { + if( imp.data.path.binding().is_Unbound() ) { DEBUG(" > Needs resolve"); - const Span sp2; // TODO: Handle possibility of recursion - return Resolve_Use_GetBinding(sp2, crate, Resolve_Use_AbsolutisePath(sp2, mod.path(), imp.data)); + return Resolve_Use_GetBinding(sp2, crate, Resolve_Use_AbsolutisePath(sp2, mod.path(), imp.data.path)); } else { - return imp.data.binding().clone(); + return imp.data.path.binding().clone(); } } if( imp.is_pub && imp.name == "" ) { - const Span sp2; // INEFFICIENT! Resolves and throws away the result (because we can't/shouldn't mutate here) ::AST::PathBinding binding_; - const auto* binding = &imp.data.binding(); + const auto* binding = &imp.data.path.binding(); if( binding->is_Unbound() ) { DEBUG("Temp resolving wildcard " << imp.data); // TODO: Handle possibility of recursion - binding_ = Resolve_Use_GetBinding(sp2, crate, Resolve_Use_AbsolutisePath(sp2, mod.path(), imp.data)); + binding_ = Resolve_Use_GetBinding(sp2, crate, Resolve_Use_AbsolutisePath(sp2, mod.path(), imp.data.path)); binding = &binding_; } -- cgit v1.2.3