diff options
| author | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2017-03-05 05:15:58 +0000 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2017-03-10 08:08:32 -0800 |
| commit | 212b6c25507b963b60a646a2ff3df7496bd30acf (patch) | |
| tree | 8fd7c3e2317c5b9c92e17aaec9b4c48a72f75ac7 /src/libsyntax/parse | |
| parent | f573db4f80c75f156df8a743f456bf087ec81dc2 (diff) | |
| download | rust-212b6c25507b963b60a646a2ff3df7496bd30acf.tar.gz rust-212b6c25507b963b60a646a2ff3df7496bd30acf.zip | |
Refactor out `ast::ItemKind::MacroDef`.
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 6c566dab1d6..d81732489dd 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -43,6 +43,7 @@ use {ast, attr}; use codemap::{self, CodeMap, Spanned, spanned, respan}; use syntax_pos::{self, Span, Pos, BytePos, mk_sp}; use errors::{self, DiagnosticBuilder}; +use ext::hygiene::Mark; use parse::{self, classify, token}; use parse::common::SeqSep; use parse::lexer::TokenAndSpan; @@ -1048,7 +1049,7 @@ impl<'a> Parser<'a> { self.expected_tokens.clear(); } - pub fn look_ahead<R, F>(&mut self, dist: usize, f: F) -> R where + pub fn look_ahead<R, F>(&self, dist: usize, f: F) -> R where F: FnOnce(&token::Token) -> R, { if dist == 0 { @@ -3699,11 +3700,41 @@ impl<'a> Parser<'a> { }) } - fn is_union_item(&mut self) -> bool { + fn is_union_item(&self) -> bool { self.token.is_keyword(keywords::Union) && self.look_ahead(1, |t| t.is_ident() && !t.is_any_keyword()) } + fn eat_macro_def(&mut self, attrs: &[Attribute], vis: &Visibility) + -> PResult<'a, Option<P<Item>>> { + let lo = self.span.lo; + match self.token { + token::Ident(ident) if ident.name == "macro_rules" => { + if self.look_ahead(1, |t| *t == token::Not) { + let prev_span = self.prev_span; + self.complain_if_pub_macro(vis, prev_span); + self.bump(); + self.bump(); + } + } + _ => return Ok(None), + }; + + let id = self.parse_ident()?; + let (delim, tts) = self.expect_delimited_token_tree()?; + if delim != token::Brace { + if !self.eat(&token::Semi) { + let msg = "macros that expand to items must either be surrounded with braces \ + or followed by a semicolon"; + self.span_err(self.prev_span, msg); + } + } + + let hi = self.prev_span.hi; + let kind = ItemKind::MacroDef(tts, Mark::fresh()); + Ok(Some(self.mk_item(lo, hi, id, kind, Visibility::Inherited, attrs.to_owned()))) + } + fn parse_stmt_without_recovery(&mut self, macro_legacy_warnings: bool) -> PResult<'a, Option<Stmt>> { @@ -3718,6 +3749,12 @@ impl<'a> Parser<'a> { node: StmtKind::Local(self.parse_local(attrs.into())?), span: mk_sp(lo, self.prev_span.hi), } + } else if let Some(macro_def) = self.eat_macro_def(&attrs, &Visibility::Inherited)? { + Stmt { + id: ast::DUMMY_NODE_ID, + node: StmtKind::Item(macro_def), + span: mk_sp(lo, self.prev_span.hi), + } // Starts like a simple path, but not a union item. } else if self.token.is_path_start() && !self.token.is_qpath_start() && @@ -5767,6 +5804,10 @@ impl<'a> Parser<'a> { maybe_append(attrs, extra_attrs)); return Ok(Some(item)); } + if let Some(macro_def) = self.eat_macro_def(&attrs, &visibility)? { + return Ok(Some(macro_def)); + } + self.parse_macro_use_or_failure(attrs,macros_allowed,attributes_allowed,lo,visibility) } @@ -5948,7 +5989,6 @@ impl<'a> Parser<'a> { attrs: self.parse_inner_attributes()?, module: self.parse_mod_items(&token::Eof, lo)?, span: mk_sp(lo, self.span.lo), - exported_macros: Vec::new(), }) } |
