move AttributeTemplate to builtin_attrs

This commit is contained in:
Mazdak Farrokhzad 2019-11-30 00:56:46 +01:00
parent 048201fa7a
commit 8ad4d15f38
6 changed files with 34 additions and 33 deletions

View File

@ -39,10 +39,10 @@ use rustc_feature::Stability;
use syntax::tokenstream::{TokenTree, TokenStream};
use syntax::ast::{self, Expr};
use syntax::ptr::P;
use syntax::attr::{self, HasAttrs, AttributeTemplate};
use syntax::attr::{self, HasAttrs};
use syntax::source_map::Spanned;
use syntax::edition::Edition;
use syntax::feature_gate::{AttributeGate, AttributeType};
use syntax::feature_gate::{AttributeGate, AttributeTemplate, AttributeType};
use syntax::feature_gate::deprecated_attributes;
use syntax_pos::{BytePos, Span};
use syntax::symbol::{Symbol, kw, sym};

View File

@ -1,8 +1,9 @@
//! Meta-syntax validation logic of attributes for post-expansion.
use errors::{PResult, Applicability};
use syntax::ast::{self, Attribute, AttrKind, Ident, MetaItem};
use syntax::attr::{AttributeTemplate, mk_name_value_item_str};
use syntax::feature_gate::AttributeTemplate;
use syntax::ast::{self, Attribute, AttrKind, Ident, MetaItem, MetaItemKind};
use syntax::attr::mk_name_value_item_str;
use syntax::early_buffered_lints::BufferedEarlyLintId;
use syntax::feature_gate::BUILTIN_ATTRIBUTE_MAP;
use syntax::token;
@ -41,6 +42,16 @@ pub fn parse_meta<'a>(sess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Meta
})
}
/// Checks that the given meta-item is compatible with this `AttributeTemplate`.
fn is_attr_template_compatible(template: &AttributeTemplate, meta: &ast::MetaItemKind) -> bool {
match meta {
MetaItemKind::Word => template.word,
MetaItemKind::List(..) => template.list.is_some(),
MetaItemKind::NameValue(lit) if lit.kind.is_str() => template.name_value_str.is_some(),
MetaItemKind::NameValue(..) => false,
}
}
pub fn check_builtin_attribute(
sess: &ParseSess,
attr: &Attribute,
@ -57,7 +68,7 @@ pub fn check_builtin_attribute(
name == sym::test || name == sym::bench;
match parse_meta(sess, attr) {
Ok(meta) => if !should_skip(name) && !template.compatible(&meta.kind) {
Ok(meta) => if !should_skip(name) && !is_attr_template_compatible(&template, &meta.kind) {
let error_msg = format!("malformed `{}` attribute input", name);
let mut msg = "attribute must be of the form ".to_owned();
let mut suggestions = vec![];

View File

@ -25,31 +25,6 @@ enum AttrError {
UnsupportedLiteral(&'static str, /* is_bytestr */ bool),
}
/// A template that the attribute input must match.
/// Only top-level shape (`#[attr]` vs `#[attr(...)]` vs `#[attr = ...]`) is considered now.
#[derive(Clone, Copy)]
pub struct AttributeTemplate {
pub word: bool,
pub list: Option<&'static str>,
pub name_value_str: Option<&'static str>,
}
impl AttributeTemplate {
pub fn only_word() -> Self {
Self { word: true, list: None, name_value_str: None }
}
/// Checks that the given meta-item is compatible with this template.
pub fn compatible(&self, meta_item_kind: &ast::MetaItemKind) -> bool {
match meta_item_kind {
ast::MetaItemKind::Word => self.word,
ast::MetaItemKind::List(..) => self.list.is_some(),
ast::MetaItemKind::NameValue(lit) if lit.kind.is_str() => self.name_value_str.is_some(),
ast::MetaItemKind::NameValue(..) => false,
}
}
}
fn handle_errors(sess: &ParseSess, span: Span, error: AttrError) {
let diag = &sess.span_diagnostic;
match error {

View File

@ -8,7 +8,6 @@ use super::check::{EXPLAIN_ALLOW_INTERNAL_UNSAFE, EXPLAIN_ALLOW_INTERNAL_UNSTABL
use rustc_feature::{Features, Stability};
use crate::ast;
use crate::attr::AttributeTemplate;
use crate::sess::ParseSess;
use syntax_pos::symbol::{Symbol, sym};
@ -16,6 +15,7 @@ use syntax_pos::Span;
use rustc_data_structures::fx::FxHashMap;
use lazy_static::lazy_static;
type GateFn = fn(&Features) -> bool;
macro_rules! cfg_fn {
@ -108,6 +108,21 @@ impl AttributeGate {
}
}
/// A template that the attribute input must match.
/// Only top-level shape (`#[attr]` vs `#[attr(...)]` vs `#[attr = ...]`) is considered now.
#[derive(Clone, Copy)]
pub struct AttributeTemplate {
pub word: bool,
pub list: Option<&'static str>,
pub name_value_str: Option<&'static str>,
}
impl AttributeTemplate {
pub fn only_word() -> Self {
Self { word: true, list: None, name_value_str: None }
}
}
/// A convenience macro for constructing attribute templates.
/// E.g., `template!(Word, List: "description")` means that the attribute
/// supports forms `#[attr]` and `#[attr(description)]`.

View File

@ -101,7 +101,7 @@ pub mod feature_gate {
};
mod builtin_attrs;
pub use builtin_attrs::{
AttributeGate, AttributeType, GatedCfg,
AttributeGate, AttributeTemplate, AttributeType, GatedCfg,
BuiltinAttribute, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
deprecated_attributes, is_builtin_attr, is_builtin_attr_name,
};

View File

@ -1,7 +1,7 @@
use rustc_parse::validate_attr;
use syntax_pos::Symbol;
use syntax::ast::MetaItem;
use syntax::attr::AttributeTemplate;
use syntax::feature_gate::AttributeTemplate;
use syntax_expand::base::ExtCtxt;
pub fn check_builtin_macro_attribute(ecx: &ExtCtxt<'_>, meta_item: &MetaItem, name: Symbol) {