diff options
| author | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2017-03-08 23:13:35 +0000 |
|---|---|---|
| committer | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2017-03-14 04:39:21 +0000 |
| commit | 839c2860ccb7cd3d381abf2838dfba566f52618e (patch) | |
| tree | de9b57f15703328322a174cb820ba1e97bd29bba /src/libsyntax/parse | |
| parent | 68c1cc68b44bb987ec57251bc457a55292515d1d (diff) | |
| download | rust-839c2860ccb7cd3d381abf2838dfba566f52618e.tar.gz rust-839c2860ccb7cd3d381abf2838dfba566f52618e.zip | |
Liberalize attributes.
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/attr.rs | 32 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 11 |
2 files changed, 36 insertions, 7 deletions
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index 272cff7ad34..53106214fa3 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -14,8 +14,9 @@ use syntax_pos::{mk_sp, Span}; use codemap::spanned; use parse::common::SeqSep; use parse::PResult; -use parse::token; -use parse::parser::{Parser, TokenType}; +use parse::token::{self, Nonterminal}; +use parse::parser::{Parser, TokenType, PathStyle}; +use tokenstream::TokenStream; #[derive(PartialEq, Eq, Debug)] enum InnerAttributeParsePolicy<'a> { @@ -91,7 +92,7 @@ impl<'a> Parser<'a> { debug!("parse_attribute_with_inner_parse_policy: inner_parse_policy={:?} self.token={:?}", inner_parse_policy, self.token); - let (span, value, mut style) = match self.token { + let (span, path, tokens, mut style) = match self.token { token::Pound => { let lo = self.span.lo; self.bump(); @@ -119,11 +120,11 @@ impl<'a> Parser<'a> { }; self.expect(&token::OpenDelim(token::Bracket))?; - let meta_item = self.parse_meta_item()?; + let (path, tokens) = self.parse_path_and_tokens()?; self.expect(&token::CloseDelim(token::Bracket))?; let hi = self.prev_span.hi; - (mk_sp(lo, hi), meta_item, style) + (mk_sp(lo, hi), path, tokens, style) } _ => { let token_str = self.this_token_to_string(); @@ -143,13 +144,30 @@ impl<'a> Parser<'a> { Ok(ast::Attribute { id: attr::mk_attr_id(), style: style, - path: ast::Path::from_ident(value.span, ast::Ident::with_empty_ctxt(value.name)), - tokens: value.node.tokens(value.span), + path: path, + tokens: tokens, is_sugared_doc: false, span: span, }) } + pub fn parse_path_and_tokens(&mut self) -> PResult<'a, (ast::Path, TokenStream)> { + let meta = match self.token { + token::Interpolated(ref nt) => match **nt { + Nonterminal::NtMeta(ref meta) => Some(meta.clone()), + _ => None, + }, + _ => None, + }; + Ok(if let Some(meta) = meta { + self.bump(); + (ast::Path::from_ident(meta.span, ast::Ident::with_empty_ctxt(meta.name)), + meta.node.tokens(meta.span)) + } else { + (self.parse_path(PathStyle::Mod)?, self.parse_tokens()) + }) + } + /// Parse attributes that appear after the opening of an item. These should /// be preceded by an exclamation mark, but we accept and warn about one /// terminated by a semicolon. diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ed512b89987..308876fed56 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2644,6 +2644,17 @@ impl<'a> Parser<'a> { Ok(tts) } + pub fn parse_tokens(&mut self) -> TokenStream { + let mut result = Vec::new(); + loop { + match self.token { + token::Eof | token::CloseDelim(..) => break, + _ => result.push(self.parse_token_tree().into()), + } + } + TokenStream::concat(result) + } + /// Parse a prefix-unary-operator expr pub fn parse_prefix_expr(&mut self, already_parsed_attrs: Option<ThinVec<Attribute>>) |
