General MetaItem encapsulation rewrites.
This commit is contained in:
parent
9316ae515e
commit
a5e5ea1646
@ -366,19 +366,19 @@ pub fn gather_attr(attr: &ast::Attribute)
|
||||
attr::mark_used(attr);
|
||||
|
||||
let meta = &attr.node.value;
|
||||
let metas = match meta.node {
|
||||
ast::MetaItemKind::List(_, ref metas) => metas,
|
||||
_ => {
|
||||
out.push(Err(meta.span));
|
||||
return out;
|
||||
}
|
||||
};
|
||||
let metas = if let Some(metas) = meta.meta_item_list() {
|
||||
metas
|
||||
} else {
|
||||
out.push(Err(meta.span));
|
||||
return out;
|
||||
};
|
||||
|
||||
for meta in metas {
|
||||
out.push(match meta.node {
|
||||
ast::MetaItemKind::Word(ref lint_name) => Ok((lint_name.clone(), level, meta.span)),
|
||||
_ => Err(meta.span),
|
||||
});
|
||||
out.push(if meta.is_word() {
|
||||
Ok((meta.name().clone(), level, meta.span))
|
||||
} else {
|
||||
Err(meta.span)
|
||||
});
|
||||
}
|
||||
|
||||
out
|
||||
|
@ -95,6 +95,7 @@ use std::thread;
|
||||
use rustc::session::early_error;
|
||||
|
||||
use syntax::{ast, json};
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::codemap::{CodeMap, FileLoader, RealFileLoader};
|
||||
use syntax::feature_gate::{GatedCfg, UnstableFeatures};
|
||||
use syntax::parse::{self, PResult};
|
||||
@ -392,15 +393,13 @@ fn check_cfg(sopts: &config::Options,
|
||||
|
||||
let mut saw_invalid_predicate = false;
|
||||
for item in sopts.cfg.iter() {
|
||||
match item.node {
|
||||
ast::MetaItemKind::List(ref pred, _) => {
|
||||
saw_invalid_predicate = true;
|
||||
handler.emit(&MultiSpan::new(),
|
||||
&format!("invalid predicate in --cfg command line argument: `{}`",
|
||||
pred),
|
||||
errors::Level::Fatal);
|
||||
}
|
||||
_ => {},
|
||||
if item.is_meta_item_list() {
|
||||
saw_invalid_predicate = true;
|
||||
saw_invalid_predicate = true;
|
||||
handler.emit(&MultiSpan::new(),
|
||||
&format!("invalid predicate in --cfg command line argument: `{}`",
|
||||
pred),
|
||||
errors::Level::Fatal);
|
||||
}
|
||||
}
|
||||
|
||||
@ -649,20 +648,19 @@ impl RustcDefaultCalls {
|
||||
if !allow_unstable_cfg && GatedCfg::gate(&*cfg).is_some() {
|
||||
continue;
|
||||
}
|
||||
match cfg.node {
|
||||
ast::MetaItemKind::Word(ref word) => println!("{}", word),
|
||||
ast::MetaItemKind::NameValue(ref name, ref value) => {
|
||||
println!("{}=\"{}\"", name, match value.node {
|
||||
ast::LitKind::Str(ref s, _) => s,
|
||||
_ => continue,
|
||||
});
|
||||
if cfg.is_word() {
|
||||
println!("{}", cfg.name());
|
||||
} else if cfg.is_value_str() {
|
||||
let rhs = cfg.value_str();
|
||||
match rhs {
|
||||
Some(s) => println!("{}=\"{}\"", cfg.name(), s),
|
||||
None => continue,
|
||||
}
|
||||
} else if cfg.is_meta_item_list() {
|
||||
// Right now there are not and should not be any
|
||||
// MetaItemKind::List items in the configuration returned by
|
||||
// `build_configuration`.
|
||||
ast::MetaItemKind::List(..) => {
|
||||
panic!("MetaItemKind::List encountered in default cfg")
|
||||
}
|
||||
panic!("MetaItemKind::List encountered in default cfg")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -110,13 +110,13 @@ impl<'a, 'tcx> IfThisChanged<'a, 'tcx> {
|
||||
if attr.check_name(IF_THIS_CHANGED) {
|
||||
let mut id = None;
|
||||
for meta_item in attr.meta_item_list().unwrap_or_default() {
|
||||
match meta_item.node {
|
||||
ast::MetaItemKind::Word(ref s) if id.is_none() => id = Some(s.clone()),
|
||||
_ => {
|
||||
self.tcx.sess.span_err(
|
||||
meta_item.span,
|
||||
&format!("unexpected meta-item {:?}", meta_item.node));
|
||||
}
|
||||
if meta_item.is_word() && id.is_none() {
|
||||
id = Some(meta_item.name().clone());
|
||||
} else {
|
||||
// FIXME better-encapsulate meta_item (don't directly access `node`)
|
||||
self.tcx.sess.span_err(
|
||||
meta_item.span(),
|
||||
&format!("unexpected meta-item {:?}", meta_item.node));
|
||||
}
|
||||
}
|
||||
let id = id.unwrap_or(InternedString::new(ID));
|
||||
@ -127,16 +127,15 @@ impl<'a, 'tcx> IfThisChanged<'a, 'tcx> {
|
||||
let mut dep_node_interned = None;
|
||||
let mut id = None;
|
||||
for meta_item in attr.meta_item_list().unwrap_or_default() {
|
||||
match meta_item.node {
|
||||
ast::MetaItemKind::Word(ref s) if dep_node_interned.is_none() =>
|
||||
dep_node_interned = Some(s.clone()),
|
||||
ast::MetaItemKind::Word(ref s) if id.is_none() =>
|
||||
id = Some(s.clone()),
|
||||
_ => {
|
||||
self.tcx.sess.span_err(
|
||||
meta_item.span,
|
||||
&format!("unexpected meta-item {:?}", meta_item.node));
|
||||
}
|
||||
if meta_item.is_word() && dep_node_interned.is_none() {
|
||||
dep_node_interned = Some(meta_item.name().clone());
|
||||
} else if meta_item.is_word() && id.is_none() {
|
||||
id = Some(meta_item.name().clone());
|
||||
} else {
|
||||
// FIXME better-encapsulate meta_item (don't directly access `node`)
|
||||
self.tcx.sess.span_err(
|
||||
meta_item.span(),
|
||||
&format!("unexpected meta-item {:?}", meta_item.node));
|
||||
}
|
||||
}
|
||||
let dep_node = match dep_node_interned {
|
||||
|
@ -11,6 +11,7 @@
|
||||
//! Calculation of a Strict Version Hash for crates. For a length
|
||||
//! comment explaining the general idea, see `librustc/middle/svh.rs`.
|
||||
|
||||
use syntax::attr::AttributeMethods;
|
||||
use std::hash::{Hash, SipHasher, Hasher};
|
||||
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
|
||||
use rustc::hir::svh::Svh;
|
||||
@ -69,7 +70,7 @@ impl<'a, 'tcx> SvhCalculate for TyCtxt<'a, 'tcx, 'tcx> {
|
||||
// to avoid hashing the AttrId
|
||||
for attr in &krate.attrs {
|
||||
debug!("krate attr {:?}", attr);
|
||||
attr.node.value.hash(&mut state);
|
||||
attr.meta().hash(&mut state);
|
||||
}
|
||||
|
||||
Svh::new(state.finish())
|
||||
|
@ -44,7 +44,7 @@ use lint::{LintPass, LateLintPass};
|
||||
use std::collections::HashSet;
|
||||
|
||||
use syntax::{ast};
|
||||
use syntax::attr::{self, AttrMetaMethods};
|
||||
use syntax::attr::{self, AttrMetaMethods, AttributeMethods};
|
||||
use syntax_pos::{self, Span};
|
||||
|
||||
use rustc::hir::{self, PatKind};
|
||||
@ -299,9 +299,10 @@ impl MissingDoc {
|
||||
}
|
||||
|
||||
let has_doc = attrs.iter().any(|a| {
|
||||
match a.node.value.node {
|
||||
ast::MetaItemKind::NameValue(ref name, _) if *name == "doc" => true,
|
||||
_ => false
|
||||
if a.is_value_str() && a.name() == "doc" {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
});
|
||||
if !has_doc {
|
||||
@ -1094,10 +1095,10 @@ impl LintPass for UnstableFeatures {
|
||||
|
||||
impl LateLintPass for UnstableFeatures {
|
||||
fn check_attribute(&mut self, ctx: &LateContext, attr: &ast::Attribute) {
|
||||
if attr::contains_name(&[attr.node.value.clone()], "feature") {
|
||||
if let Some(items) = attr.node.value.meta_item_list() {
|
||||
if attr::contains_name(&[attr.meta().clone()], "feature") {
|
||||
if let Some(items) = attr.meta().meta_item_list() {
|
||||
for item in items {
|
||||
ctx.span_lint(UNSTABLE_FEATURES, item.span, "unstable feature");
|
||||
ctx.span_lint(UNSTABLE_FEATURES, item.span(), "unstable feature");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1160,15 +1160,7 @@ fn get_attributes(md: rbml::Doc) -> Vec<ast::Attribute> {
|
||||
// an attribute
|
||||
assert_eq!(meta_items.len(), 1);
|
||||
let meta_item = meta_items.into_iter().nth(0).unwrap();
|
||||
codemap::Spanned {
|
||||
node: ast::Attribute_ {
|
||||
id: attr::mk_attr_id(),
|
||||
style: ast::AttrStyle::Outer,
|
||||
value: meta_item,
|
||||
is_sugared_doc: is_sugared_doc,
|
||||
},
|
||||
span: syntax_pos::DUMMY_SP
|
||||
}
|
||||
attr::mk_doc_attr_outer(attr::mk_attr_id(), meta_item, is_sugared_doc)
|
||||
}).collect()
|
||||
},
|
||||
None => vec![],
|
||||
|
@ -44,7 +44,7 @@ use std::rc::Rc;
|
||||
use std::u32;
|
||||
use syntax::abi::Abi;
|
||||
use syntax::ast::{self, NodeId, Name, CRATE_NODE_ID, CrateNum};
|
||||
use syntax::attr;
|
||||
use syntax::attr::{self,AttrMetaMethods,AttributeMethods};
|
||||
use errors::Handler;
|
||||
use syntax;
|
||||
use syntax_pos::BytePos;
|
||||
@ -1431,31 +1431,28 @@ fn encode_item_index(rbml_w: &mut Encoder, index: IndexData) {
|
||||
}
|
||||
|
||||
fn encode_meta_item(rbml_w: &mut Encoder, mi: &ast::MetaItem) {
|
||||
match mi.node {
|
||||
ast::MetaItemKind::Word(ref name) => {
|
||||
if mi.is_word() {
|
||||
let name = mi.name();
|
||||
rbml_w.start_tag(tag_meta_item_word);
|
||||
rbml_w.wr_tagged_str(tag_meta_item_name, name);
|
||||
rbml_w.wr_tagged_str(tag_meta_item_name, &name);
|
||||
rbml_w.end_tag();
|
||||
}
|
||||
ast::MetaItemKind::NameValue(ref name, ref value) => {
|
||||
match value.node {
|
||||
ast::LitKind::Str(ref value, _) => {
|
||||
rbml_w.start_tag(tag_meta_item_name_value);
|
||||
rbml_w.wr_tagged_str(tag_meta_item_name, name);
|
||||
rbml_w.wr_tagged_str(tag_meta_item_value, value);
|
||||
rbml_w.end_tag();
|
||||
}
|
||||
_ => {/* FIXME (#623): encode other variants */ }
|
||||
}
|
||||
}
|
||||
ast::MetaItemKind::List(ref name, ref items) => {
|
||||
} else if mi.is_value_str() {
|
||||
let name = mi.name();
|
||||
/* FIXME (#623): support other literal kinds */
|
||||
let value = mi.value_str().unwrap();
|
||||
rbml_w.start_tag(tag_meta_item_name_value);
|
||||
rbml_w.wr_tagged_str(tag_meta_item_name, &name);
|
||||
rbml_w.wr_tagged_str(tag_meta_item_value, &value);
|
||||
rbml_w.end_tag();
|
||||
} else { // it must be a list
|
||||
let name = mi.name();
|
||||
let items = mi.meta_item_list().unwrap();
|
||||
rbml_w.start_tag(tag_meta_item_list);
|
||||
rbml_w.wr_tagged_str(tag_meta_item_name, name);
|
||||
rbml_w.wr_tagged_str(tag_meta_item_name, &name);
|
||||
for inner_item in items {
|
||||
encode_meta_item(rbml_w, &inner_item);
|
||||
}
|
||||
rbml_w.end_tag();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1464,7 +1461,7 @@ fn encode_attributes(rbml_w: &mut Encoder, attrs: &[ast::Attribute]) {
|
||||
for attr in attrs {
|
||||
rbml_w.start_tag(tag_attribute);
|
||||
rbml_w.wr_tagged_u8(tag_attribute_is_sugared_doc, attr.node.is_sugared_doc as u8);
|
||||
encode_meta_item(rbml_w, &attr.node.value);
|
||||
encode_meta_item(rbml_w, attr.meta());
|
||||
rbml_w.end_tag();
|
||||
}
|
||||
rbml_w.end_tag();
|
||||
|
@ -60,10 +60,10 @@ impl<'a> ext::base::MacroLoader for MacroLoader<'a> {
|
||||
}
|
||||
if let (Some(sel), Some(names)) = (import.as_mut(), names) {
|
||||
for attr in names {
|
||||
if let ast::MetaItemKind::Word(ref name) = attr.node {
|
||||
sel.insert(name.clone(), attr.span);
|
||||
if attr.is_word() {
|
||||
sel.insert(attr.name().clone(), attr.span());
|
||||
} else {
|
||||
span_err!(self.sess, attr.span, E0466, "bad macro import");
|
||||
span_err!(self.sess, attr.span(), E0466, "bad macro import");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -78,10 +78,10 @@ impl<'a> ext::base::MacroLoader for MacroLoader<'a> {
|
||||
};
|
||||
|
||||
for attr in names {
|
||||
if let ast::MetaItemKind::Word(ref name) = attr.node {
|
||||
reexport.insert(name.clone(), attr.span);
|
||||
if attr.is_word() {
|
||||
reexport.insert(attr.name().clone(), attr.span());
|
||||
} else {
|
||||
call_bad_macro_reexport(self.sess, attr.span);
|
||||
call_bad_macro_reexport(self.sess, attr.span());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -498,21 +498,20 @@ pub enum Attribute {
|
||||
|
||||
impl Clean<Attribute> for ast::MetaItem {
|
||||
fn clean(&self, cx: &DocContext) -> Attribute {
|
||||
match self.node {
|
||||
ast::MetaItemKind::Word(ref s) => Word(s.to_string()),
|
||||
ast::MetaItemKind::List(ref s, ref l) => {
|
||||
List(s.to_string(), l.clean(cx))
|
||||
}
|
||||
ast::MetaItemKind::NameValue(ref s, ref v) => {
|
||||
NameValue(s.to_string(), lit_to_string(v))
|
||||
}
|
||||
}
|
||||
if self.is_word() {
|
||||
Word(self.name().to_string())
|
||||
} else if let Some(v) = self.value_str() {
|
||||
NameValue(self.name().to_string(), v.to_string())
|
||||
} else { // must be a list
|
||||
let l = self.meta_item_list().unwrap();
|
||||
List(self.name().to_string(), l.clean(cx))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Clean<Attribute> for ast::Attribute {
|
||||
fn clean(&self, cx: &DocContext) -> Attribute {
|
||||
self.with_desugared_doc(|a| a.node.value.clean(cx))
|
||||
self.with_desugared_doc(|a| a.meta().clean(cx))
|
||||
}
|
||||
}
|
||||
|
||||
@ -535,6 +534,28 @@ impl attr::AttrMetaMethods for Attribute {
|
||||
}
|
||||
}
|
||||
fn meta_item_list<'a>(&'a self) -> Option<&'a [P<ast::MetaItem>]> { None }
|
||||
|
||||
fn is_word(&self) -> bool {
|
||||
match *self {
|
||||
Word(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_value_str(&self) -> bool {
|
||||
match *self {
|
||||
NameValue(..) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_meta_item_list(&self) -> bool {
|
||||
match *self {
|
||||
List(..) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn span(&self) -> syntax_pos::Span { unimplemented!() }
|
||||
}
|
||||
|
||||
@ -2568,25 +2589,25 @@ impl ToSource for syntax_pos::Span {
|
||||
}
|
||||
}
|
||||
|
||||
fn lit_to_string(lit: &ast::Lit) -> String {
|
||||
match lit.node {
|
||||
ast::LitKind::Str(ref st, _) => st.to_string(),
|
||||
ast::LitKind::ByteStr(ref data) => format!("{:?}", data),
|
||||
ast::LitKind::Byte(b) => {
|
||||
let mut res = String::from("b'");
|
||||
for c in (b as char).escape_default() {
|
||||
res.push(c);
|
||||
}
|
||||
res.push('\'');
|
||||
res
|
||||
},
|
||||
ast::LitKind::Char(c) => format!("'{}'", c),
|
||||
ast::LitKind::Int(i, _t) => i.to_string(),
|
||||
ast::LitKind::Float(ref f, _t) => f.to_string(),
|
||||
ast::LitKind::FloatUnsuffixed(ref f) => f.to_string(),
|
||||
ast::LitKind::Bool(b) => b.to_string(),
|
||||
}
|
||||
}
|
||||
// fn lit_to_string(lit: &ast::Lit) -> String {
|
||||
// match lit.node {
|
||||
// ast::LitKind::Str(ref st, _) => st.to_string(),
|
||||
// ast::LitKind::ByteStr(ref data) => format!("{:?}", data),
|
||||
// ast::LitKind::Byte(b) => {
|
||||
// let mut res = String::from("b'");
|
||||
// for c in (b as char).escape_default() {
|
||||
// res.push(c);
|
||||
// }
|
||||
// res.push('\'');
|
||||
// res
|
||||
// },
|
||||
// ast::LitKind::Char(c) => format!("'{}'", c),
|
||||
// ast::LitKind::Int(i, _t) => i.to_string(),
|
||||
// ast::LitKind::Float(ref f, _t) => f.to_string(),
|
||||
// ast::LitKind::FloatUnsuffixed(ref f) => f.to_string(),
|
||||
// ast::LitKind::Bool(b) => b.to_string(),
|
||||
// }
|
||||
// }
|
||||
|
||||
fn name_from_pat(p: &hir::Pat) -> String {
|
||||
use rustc::hir::*;
|
||||
|
@ -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,13 @@ 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;
|
||||
/// Indicates if the attribute is a Meta-Item List.
|
||||
fn is_meta_item_list(&self) -> bool;
|
||||
|
||||
fn span(&self) -> Span;
|
||||
}
|
||||
|
||||
@ -108,8 +115,14 @@ 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 is_value_str(&self) -> bool { self.meta().is_value_str() }
|
||||
|
||||
fn is_meta_item_list(&self) -> bool { self.meta().is_meta_item_list() }
|
||||
|
||||
fn span(&self) -> Span { self.meta().span }
|
||||
}
|
||||
|
||||
@ -140,6 +153,18 @@ impl AttrMetaMethods for MetaItem {
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
fn is_word(&self) -> bool {
|
||||
match self.node {
|
||||
MetaItemKind::Word(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_value_str(&self) -> bool { self.value_str().is_some() }
|
||||
|
||||
fn is_meta_item_list(&self) -> bool { self.meta_item_list().is_some() }
|
||||
|
||||
fn span(&self) -> Span { self.span }
|
||||
}
|
||||
|
||||
@ -150,6 +175,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 +222,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 +267,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,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -1108,14 +1108,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;
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
//! The compiler code necessary to implement the `#[derive]` extensions.
|
||||
|
||||
use syntax::ast::{self, MetaItem, MetaItemKind};
|
||||
use syntax::ast::{MetaItem, self};
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::ext::base::{Annotatable, ExtCtxt, SyntaxEnv};
|
||||
use syntax::ext::base::{MultiDecorator, MultiItemDecorator, MultiModifier};
|
||||
@ -98,15 +98,14 @@ fn expand_derive(cx: &mut ExtCtxt,
|
||||
let mut eq_span = None;
|
||||
|
||||
for titem in traits.iter().rev() {
|
||||
let tname = match titem.node {
|
||||
MetaItemKind::Word(ref tname) => tname,
|
||||
_ => {
|
||||
cx.span_err(titem.span, "malformed `derive` entry");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let tname = if titem.is_word() {
|
||||
titem.name() }
|
||||
else {
|
||||
cx.span_err(titem.span, "malformed `derive` entry");
|
||||
continue;
|
||||
};
|
||||
|
||||
if !(is_builtin_trait(tname) || cx.ecfg.enable_custom_derive()) {
|
||||
if !(is_builtin_trait(&tname) || cx.ecfg.enable_custom_derive()) {
|
||||
feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic,
|
||||
"custom_derive",
|
||||
titem.span,
|
||||
|
Loading…
x
Reference in New Issue
Block a user