diff --git a/serde_codegen/Cargo.toml b/serde_codegen/Cargo.toml index 57f830dd..60d73519 100644 --- a/serde_codegen/Cargo.toml +++ b/serde_codegen/Cargo.toml @@ -22,7 +22,6 @@ with-syn = [] [dependencies] clippy = { version = "^0.*", optional = true } -post-expansion = "0.2" quote = "0.3" serde_codegen_internals = { version = "=0.10.0", default-features = false, path = "../serde_codegen_internals" } syn = { version = "0.10", features = ["aster", "visit"] } diff --git a/serde_codegen/src/lib.rs b/serde_codegen/src/lib.rs index b9920af0..ba18584b 100644 --- a/serde_codegen/src/lib.rs +++ b/serde_codegen/src/lib.rs @@ -27,9 +27,6 @@ extern crate syn; #[macro_use] extern crate quote; -#[cfg(feature = "with-syn")] -extern crate post_expansion; - #[cfg(feature = "with-syntex")] use std::path::Path; @@ -73,8 +70,8 @@ fn syntex_registry() -> syntex::Registry { reg.add_attr("feature(custom_derive)"); reg.add_attr("feature(custom_attribute)"); - reg.add_decorator("derive_Serialize", expand_derive_serialize); - reg.add_decorator("derive_Deserialize", expand_derive_deserialize); + reg.add_decorator("derive_Serialize", shim::expand_derive_serialize); + reg.add_decorator("derive_Deserialize", shim::expand_derive_deserialize); reg.add_post_expansion_pass(strip_attributes); @@ -112,19 +109,19 @@ pub fn register(reg: &mut rustc_plugin::Registry) { reg.register_syntax_extension( syntax::parse::token::intern("derive_Serialize"), syntax::ext::base::MultiDecorator( - Box::new(expand_derive_serialize))); + Box::new(shim::expand_derive_serialize))); reg.register_syntax_extension( syntax::parse::token::intern("derive_Deserialize"), syntax::ext::base::MultiDecorator( - Box::new(expand_derive_deserialize))); + Box::new(shim::expand_derive_deserialize))); reg.register_attribute("serde".to_owned(), AttributeType::Normal); } macro_rules! shim { ($name:ident $pkg:ident :: $func:ident) => { - fn $func( + pub fn $func( cx: &mut ::syntax::ext::base::ExtCtxt, span: ::syntax::codemap::Span, meta_item: &::syntax::ast::MetaItem, @@ -160,6 +157,7 @@ macro_rules! shim { use syntax::print::pprust; let s = pprust::item_to_string(item); + use {syn, $pkg}; let syn_item = syn::parse_macro_input(&s).unwrap(); let expanded = match $pkg::$func(&syn_item) { Ok(expanded) => expanded.to_string(), @@ -178,72 +176,23 @@ macro_rules! shim { }; } -shim!(Serialize ser::expand_derive_serialize); -shim!(Deserialize de::expand_derive_deserialize); +mod shim { + shim!(Serialize ser::expand_derive_serialize); + shim!(Deserialize de::expand_derive_deserialize); +} #[cfg(feature = "with-syn")] -pub fn expand_single_item(item: &str) -> Result { +#[doc(hidden)] +/// Not public API. Use the serde_derive crate. +pub fn expand_derive_serialize(item: &str) -> Result { let syn_item = syn::parse_macro_input(item).unwrap(); - let (ser, de, syn_item) = strip_serde_derives(syn_item); - let expanded_ser = if ser { - Some(try!(ser::expand_derive_serialize(&syn_item))) - } else { - None - }; - let expanded_de = if de { - 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) - } + ser::expand_derive_serialize(&syn_item).map(|derive| derive.to_string()) +} + +#[cfg(feature = "with-syn")] +#[doc(hidden)] +/// Not public API. Use the serde_derive crate. +pub fn expand_derive_deserialize(item: &str) -> Result { + let syn_item = syn::parse_macro_input(item).unwrap(); + de::expand_derive_deserialize(&syn_item).map(|derive| derive.to_string()) } diff --git a/serde_derive/Cargo.toml b/serde_derive/Cargo.toml index 59157673..3d3f4ae7 100644 --- a/serde_derive/Cargo.toml +++ b/serde_derive/Cargo.toml @@ -14,9 +14,6 @@ include = ["Cargo.toml", "src/**/*.rs"] name = "serde_derive" proc-macro = true -[dependencies] -post-expansion = "0.2.0" - [dependencies.serde_codegen] version = "=0.8.17" path = "../serde_codegen" diff --git a/serde_derive/src/lib.rs b/serde_derive/src/lib.rs index f631d6dd..cacc56e1 100644 --- a/serde_derive/src/lib.rs +++ b/serde_derive/src/lib.rs @@ -4,27 +4,20 @@ extern crate proc_macro; extern crate serde_codegen; -#[macro_use] -extern crate post_expansion; - use proc_macro::TokenStream; -#[proc_macro_derive(Serialize)] +#[proc_macro_derive(Serialize, attributes(serde))] pub fn derive_serialize(input: TokenStream) -> TokenStream { - let item = format!("#[derive(Serialize)]\n{}", input); - match serde_codegen::expand_single_item(&item) { + match serde_codegen::expand_derive_serialize(&input.to_string()) { Ok(expanded) => expanded.parse().unwrap(), Err(msg) => panic!(msg), } } -#[proc_macro_derive(Deserialize)] +#[proc_macro_derive(Deserialize, attributes(serde))] pub fn derive_deserialize(input: TokenStream) -> TokenStream { - let item = format!("#[derive(Deserialize)]\n{}", input); - match serde_codegen::expand_single_item(&item) { + match serde_codegen::expand_derive_deserialize(&input.to_string()) { Ok(expanded) => expanded.parse().unwrap(), Err(msg) => panic!(msg), } } - -register_post_expansion!(PostExpansion_serde);