about summary refs log tree commit diff
path: root/src/libsyntax/parse/attr.rs
diff options
context:
space:
mode:
authorQuietMisdreavus <grey@quietmisdreavus.net>2017-04-09 10:38:38 -0500
committerQuietMisdreavus <grey@quietmisdreavus.net>2017-04-09 10:38:38 -0500
commit8dd4c44ef6c851afcc9651c9b32df005e35d0d1d (patch)
tree5dc8ec96361b673f8d4162821a97f8f021d83436 /src/libsyntax/parse/attr.rs
parentbfd01b7f40ae2cbfe9acbc1d10e79ffe16870df8 (diff)
parent2c48ae6f7ffae392d85c86240c67f49df01f44fd (diff)
merge with master to pick up pulldown switch
Diffstat (limited to 'src/libsyntax/parse/attr.rs')
-rw-r--r--src/libsyntax/parse/attr.rs67
1 files changed, 43 insertions, 24 deletions
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index ded676da3c6..92cec462ffb 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -10,12 +10,12 @@
 
 use attr;
 use ast;
-use syntax_pos::{mk_sp, Span};
-use codemap::spanned;
+use codemap::respan;
 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> {
@@ -48,8 +48,7 @@ impl<'a> Parser<'a> {
                     just_parsed_doc_comment = false;
                 }
                 token::DocComment(s) => {
-                    let Span { lo, hi, .. } = self.span;
-                    let attr = attr::mk_sugared_doc_attr(attr::mk_attr_id(), s, lo, hi);
+                    let attr = attr::mk_sugared_doc_attr(attr::mk_attr_id(), s, self.span);
                     if attr.style != ast::AttrStyle::Outer {
                         let mut err = self.fatal("expected outer doc comment");
                         err.note("inner doc comments like this (starting with \
@@ -91,9 +90,9 @@ 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;
+                let lo = self.span;
                 self.bump();
 
                 if inner_parse_policy == InnerAttributeParsePolicy::Permitted {
@@ -119,11 +118,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;
+                let hi = self.prev_span;
 
-                (mk_sp(lo, hi), meta_item, style)
+                (lo.to(hi), path, tokens, style)
             }
             _ => {
                 let token_str = self.this_token_to_string();
@@ -143,12 +142,30 @@ impl<'a> Parser<'a> {
         Ok(ast::Attribute {
             id: attr::mk_attr_id(),
             style: style,
-            value: value,
+            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.
@@ -170,8 +187,7 @@ impl<'a> Parser<'a> {
                 }
                 token::DocComment(s) => {
                     // we need to get the position of this token before we bump.
-                    let Span { lo, hi, .. } = self.span;
-                    let attr = attr::mk_sugared_doc_attr(attr::mk_attr_id(), s, lo, hi);
+                    let attr = attr::mk_sugared_doc_attr(attr::mk_attr_id(), s, self.span);
                     if attr.style == ast::AttrStyle::Inner {
                         attrs.push(attr);
                         self.bump();
@@ -219,41 +235,44 @@ impl<'a> Parser<'a> {
             return Ok(meta);
         }
 
-        let lo = self.span.lo;
+        let lo = self.span;
         let ident = self.parse_ident()?;
-        let node = if self.eat(&token::Eq) {
+        let node = self.parse_meta_item_kind()?;
+        Ok(ast::MetaItem { name: ident.name, node: node, span: lo.to(self.prev_span) })
+    }
+
+    pub fn parse_meta_item_kind(&mut self) -> PResult<'a, ast::MetaItemKind> {
+        Ok(if self.eat(&token::Eq) {
             ast::MetaItemKind::NameValue(self.parse_unsuffixed_lit()?)
         } else if self.token == token::OpenDelim(token::Paren) {
             ast::MetaItemKind::List(self.parse_meta_seq()?)
         } else {
+            self.eat(&token::OpenDelim(token::Paren));
             ast::MetaItemKind::Word
-        };
-        let hi = self.prev_span.hi;
-        Ok(ast::MetaItem { name: ident.name, node: node, span: mk_sp(lo, hi) })
+        })
     }
 
     /// matches meta_item_inner : (meta_item | UNSUFFIXED_LIT) ;
     fn parse_meta_item_inner(&mut self) -> PResult<'a, ast::NestedMetaItem> {
-        let sp = self.span;
-        let lo = self.span.lo;
+        let lo = self.span;
 
         match self.parse_unsuffixed_lit() {
             Ok(lit) => {
-                return Ok(spanned(lo, self.prev_span.hi, ast::NestedMetaItemKind::Literal(lit)))
+                return Ok(respan(lo.to(self.prev_span), ast::NestedMetaItemKind::Literal(lit)))
             }
             Err(ref mut err) => self.diagnostic().cancel(err)
         }
 
         match self.parse_meta_item() {
             Ok(mi) => {
-                return Ok(spanned(lo, self.prev_span.hi, ast::NestedMetaItemKind::MetaItem(mi)))
+                return Ok(respan(lo.to(self.prev_span), ast::NestedMetaItemKind::MetaItem(mi)))
             }
             Err(ref mut err) => self.diagnostic().cancel(err)
         }
 
         let found = self.this_token_to_string();
         let msg = format!("expected unsuffixed literal or identifier, found {}", found);
-        Err(self.diagnostic().struct_span_err(sp, &msg))
+        Err(self.diagnostic().struct_span_err(lo, &msg))
     }
 
     /// matches meta_seq = ( COMMASEP(meta_item_inner) )