summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2017-01-08 10:13:44 +0800
committerJohn Hodge <tpg@mutabah.net>2017-01-08 10:13:44 +0800
commitd14787eb48b60a7e1149736f929be809af857e95 (patch)
tree5e0ff9cf28561f05e1785a54e541f504e21cfc6e /src
parent81b96e997a95687722dbca9386447513235c6e22 (diff)
downloadmrust-d14787eb48b60a7e1149736f929be809af857e95.tar.gz
Parse - Hack in `pub(restricted)` support
Diffstat (limited to 'src')
-rw-r--r--src/parse/root.cpp112
1 files changed, 73 insertions, 39 deletions
diff --git a/src/parse/root.cpp b/src/parse/root.cpp
index e5f5b5f4..aefd5a13 100644
--- a/src/parse/root.cpp
+++ b/src/parse/root.cpp
@@ -43,6 +43,63 @@ Spanned<T> get_spanned(TokenStream& lex, ::std::function<T()> f) {
AST::MetaItem Parse_MetaItem(TokenStream& lex);
void Parse_ModRoot(TokenStream& lex, AST::Module& mod, AST::MetaItems& mod_attrs);
+//::AST::Path Parse_Publicity(TokenStream& lex)
+bool Parse_Publicity(TokenStream& lex)
+{
+ Token tok;
+ if( LOOK_AHEAD(lex) == TOK_RWORD_PUB )
+ {
+ GET_TOK(tok, lex);
+ if( LOOK_AHEAD(lex) == TOK_PAREN_OPEN )
+ {
+ auto path = AST::Path("", {});
+ // Restricted publicity.
+ GET_TOK(tok, lex); // '('
+
+ switch(GET_TOK(tok, lex))
+ {
+ case TOK_RWORD_CRATE:
+ // Crate visibility
+ break;
+ case TOK_RWORD_SELF:
+ // Private!
+ path = AST::Path( lex.parse_state().get_current_mod().path() );
+ break;
+ case TOK_RWORD_SUPER:
+ path = AST::Path( lex.parse_state().get_current_mod().path() );
+ path.nodes().pop_back();
+ while( lex.lookahead(0) == TOK_DOUBLE_COLON && lex.lookahead(1) == TOK_RWORD_SUPER )
+ {
+ GET_TOK(tok, lex);
+ GET_TOK(tok, lex);
+ path.nodes().pop_back();
+ }
+ if( lex.lookahead(0) != TOK_DOUBLE_COLON )
+ break;
+ GET_TOK(tok, lex);
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ case TOK_IDENT:
+ path.nodes().push_back( AST::PathNode(tok.str()) );
+ while( LOOK_AHEAD(lex) == TOK_DOUBLE_COLON )
+ {
+ GET_TOK(tok, lex);
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ path.nodes().push_back( AST::PathNode(tok.str()) );
+ }
+ break;
+ default:
+ throw ParseError::Unexpected(lex, tok);
+ }
+ GET_CHECK_TOK(tok, lex, TOK_PAREN_CLOSE);
+ }
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
::std::vector< ::std::string> Parse_HRB(TokenStream& lex)
{
TRACE_FUNCTION;
@@ -483,11 +540,8 @@ AST::Struct Parse_Struct(TokenStream& lex, const AST::MetaItems& meta_items)
}
SET_ATTRS(lex, item_attrs);
- bool is_pub = false;
- if(tok.type() == TOK_RWORD_PUB)
- is_pub = true;
- else
- PUTBACK(tok, lex);
+ PUTBACK(tok, lex);
+ bool is_pub = Parse_Publicity(lex);
refs.push_back( AST::TupleItem( mv$(item_attrs), is_pub, Parse_Type(lex) ) );
if( GET_TOK(tok, lex) != TOK_COMMA )
@@ -524,13 +578,10 @@ AST::Struct Parse_Struct(TokenStream& lex, const AST::MetaItems& meta_items)
}
SET_ATTRS(lex, item_attrs);
- bool is_pub = false;
- if(tok.type() == TOK_RWORD_PUB) {
- is_pub = true;
- GET_TOK(tok, lex);
- }
+ PUTBACK(tok, lex);
+ bool is_pub = Parse_Publicity(lex);
- CHECK_TOK(tok, TOK_IDENT);
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
auto name = mv$(tok.str());
GET_CHECK_TOK(tok, lex, TOK_COLON);
TypeRef type = Parse_Type(lex);
@@ -883,11 +934,7 @@ AST::Enum Parse_EnumDef(TokenStream& lex, const AST::MetaItems& meta_items)
}
SET_ATTRS(lex, item_attrs);
- bool is_pub = false;
- if( LOOK_AHEAD(lex) == TOK_RWORD_PUB ) {
- is_pub = true;
- GET_TOK(tok, lex);
- }
+ bool is_pub = Parse_Publicity(lex);
GET_CHECK_TOK(tok, lex, TOK_IDENT);
auto name = mv$(tok.str());
@@ -1066,11 +1113,9 @@ void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl)
auto ps = lex.start_span();
- bool is_public = false;
- if(tok.type() == TOK_RWORD_PUB) {
- is_public = true;
- GET_TOK(tok, lex);
- }
+ PUTBACK(tok, lex);
+ bool is_public = Parse_Publicity(lex);
+ GET_TOK(tok, lex);
bool is_specialisable = false;
if( tok.type() == TOK_IDENT && tok.str() == "default" ) {
@@ -1178,12 +1223,9 @@ AST::ExternBlock Parse_ExternBlock(TokenStream& lex, ::std::string abi, ::AST::M
auto ps = lex.start_span();
- bool is_public = false;
- if( tok.type() == TOK_RWORD_PUB ) {
- is_public = true;
- GET_TOK(tok, lex);
- }
- switch(tok.type())
+ PUTBACK(tok, lex);
+ bool is_public = Parse_Publicity(lex);
+ switch( GET_TOK(tok, lex) )
{
case TOK_RWORD_FN: {
GET_CHECK_TOK(tok, lex, TOK_IDENT);
@@ -1413,13 +1455,7 @@ void Parse_Use(TokenStream& lex, ::std::function<void(AST::UseStmt, ::std::strin
return ::AST::Named< ::AST::Item> { "", mv$(item_data), false };
}
- bool is_public = false;
- if( GET_TOK(tok, lex) == TOK_RWORD_PUB ) {
- is_public = true;
- }
- else {
- PUTBACK(tok, lex);
- }
+ bool is_public = Parse_Publicity(lex);
switch( GET_TOK(tok, lex) )
{
@@ -1788,13 +1824,11 @@ void Parse_Mod_Item(TokenStream& lex, AST::Module& mod, AST::MetaItems meta_item
Token tok;
// `use ...`
+ // TODO: This doesn't spot `pub(path) use`.
if( LOOK_AHEAD(lex) == TOK_RWORD_USE || (lex.lookahead(0) == TOK_RWORD_PUB && lex.lookahead(1) == TOK_RWORD_USE) )
{
- bool is_public = false;
- if( GET_TOK(tok, lex) == TOK_RWORD_PUB ) {
- is_public = true;
- GET_TOK(tok, lex);
- }
+ bool is_public = Parse_Publicity(lex);
+ GET_CHECK_TOK(tok, lex, TOK_RWORD_USE);
Parse_Use(lex, [&mod,is_public,&meta_items](AST::UseStmt p, std::string s) {
DEBUG(mod.path() << " - use " << p << " as '" << s << "'");