diff options
| author | bors <bors@rust-lang.org> | 2016-07-29 16:26:38 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-07-29 16:26:38 -0700 |
| commit | f164cf5d6443fd265f93662055d744074648189f (patch) | |
| tree | e84bccd6a04c054c1dab83eb206932e23a5c810c /src/libsyntax | |
| parent | 5a7773a18098be712d7e1ce4fded36aed8c3c311 (diff) | |
| parent | 5553901146fa80c652abdc514b38360a0ae7418d (diff) | |
| download | rust-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.rs | 93 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 23 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 5 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate.rs | 15 |
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; |
