mirror of
https://github.com/clap-rs/clap
synced 2024-12-14 06:42:33 +00:00
fix(derive): Report deprecations for structopt attributes
This is more of a test bed for adding new attributes and deprecating clap ones.
This commit is contained in:
parent
7b0c76de31
commit
0ae119fda9
3 changed files with 75 additions and 4 deletions
|
@ -5,6 +5,7 @@ use proc_macro_error::abort;
|
|||
use proc_macro_error::ResultExt;
|
||||
use quote::quote;
|
||||
use quote::ToTokens;
|
||||
use syn::spanned::Spanned;
|
||||
use syn::{
|
||||
parenthesized,
|
||||
parse::{Parse, ParseStream},
|
||||
|
@ -12,8 +13,11 @@ use syn::{
|
|||
Attribute, Expr, Ident, LitStr, Token,
|
||||
};
|
||||
|
||||
use crate::utils::Sp;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ClapAttr {
|
||||
pub kind: Sp<AttrKind>,
|
||||
pub name: Ident,
|
||||
pub magic: Option<MagicAttrName>,
|
||||
pub value: Option<AttrValue>,
|
||||
|
@ -23,10 +27,24 @@ impl ClapAttr {
|
|||
pub fn parse_all(all_attrs: &[Attribute]) -> Vec<Self> {
|
||||
all_attrs
|
||||
.iter()
|
||||
.filter(|attr| attr.path.is_ident("clap") || attr.path.is_ident("structopt"))
|
||||
.flat_map(|attr| {
|
||||
.filter_map(|attr| {
|
||||
let kind = if attr.path.is_ident("clap") {
|
||||
Some(Sp::new(AttrKind::Clap, attr.path.span()))
|
||||
} else if attr.path.is_ident("structopt") {
|
||||
Some(Sp::new(AttrKind::StructOpt, attr.path.span()))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
kind.map(|k| (k, attr))
|
||||
})
|
||||
.flat_map(|(k, attr)| {
|
||||
attr.parse_args_with(Punctuated::<ClapAttr, Token![,]>::parse_terminated)
|
||||
.unwrap_or_abort()
|
||||
.into_iter()
|
||||
.map(move |mut a| {
|
||||
a.kind = k;
|
||||
a
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
@ -113,7 +131,12 @@ impl Parse for ClapAttr {
|
|||
None
|
||||
};
|
||||
|
||||
Ok(Self { name, magic, value })
|
||||
Ok(Self {
|
||||
kind: Sp::new(AttrKind::Clap, name.span()),
|
||||
name,
|
||||
magic,
|
||||
value,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -166,3 +189,18 @@ impl ToTokens for AttrValue {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub enum AttrKind {
|
||||
Clap,
|
||||
StructOpt,
|
||||
}
|
||||
|
||||
impl AttrKind {
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Clap => "clap",
|
||||
Self::StructOpt => "structopt",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -494,6 +494,18 @@ impl Item {
|
|||
}
|
||||
|
||||
for attr in &parsed {
|
||||
match attr.kind.get() {
|
||||
AttrKind::Clap => {}
|
||||
AttrKind::StructOpt => {
|
||||
self.deprecations.push(Deprecation::attribute(
|
||||
"4.0.0",
|
||||
*attr.kind.get(),
|
||||
AttrKind::Clap,
|
||||
attr.kind.span(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(AttrValue::Call(tokens)) = &attr.value {
|
||||
// Force raw mode with method call syntax
|
||||
self.push_method(attr.name.clone(), quote!(#(#tokens),*));
|
||||
|
@ -541,7 +553,9 @@ impl Item {
|
|||
);
|
||||
}
|
||||
|
||||
Some(MagicAttrName::ValueEnum) if attr.value.is_none() => self.is_enum = true,
|
||||
Some(MagicAttrName::ValueEnum) if attr.value.is_none() => {
|
||||
self.is_enum = true
|
||||
}
|
||||
|
||||
Some(MagicAttrName::VerbatimDocComment) if attr.value.is_none() => {
|
||||
self.verbatim_doc_comment = true
|
||||
|
@ -1182,6 +1196,21 @@ pub struct Deprecation {
|
|||
pub description: String,
|
||||
}
|
||||
|
||||
impl Deprecation {
|
||||
fn attribute(version: &'static str, old: AttrKind, new: AttrKind, span: Span) -> Self {
|
||||
Self {
|
||||
span,
|
||||
id: "old_attribute",
|
||||
version,
|
||||
description: format!(
|
||||
"Attribute `#[{}(...)]` has been deprecated in favor of `#[{}(...)]`",
|
||||
old.as_str(),
|
||||
new.as_str()
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for Deprecation {
|
||||
fn to_tokens(&self, ts: &mut proc_macro2::TokenStream) {
|
||||
let tokens = if cfg!(feature = "deprecated") {
|
||||
|
|
|
@ -23,6 +23,10 @@ impl<T> Sp<T> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get(&self) -> &T {
|
||||
&self.val
|
||||
}
|
||||
|
||||
pub fn span(&self) -> Span {
|
||||
self.span
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue