From ff8c3b3d514ffc33a5de1412cbd8076077836d4f Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Sun, 17 May 2015 23:26:04 -0700 Subject: [PATCH] Initial support for syntex --- serde_codegen/Cargo.toml | 18 ++++++++-- serde_codegen/build.rs | 28 ++++++++++++++++ serde_codegen/src/field.rs | 2 +- serde_codegen/src/lib.rs | 63 +++++++++++++++++++++++++++++++---- serde_codegen/src/lib.rs.in | 4 +++ serde_macros/Cargo.toml | 7 +++- serde_macros/benches/bench.rs | 9 +++++ serde_macros/tests/test.rs | 7 ++++ serde_tests/Cargo.toml | 10 ++++-- serde_tests/benches/bench.rs | 9 +++-- serde_tests/build.rs | 22 ++++++++++++ serde_tests/tests/test.rs | 5 ++- 12 files changed, 161 insertions(+), 23 deletions(-) create mode 100644 serde_codegen/build.rs create mode 100644 serde_codegen/src/lib.rs.in create mode 100644 serde_macros/benches/bench.rs create mode 100644 serde_macros/tests/test.rs create mode 100644 serde_tests/build.rs diff --git a/serde_codegen/Cargo.toml b/serde_codegen/Cargo.toml index 45a39bfc..7ab3e212 100644 --- a/serde_codegen/Cargo.toml +++ b/serde_codegen/Cargo.toml @@ -5,8 +5,20 @@ authors = ["Erick Tryzelaar "] license = "MIT/Apache-2.0" description = "Macros to auto-generate implementations for the serde framework" repository = "https://github.com/erickt/rust-serde" +build = "build.rs" + +[features] +default = ["with-syntex"] +nightly = ["quasi_macros"] +with-syntex = ["quasi/with-syntex", "quasi_codegen/with-syntex", "syntex", "syntex_syntax"] + +[build-dependencies] +quasi_codegen = { verision = "*", optional = true } +syntex = { version = "*", optional = true } [dependencies] -aster = "*" -quasi = "*" -quasi_macros = "*" +aster = { version = "*", default-features = false } +quasi = { verision = "*", default-features = false } +quasi_macros = { version = "*", optional = true } +syntex = { version = "*", optional = true } +syntex_syntax = { version = "*", optional = true } diff --git a/serde_codegen/build.rs b/serde_codegen/build.rs new file mode 100644 index 00000000..080e314e --- /dev/null +++ b/serde_codegen/build.rs @@ -0,0 +1,28 @@ +#[cfg(feature = "with-syntex")] +mod inner { + extern crate syntex; + extern crate quasi_codegen; + + use std::env; + use std::path::Path; + + pub fn main() { + let out_dir = env::var_os("OUT_DIR").unwrap(); + let mut registry = syntex::Registry::new(); + quasi_codegen::register(&mut registry); + + let src = Path::new("src/lib.rs.in"); + let dst = Path::new(&out_dir).join("lib.rs"); + + registry.expand("", &src, &dst).unwrap(); + } +} + +#[cfg(not(feature = "with-syntex"))] +mod inner { + pub fn main() {} +} + +fn main() { + inner::main(); +} diff --git a/serde_codegen/src/field.rs b/serde_codegen/src/field.rs index 5a666cfc..676e6cb7 100644 --- a/serde_codegen/src/field.rs +++ b/serde_codegen/src/field.rs @@ -7,7 +7,7 @@ use syntax::attr; use syntax::ext::base::ExtCtxt; use syntax::ptr::P; -use super::attr::FieldAttrs; +use attr::FieldAttrs; enum Rename<'a> { None, diff --git a/serde_codegen/src/lib.rs b/serde_codegen/src/lib.rs index 8b6db0b2..0deaecb5 100644 --- a/serde_codegen/src/lib.rs +++ b/serde_codegen/src/lib.rs @@ -1,16 +1,65 @@ -#![feature(custom_derive, plugin, rustc_private, unboxed_closures)] -#![plugin(quasi_macros)] +#![cfg_attr(not(feature = "with-syntex"), feature(rustc_private, plugin))] +#![cfg_attr(not(feature = "with-syntex"), plugin(quasi_macros))] extern crate aster; extern crate quasi; -extern crate rustc; + +#[cfg(feature = "with-syntex")] +extern crate syntex; + +#[cfg(feature = "with-syntex")] +extern crate syntex_syntax as syntax; + +#[cfg(not(feature = "with-syntex"))] extern crate syntax; -mod attr; -mod de; -mod field; -mod ser; +#[cfg(not(feature = "with-syntex"))] +extern crate rustc; +#[cfg(feature = "with-syntex")] +include!(concat!(env!("OUT_DIR"), "/lib.rs")); + +#[cfg(not(feature = "with-syntex"))] +include!("lib.rs.in"); + +#[cfg(feature = "with-syntex")] +pub fn register(reg: &mut syntex::Registry) { + use syntax::{ast, fold}; + + reg.add_attr("feature(custom_derive)"); + reg.add_attr("feature(custom_attribute)"); + + reg.add_decorator("derive_Serialize", ser::expand_derive_serialize); + reg.add_decorator("derive_Deserialize", de::expand_derive_deserialize); + + reg.add_post_expansion_pass(strip_attributes); + + /// Strip the serde attributes from the crate. + #[cfg(feature = "with-syntex")] + fn strip_attributes(krate: ast::Crate) -> ast::Crate { + /// Helper folder that strips the serde attributes after the extensions have been expanded. + struct StripAttributeFolder; + + impl fold::Folder for StripAttributeFolder { + fn fold_attribute(&mut self, attr: ast::Attribute) -> Option { + match attr.node.value.node { + ast::MetaList(ref n, _) if n == &"serde" => { return None; } + _ => {} + } + + Some(attr) + } + + fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac { + fold::noop_fold_mac(mac, self) + } + } + + fold::Folder::fold_crate(&mut StripAttributeFolder, krate) + } +} + +#[cfg(not(feature = "with-syntex"))] pub fn register(reg: &mut rustc::plugin::Registry) { reg.register_syntax_extension( syntax::parse::token::intern("derive_Serialize"), diff --git a/serde_codegen/src/lib.rs.in b/serde_codegen/src/lib.rs.in new file mode 100644 index 00000000..18f155ec --- /dev/null +++ b/serde_codegen/src/lib.rs.in @@ -0,0 +1,4 @@ +mod attr; +mod de; +mod field; +mod ser; diff --git a/serde_macros/Cargo.toml b/serde_macros/Cargo.toml index bb8dc9f6..0f392525 100644 --- a/serde_macros/Cargo.toml +++ b/serde_macros/Cargo.toml @@ -11,4 +11,9 @@ name = "serde_macros" plugin = true [dependencies] -serde_codegen = { version = "*", path = "../serde_codegen" } +serde_codegen = { version = "*", path = "../serde_codegen", default-features = false, features = ["nightly"] } + +[dev-dependencies] +num = "*" +rustc-serialize = "*" +serde = { version = "*", path = "../serde" } diff --git a/serde_macros/benches/bench.rs b/serde_macros/benches/bench.rs new file mode 100644 index 00000000..519c189f --- /dev/null +++ b/serde_macros/benches/bench.rs @@ -0,0 +1,9 @@ +#![feature(custom_attribute, custom_derive, plugin, test)] +#![plugin(serde_macros)] + +extern crate num; +extern crate rustc_serialize; +extern crate serde; +extern crate test; + +include!("../../serde_tests/benches/bench.rs.in"); diff --git a/serde_macros/tests/test.rs b/serde_macros/tests/test.rs new file mode 100644 index 00000000..fd353e1b --- /dev/null +++ b/serde_macros/tests/test.rs @@ -0,0 +1,7 @@ +#![feature(test, custom_attribute, custom_derive, plugin)] +#![plugin(serde_macros)] + +extern crate serde; +extern crate test; + +include!("../../serde_tests/tests/test.rs.in"); diff --git a/serde_tests/Cargo.toml b/serde_tests/Cargo.toml index b2d430e2..60922ecf 100644 --- a/serde_tests/Cargo.toml +++ b/serde_tests/Cargo.toml @@ -8,14 +8,18 @@ repository = "https://github.com/serde-rs/serde" documentation = "http://serde-rs.github.io/serde/serde" readme = "README.md" keywords = ["serialization"] +build = "build.rs" -[dependencies] -num = "*" +[build-dependencies] +syntex = { version = "*", optional = true } +syntex_syntax = { version = "*" } +serde_codegen = { version = "*", path = "../serde_codegen", features = ["with-syntex"] } [dev-dependencies] +num = "*" rustc-serialize = "*" serde = { version = "*", path = "../serde" } -serde_macros = { version = "*", path = "../serde_macros" } +syntex = "*" [[test]] name = "test" diff --git a/serde_tests/benches/bench.rs b/serde_tests/benches/bench.rs index 02bf6e9f..181c4c61 100644 --- a/serde_tests/benches/bench.rs +++ b/serde_tests/benches/bench.rs @@ -1,9 +1,8 @@ -#![feature(custom_attribute, custom_derive, plugin, test)] -#![plugin(serde_macros)] +#![feature(test)] +extern crate num; +extern crate rustc_serialize; extern crate serde; extern crate test; -mod syntax { - include!("bench.rs.in"); -} +include!(concat!(env!("OUT_DIR"), "/bench.rs")); diff --git a/serde_tests/build.rs b/serde_tests/build.rs new file mode 100644 index 00000000..81f5c41f --- /dev/null +++ b/serde_tests/build.rs @@ -0,0 +1,22 @@ +extern crate syntex; +extern crate serde_codegen; + +use std::env; +use std::path::Path; + +fn main() { + let out_dir = env::var_os("OUT_DIR").unwrap(); + + for &(src, dst) in &[ + ("tests/test.rs.in", "test.rs"), + ("benches/bench.rs.in", "bench.rs"), + ] { + let src = Path::new(src); + let dst = Path::new(&out_dir).join(dst); + + let mut registry = syntex::Registry::new(); + + serde_codegen::register(&mut registry); + registry.expand("", &src, &dst).unwrap(); + } +} diff --git a/serde_tests/tests/test.rs b/serde_tests/tests/test.rs index b3cb3492..f086bc96 100644 --- a/serde_tests/tests/test.rs +++ b/serde_tests/tests/test.rs @@ -1,7 +1,6 @@ -#![feature(custom_attribute, custom_derive, plugin, test)] -#![plugin(serde_macros)] +#![feature(test)] extern crate serde; extern crate test; -include!("test.rs.in"); +include!(concat!(env!("OUT_DIR"), "/test.rs"));