mirror of
https://github.com/serde-rs/serde.git
synced 2025-10-04 08:15:44 +00:00
Ask proc_macro_derive to ignore serde attributes
This commit is contained in:
parent
133d117bf4
commit
a16f07858b
@ -22,7 +22,6 @@ with-syn = []
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clippy = { version = "^0.*", optional = true }
|
clippy = { version = "^0.*", optional = true }
|
||||||
post-expansion = "0.2"
|
|
||||||
quote = "0.3"
|
quote = "0.3"
|
||||||
serde_codegen_internals = { version = "=0.10.0", default-features = false, path = "../serde_codegen_internals" }
|
serde_codegen_internals = { version = "=0.10.0", default-features = false, path = "../serde_codegen_internals" }
|
||||||
syn = { version = "0.10", features = ["aster", "visit"] }
|
syn = { version = "0.10", features = ["aster", "visit"] }
|
||||||
|
@ -27,9 +27,6 @@ extern crate syn;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate quote;
|
extern crate quote;
|
||||||
|
|
||||||
#[cfg(feature = "with-syn")]
|
|
||||||
extern crate post_expansion;
|
|
||||||
|
|
||||||
#[cfg(feature = "with-syntex")]
|
#[cfg(feature = "with-syntex")]
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
@ -73,8 +70,8 @@ fn syntex_registry() -> syntex::Registry {
|
|||||||
reg.add_attr("feature(custom_derive)");
|
reg.add_attr("feature(custom_derive)");
|
||||||
reg.add_attr("feature(custom_attribute)");
|
reg.add_attr("feature(custom_attribute)");
|
||||||
|
|
||||||
reg.add_decorator("derive_Serialize", expand_derive_serialize);
|
reg.add_decorator("derive_Serialize", shim::expand_derive_serialize);
|
||||||
reg.add_decorator("derive_Deserialize", expand_derive_deserialize);
|
reg.add_decorator("derive_Deserialize", shim::expand_derive_deserialize);
|
||||||
|
|
||||||
reg.add_post_expansion_pass(strip_attributes);
|
reg.add_post_expansion_pass(strip_attributes);
|
||||||
|
|
||||||
@ -112,19 +109,19 @@ pub fn register(reg: &mut rustc_plugin::Registry) {
|
|||||||
reg.register_syntax_extension(
|
reg.register_syntax_extension(
|
||||||
syntax::parse::token::intern("derive_Serialize"),
|
syntax::parse::token::intern("derive_Serialize"),
|
||||||
syntax::ext::base::MultiDecorator(
|
syntax::ext::base::MultiDecorator(
|
||||||
Box::new(expand_derive_serialize)));
|
Box::new(shim::expand_derive_serialize)));
|
||||||
|
|
||||||
reg.register_syntax_extension(
|
reg.register_syntax_extension(
|
||||||
syntax::parse::token::intern("derive_Deserialize"),
|
syntax::parse::token::intern("derive_Deserialize"),
|
||||||
syntax::ext::base::MultiDecorator(
|
syntax::ext::base::MultiDecorator(
|
||||||
Box::new(expand_derive_deserialize)));
|
Box::new(shim::expand_derive_deserialize)));
|
||||||
|
|
||||||
reg.register_attribute("serde".to_owned(), AttributeType::Normal);
|
reg.register_attribute("serde".to_owned(), AttributeType::Normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! shim {
|
macro_rules! shim {
|
||||||
($name:ident $pkg:ident :: $func:ident) => {
|
($name:ident $pkg:ident :: $func:ident) => {
|
||||||
fn $func(
|
pub fn $func(
|
||||||
cx: &mut ::syntax::ext::base::ExtCtxt,
|
cx: &mut ::syntax::ext::base::ExtCtxt,
|
||||||
span: ::syntax::codemap::Span,
|
span: ::syntax::codemap::Span,
|
||||||
meta_item: &::syntax::ast::MetaItem,
|
meta_item: &::syntax::ast::MetaItem,
|
||||||
@ -160,6 +157,7 @@ macro_rules! shim {
|
|||||||
use syntax::print::pprust;
|
use syntax::print::pprust;
|
||||||
let s = pprust::item_to_string(item);
|
let s = pprust::item_to_string(item);
|
||||||
|
|
||||||
|
use {syn, $pkg};
|
||||||
let syn_item = syn::parse_macro_input(&s).unwrap();
|
let syn_item = syn::parse_macro_input(&s).unwrap();
|
||||||
let expanded = match $pkg::$func(&syn_item) {
|
let expanded = match $pkg::$func(&syn_item) {
|
||||||
Ok(expanded) => expanded.to_string(),
|
Ok(expanded) => expanded.to_string(),
|
||||||
@ -178,72 +176,19 @@ macro_rules! shim {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
shim!(Serialize ser::expand_derive_serialize);
|
mod shim {
|
||||||
shim!(Deserialize de::expand_derive_deserialize);
|
shim!(Serialize ser::expand_derive_serialize);
|
||||||
|
shim!(Deserialize de::expand_derive_deserialize);
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "with-syn")]
|
#[cfg(feature = "with-syn")]
|
||||||
pub fn expand_single_item(item: &str) -> Result<String, String> {
|
pub fn expand_derive_serialize(item: &str) -> Result<String, String> {
|
||||||
let syn_item = syn::parse_macro_input(item).unwrap();
|
let syn_item = syn::parse_macro_input(item).unwrap();
|
||||||
let (ser, de, syn_item) = strip_serde_derives(syn_item);
|
ser::expand_derive_serialize(&syn_item).map(|derive| derive.to_string())
|
||||||
let expanded_ser = if ser {
|
}
|
||||||
Some(try!(ser::expand_derive_serialize(&syn_item)))
|
|
||||||
} else {
|
#[cfg(feature = "with-syn")]
|
||||||
None
|
pub fn expand_derive_deserialize(item: &str) -> Result<String, String> {
|
||||||
};
|
let syn_item = syn::parse_macro_input(item).unwrap();
|
||||||
let expanded_de = if de {
|
de::expand_derive_deserialize(&syn_item).map(|derive| derive.to_string())
|
||||||
Some(try!(de::expand_derive_deserialize(&syn_item)))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
let syn_item = post_expansion::strip_attrs_later(syn_item, &["serde"], "serde");
|
|
||||||
return Ok(quote!(#expanded_ser #expanded_de #syn_item).to_string());
|
|
||||||
|
|
||||||
fn strip_serde_derives(item: syn::MacroInput) -> (bool, bool, syn::MacroInput) {
|
|
||||||
let mut ser = false;
|
|
||||||
let mut de = false;
|
|
||||||
let item = syn::MacroInput {
|
|
||||||
attrs: item.attrs.into_iter().flat_map(|attr| {
|
|
||||||
if attr.is_sugared_doc || attr.style != syn::AttrStyle::Outer {
|
|
||||||
return Some(attr);
|
|
||||||
}
|
|
||||||
let (name, nested) = match attr.value {
|
|
||||||
syn::MetaItem::List(name, nested) => (name, nested),
|
|
||||||
_ => return Some(attr)
|
|
||||||
};
|
|
||||||
if name != "derive" {
|
|
||||||
return Some(syn::Attribute {
|
|
||||||
style: syn::AttrStyle::Outer,
|
|
||||||
value: syn::MetaItem::List(name, nested),
|
|
||||||
is_sugared_doc: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
let rest: Vec<_> = nested.into_iter().filter(|nested| {
|
|
||||||
use syn::MetaItem::Word;
|
|
||||||
use syn::NestedMetaItem::MetaItem;
|
|
||||||
match *nested {
|
|
||||||
MetaItem(Word(ref word)) if word == "Serialize" => {
|
|
||||||
ser = true;
|
|
||||||
false
|
|
||||||
}
|
|
||||||
MetaItem(Word(ref word)) if word == "Deserialize" => {
|
|
||||||
de = true;
|
|
||||||
false
|
|
||||||
}
|
|
||||||
_ => true,
|
|
||||||
}
|
|
||||||
}).collect();
|
|
||||||
if rest.is_empty() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(syn::Attribute {
|
|
||||||
style: syn::AttrStyle::Outer,
|
|
||||||
value: syn::MetaItem::List(name, rest),
|
|
||||||
is_sugared_doc: false,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}).collect(),
|
|
||||||
..item
|
|
||||||
};
|
|
||||||
(ser, de, item)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -14,9 +14,6 @@ include = ["Cargo.toml", "src/**/*.rs"]
|
|||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
proc-macro = true
|
proc-macro = true
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
post-expansion = "0.2.0"
|
|
||||||
|
|
||||||
[dependencies.serde_codegen]
|
[dependencies.serde_codegen]
|
||||||
version = "=0.8.17"
|
version = "=0.8.17"
|
||||||
path = "../serde_codegen"
|
path = "../serde_codegen"
|
||||||
|
@ -4,27 +4,20 @@
|
|||||||
extern crate proc_macro;
|
extern crate proc_macro;
|
||||||
extern crate serde_codegen;
|
extern crate serde_codegen;
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate post_expansion;
|
|
||||||
|
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
|
|
||||||
#[proc_macro_derive(Serialize)]
|
#[proc_macro_derive(Serialize, attributes(serde))]
|
||||||
pub fn derive_serialize(input: TokenStream) -> TokenStream {
|
pub fn derive_serialize(input: TokenStream) -> TokenStream {
|
||||||
let item = format!("#[derive(Serialize)]\n{}", input);
|
match serde_codegen::expand_derive_serialize(&input.to_string()) {
|
||||||
match serde_codegen::expand_single_item(&item) {
|
|
||||||
Ok(expanded) => expanded.parse().unwrap(),
|
Ok(expanded) => expanded.parse().unwrap(),
|
||||||
Err(msg) => panic!(msg),
|
Err(msg) => panic!(msg),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[proc_macro_derive(Deserialize)]
|
#[proc_macro_derive(Deserialize, attributes(serde))]
|
||||||
pub fn derive_deserialize(input: TokenStream) -> TokenStream {
|
pub fn derive_deserialize(input: TokenStream) -> TokenStream {
|
||||||
let item = format!("#[derive(Deserialize)]\n{}", input);
|
match serde_codegen::expand_derive_deserialize(&input.to_string()) {
|
||||||
match serde_codegen::expand_single_item(&item) {
|
|
||||||
Ok(expanded) => expanded.parse().unwrap(),
|
Ok(expanded) => expanded.parse().unwrap(),
|
||||||
Err(msg) => panic!(msg),
|
Err(msg) => panic!(msg),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
register_post_expansion!(PostExpansion_serde);
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user