about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-07-29 16:26:38 -0700
committerGitHub <noreply@github.com>2016-07-29 16:26:38 -0700
commitf164cf5d6443fd265f93662055d744074648189f (patch)
treee84bccd6a04c054c1dab83eb206932e23a5c810c /src/libsyntax
parent5a7773a18098be712d7e1ce4fded36aed8c3c311 (diff)
parent5553901146fa80c652abdc514b38360a0ae7418d (diff)
downloadrust-f164cf5d6443fd265f93662055d744074648189f.tar.gz
rust-f164cf5d6443fd265f93662055d744074648189f.zip
Auto merge of #34842 - cgswords:attr_enc, r=nrc
Better attribute and metaitem encapsulation throughout the compiler

This PR refactors most (hopefully all?) of the `MetaItem` interactions outside of `libsyntax` (and a few inside) to interact with MetaItems through the provided traits instead of directly creating / destruct / matching against them. This is a necessary first step to eventually converting `MetaItem`s to internally use `TokenStream` representations (which will make `MetaItem` interactions much nicer for macro writers once the new macro system is in place).

r? @nrc
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/attr.rs93
-rw-r--r--src/libsyntax/ext/build.rs23
-rw-r--r--src/libsyntax/ext/expand.rs5
-rw-r--r--src/libsyntax/feature_gate.rs15
4 files changed, 94 insertions, 42 deletions
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
index 67f73d4dd4f..b622f6861b3 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -17,8 +17,8 @@ pub use self::IntType::*;
 use ast;
 use ast::{AttrId, Attribute, Attribute_, MetaItem, MetaItemKind};
 use ast::{Expr, Item, Local, Stmt, StmtKind};
-use codemap::{spanned, dummy_spanned, Spanned};
-use syntax_pos::{Span, BytePos};
+use codemap::{respan, spanned, dummy_spanned, Spanned};
+use syntax_pos::{Span, BytePos, DUMMY_SP};
 use errors::Handler;
 use feature_gate::{Features, GatedCfg};
 use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
@@ -92,6 +92,19 @@ pub trait AttrMetaMethods {
     /// Gets a list of inner meta items from a list MetaItem type.
     fn meta_item_list(&self) -> Option<&[P<MetaItem>]>;
 
+    /// Indicates if the attribute is a Word.
+    fn is_word(&self) -> bool;
+
+    /// Indicates if the attribute is a Value String.
+    fn is_value_str(&self) -> bool {
+        self.value_str().is_some()
+    }
+
+    /// Indicates if the attribute is a Meta-Item List.
+    fn is_meta_item_list(&self) -> bool {
+        self.meta_item_list().is_some()
+    }
+
     fn span(&self) -> Span;
 }
 
@@ -108,8 +121,11 @@ impl AttrMetaMethods for Attribute {
         self.meta().value_str()
     }
     fn meta_item_list(&self) -> Option<&[P<MetaItem>]> {
-        self.node.value.meta_item_list()
+        self.meta().meta_item_list()
     }
+
+    fn is_word(&self) -> bool { self.meta().is_word() }
+
     fn span(&self) -> Span { self.meta().span }
 }
 
@@ -140,6 +156,14 @@ impl AttrMetaMethods for MetaItem {
             _ => None
         }
     }
+
+    fn is_word(&self) -> bool {
+        match self.node {
+            MetaItemKind::Word(_) => true,
+            _ => false,
+        }
+    }
+
     fn span(&self) -> Span { self.span }
 }
 
@@ -150,6 +174,9 @@ impl AttrMetaMethods for P<MetaItem> {
     fn meta_item_list(&self) -> Option<&[P<MetaItem>]> {
         (**self).meta_item_list()
     }
+    fn is_word(&self) -> bool { (**self).is_word() }
+    fn is_value_str(&self) -> bool { (**self).is_value_str() }
+    fn is_meta_item_list(&self) -> bool { (**self).is_meta_item_list() }
     fn span(&self) -> Span { (**self).span() }
 }
 
@@ -194,22 +221,38 @@ impl AttributeMethods for Attribute {
 pub fn mk_name_value_item_str(name: InternedString, value: InternedString)
                               -> P<MetaItem> {
     let value_lit = dummy_spanned(ast::LitKind::Str(value, ast::StrStyle::Cooked));
-    mk_name_value_item(name, value_lit)
+    mk_spanned_name_value_item(DUMMY_SP, name, value_lit)
 }
 
 pub fn mk_name_value_item(name: InternedString, value: ast::Lit)
                           -> P<MetaItem> {
-    P(dummy_spanned(MetaItemKind::NameValue(name, value)))
+    mk_spanned_name_value_item(DUMMY_SP, name, value)
 }
 
 pub fn mk_list_item(name: InternedString, items: Vec<P<MetaItem>>) -> P<MetaItem> {
-    P(dummy_spanned(MetaItemKind::List(name, items)))
+    mk_spanned_list_item(DUMMY_SP, name, items)
 }
 
 pub fn mk_word_item(name: InternedString) -> P<MetaItem> {
-    P(dummy_spanned(MetaItemKind::Word(name)))
+    mk_spanned_word_item(DUMMY_SP, name)
+}
+
+pub fn mk_spanned_name_value_item(sp: Span, name: InternedString, value: ast::Lit)
+                          -> P<MetaItem> {
+    P(respan(sp, MetaItemKind::NameValue(name, value)))
+}
+
+pub fn mk_spanned_list_item(sp: Span, name: InternedString, items: Vec<P<MetaItem>>)
+                            -> P<MetaItem> {
+    P(respan(sp, MetaItemKind::List(name, items)))
+}
+
+pub fn mk_spanned_word_item(sp: Span, name: InternedString) -> P<MetaItem> {
+    P(respan(sp, MetaItemKind::Word(name)))
 }
 
+
+
 thread_local! { static NEXT_ATTR_ID: Cell<usize> = Cell::new(0) }
 
 pub fn mk_attr_id() -> AttrId {
@@ -223,21 +266,43 @@ pub fn mk_attr_id() -> AttrId {
 
 /// Returns an inner attribute with the given value.
 pub fn mk_attr_inner(id: AttrId, item: P<MetaItem>) -> Attribute {
-    dummy_spanned(Attribute_ {
-        id: id,
-        style: ast::AttrStyle::Inner,
-        value: item,
-        is_sugared_doc: false,
-    })
+    mk_spanned_attr_inner(DUMMY_SP, id, item)
+}
+
+/// Returns an innter attribute with the given value and span.
+pub fn mk_spanned_attr_inner(sp: Span, id: AttrId, item: P<MetaItem>) -> Attribute {
+    respan(sp,
+           Attribute_ {
+            id: id,
+            style: ast::AttrStyle::Inner,
+            value: item,
+            is_sugared_doc: false,
+          })
 }
 
+
 /// Returns an outer attribute with the given value.
 pub fn mk_attr_outer(id: AttrId, item: P<MetaItem>) -> Attribute {
+    mk_spanned_attr_outer(DUMMY_SP, id, item)
+}
+
+/// Returns an outer attribute with the given value and span.
+pub fn mk_spanned_attr_outer(sp: Span, id: AttrId, item: P<MetaItem>) -> Attribute {
+    respan(sp,
+           Attribute_ {
+            id: id,
+            style: ast::AttrStyle::Outer,
+            value: item,
+            is_sugared_doc: false,
+          })
+}
+
+pub fn mk_doc_attr_outer(id: AttrId, item: P<MetaItem>, is_sugared_doc: bool) -> Attribute {
     dummy_spanned(Attribute_ {
         id: id,
         style: ast::AttrStyle::Outer,
         value: item,
-        is_sugared_doc: false,
+        is_sugared_doc: is_sugared_doc,
     })
 }
 
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 435241f426e..5d6429f7bdf 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -1135,30 +1135,19 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
     }
 
     fn attribute(&self, sp: Span, mi: P<ast::MetaItem>) -> ast::Attribute {
-        respan(sp, ast::Attribute_ {
-            id: attr::mk_attr_id(),
-            style: ast::AttrStyle::Outer,
-            value: mi,
-            is_sugared_doc: false,
-        })
+        attr::mk_spanned_attr_outer(sp, attr::mk_attr_id(), mi)
     }
 
     fn meta_word(&self, sp: Span, w: InternedString) -> P<ast::MetaItem> {
-        P(respan(sp, ast::MetaItemKind::Word(w)))
+        attr::mk_spanned_word_item(sp, w)
     }
-    fn meta_list(&self,
-                 sp: Span,
-                 name: InternedString,
-                 mis: Vec<P<ast::MetaItem>> )
+    fn meta_list(&self, sp: Span, name: InternedString, mis: Vec<P<ast::MetaItem>>)
                  -> P<ast::MetaItem> {
-        P(respan(sp, ast::MetaItemKind::List(name, mis)))
+        attr::mk_spanned_list_item(sp, name, mis)
     }
-    fn meta_name_value(&self,
-                       sp: Span,
-                       name: InternedString,
-                       value: ast::LitKind)
+    fn meta_name_value(&self, sp: Span, name: InternedString, value: ast::LitKind)
                        -> P<ast::MetaItem> {
-        P(respan(sp, ast::MetaItemKind::NameValue(name, respan(sp, value))))
+        attr::mk_spanned_name_value_item(sp, name, respan(sp, value))
     }
 
     fn item_use(&self, sp: Span,
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 18342f2e38c..5293d2ab000 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -302,9 +302,8 @@ fn contains_macro_use(fld: &mut MacroExpander, attrs: &[ast::Attribute]) -> bool
         };
 
         if is_use {
-            match attr.node.value.node {
-                ast::MetaItemKind::Word(..) => (),
-                _ => fld.cx.span_err(attr.span, "arguments to macro_use are not allowed here"),
+            if !attr.is_word() {
+              fld.cx.span_err(attr.span, "arguments to macro_use are not allowed here");
             }
             return true;
         }
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index f80f25a2e77..2ead0f2f20e 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -1118,14 +1118,13 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute]) -> F
             }
             Some(list) => {
                 for mi in list {
-                    let name = match mi.node {
-                        ast::MetaItemKind::Word(ref word) => (*word).clone(),
-                        _ => {
-                            span_err!(span_handler, mi.span, E0556,
-                                      "malformed feature, expected just one word");
-                            continue
-                        }
-                    };
+                    let name = if mi.is_word() {
+                                   mi.name()
+                               } else {
+                                   span_err!(span_handler, mi.span, E0556,
+                                             "malformed feature, expected just one word");
+                                   continue
+                               };
                     if let Some(&(_, _, _, setter)) = ACTIVE_FEATURES.iter()
                         .find(|& &(n, _, _, _)| name == n) {
                         *(setter(&mut features)) = true;