From d914fdf67b175b95168f163727578ac0b8d6883b Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 28 Aug 2016 22:19:17 -0700 Subject: [PATCH 1/7] Macros 1.1 --- serde_codegen/src/lib.rs | 90 +++++++++++++++++++++++----------------- serde_derive/Cargo.toml | 18 ++++++++ serde_derive/src/lib.rs | 20 +++++++++ tmp_test/Cargo.toml | 9 ++++ tmp_test/build.sh | 32 ++++++++++++++ tmp_test/src/main.rs | 16 +++++++ 6 files changed, 148 insertions(+), 37 deletions(-) create mode 100644 serde_derive/Cargo.toml create mode 100644 serde_derive/src/lib.rs create mode 100644 tmp_test/Cargo.toml create mode 100755 tmp_test/build.sh create mode 100644 tmp_test/src/main.rs diff --git a/serde_codegen/src/lib.rs b/serde_codegen/src/lib.rs index fcdc6f4e..55318af6 100644 --- a/serde_codegen/src/lib.rs +++ b/serde_codegen/src/lib.rs @@ -35,6 +35,58 @@ include!(concat!(env!("OUT_DIR"), "/lib.rs")); #[cfg(not(feature = "with-syntex"))] include!("lib.rs.in"); +#[cfg(feature = "with-syntex")] +fn syntex_registry() -> syntex::Registry { + use syntax::{ast, fold}; + + /// 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::MetaItemKind::List(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) + } + + let mut reg = syntex::Registry::new(); + + 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); + + reg +} + +#[cfg(feature = "with-syntex")] +pub fn expand_str(src: &str) -> Result { + let src = src.to_owned(); + + let expand_thread = move || { + syntex_registry().expand_str("", "", &src) + }; + + syntex::with_extra_stack(expand_thread) +} + #[cfg(feature = "with-syntex")] pub fn expand(src: S, dst: D) -> Result<(), syntex::Error> where S: AsRef, @@ -44,43 +96,7 @@ pub fn expand(src: S, dst: D) -> Result<(), syntex::Error> let dst = dst.as_ref().to_owned(); let expand_thread = move || { - use syntax::{ast, fold}; - - /// 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::MetaItemKind::List(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) - } - - let mut reg = syntex::Registry::new(); - - 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); - - reg.expand("", src, dst) + syntex_registry().expand("", src, dst) }; syntex::with_extra_stack(expand_thread) diff --git a/serde_derive/Cargo.toml b/serde_derive/Cargo.toml new file mode 100644 index 00000000..8702b267 --- /dev/null +++ b/serde_derive/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "serde_derive" +version = "0.8.4" +authors = ["Erick Tryzelaar "] +license = "MIT/Apache-2.0" +description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]" +homepage = "https://serde.rs" +repository = "https://github.com/serde-rs/serde" +documentation = "https://serde.rs/codegen.html" +keywords = ["serde", "serialization"] +include = ["Cargo.toml", "src/**/*.rs"] + +[lib] +name = "serde_derive" +rustc-macro = true + +[dependencies] +serde_codegen = { version = "=0.8.4", path = "../serde_codegen" } diff --git a/serde_derive/src/lib.rs b/serde_derive/src/lib.rs new file mode 100644 index 00000000..d0cc0ef9 --- /dev/null +++ b/serde_derive/src/lib.rs @@ -0,0 +1,20 @@ +#![feature(rustc_macro)] + +extern crate rustc_macro; +extern crate serde_codegen; + +use rustc_macro::TokenStream; + +#[rustc_macro_derive(Serialize)] +pub fn derive_serialize(input: TokenStream) -> TokenStream { + let item = format!("#[derive(Serialize)]\n{}", input); + let expanded = serde_codegen::expand_str(&item).unwrap(); + expanded.parse().unwrap() +} + +#[rustc_macro_derive(Deserialize)] +pub fn derive_deserialize(input: TokenStream) -> TokenStream { + let item = format!("#[derive(Deserialize)]\n{}", input); + let expanded = serde_codegen::expand_str(&item).unwrap(); + expanded.parse().unwrap() +} diff --git a/tmp_test/Cargo.toml b/tmp_test/Cargo.toml new file mode 100644 index 00000000..ba3866cb --- /dev/null +++ b/tmp_test/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "tmp-test" +version = "0.1.0" +authors = ["David Tolnay "] + +[dependencies] +serde = "0.8" +serde_derive = { path = "../serde_derive" } +serde_json = "0.8" diff --git a/tmp_test/build.sh b/tmp_test/build.sh new file mode 100755 index 00000000..a2ed781b --- /dev/null +++ b/tmp_test/build.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +set -xeuo pipefail + +DIR=$(cd "$(dirname "$0")" && pwd) + +export RUSTC=${RUSTC:-$HOME/.local/bin/rustc} + +cargo build || true + +"$RUSTC" \ + "$DIR"/../serde_derive/src/lib.rs \ + --crate-name serde_derive \ + --crate-type rustc-macro \ + -C prefer-dynamic \ + -g \ + --out-dir "$DIR"/target/debug/deps \ + --emit=dep-info,link \ + -L dependency="$DIR"/target/debug/deps \ + --extern serde_codegen="$DIR"/target/debug/deps/libserde_codegen.rlib + +"$RUSTC" \ + src/main.rs \ + --crate-name tmp_test \ + --crate-type bin \ + -g \ + --out-dir "$DIR"/target/debug \ + --emit=dep-info,link \ + -L dependency="$DIR"/target/debug/deps \ + --extern serde_json=$(echo "$DIR"/target/debug/deps/libserde_json-*.rlib) \ + --extern serde=$(echo "$DIR"/target/debug/deps/libserde-*.rlib) \ + --extern serde_derive="$DIR"/target/debug/deps/libserde_derive.so diff --git a/tmp_test/src/main.rs b/tmp_test/src/main.rs new file mode 100644 index 00000000..bc3e30d4 --- /dev/null +++ b/tmp_test/src/main.rs @@ -0,0 +1,16 @@ +#![feature(rustc_macro)] + +#[macro_use] +extern crate serde_derive; +extern crate serde_json; + +#[derive(Serialize)] +enum Macros { + #[serde(rename = "macros 1.1")] + OnePointOne, +} + +fn main() { + let s = Macros::OnePointOne; + println!("{}", serde_json::to_string(&s).unwrap()); +} From 3c45e5c7a5415bcfee9b21ea81c78b60a5165094 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 30 Aug 2016 23:55:08 -0700 Subject: [PATCH 2/7] Next iteration --- serde_derive/src/lib.rs | 2 +- tmp_test/src/main.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/serde_derive/src/lib.rs b/serde_derive/src/lib.rs index d0cc0ef9..f4d592d6 100644 --- a/serde_derive/src/lib.rs +++ b/serde_derive/src/lib.rs @@ -1,4 +1,4 @@ -#![feature(rustc_macro)] +#![feature(rustc_macro, rustc_macro_lib)] extern crate rustc_macro; extern crate serde_codegen; diff --git a/tmp_test/src/main.rs b/tmp_test/src/main.rs index bc3e30d4..8e4c43b6 100644 --- a/tmp_test/src/main.rs +++ b/tmp_test/src/main.rs @@ -4,7 +4,7 @@ extern crate serde_derive; extern crate serde_json; -#[derive(Serialize)] +#[derive(Serialize, Deserialize)] enum Macros { #[serde(rename = "macros 1.1")] OnePointOne, From 54cee86fd3b8e600b712c6dd3ee733a1c85ea90d Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 31 Aug 2016 20:14:44 -0700 Subject: [PATCH 3/7] Bump to 0.8.5 --- serde_derive/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serde_derive/Cargo.toml b/serde_derive/Cargo.toml index 8702b267..50629ffc 100644 --- a/serde_derive/Cargo.toml +++ b/serde_derive/Cargo.toml @@ -15,4 +15,4 @@ name = "serde_derive" rustc-macro = true [dependencies] -serde_codegen = { version = "=0.8.4", path = "../serde_codegen" } +serde_codegen = { version = "=0.8.5", path = "../serde_codegen" } From cdb0e6c899cd857ee069c73ed05be64b154e12a6 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 31 Aug 2016 21:05:40 -0700 Subject: [PATCH 4/7] Remove build script in favor of rust-lang/cargo#3064 --- tmp_test/build.sh | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100755 tmp_test/build.sh diff --git a/tmp_test/build.sh b/tmp_test/build.sh deleted file mode 100755 index a2ed781b..00000000 --- a/tmp_test/build.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash - -set -xeuo pipefail - -DIR=$(cd "$(dirname "$0")" && pwd) - -export RUSTC=${RUSTC:-$HOME/.local/bin/rustc} - -cargo build || true - -"$RUSTC" \ - "$DIR"/../serde_derive/src/lib.rs \ - --crate-name serde_derive \ - --crate-type rustc-macro \ - -C prefer-dynamic \ - -g \ - --out-dir "$DIR"/target/debug/deps \ - --emit=dep-info,link \ - -L dependency="$DIR"/target/debug/deps \ - --extern serde_codegen="$DIR"/target/debug/deps/libserde_codegen.rlib - -"$RUSTC" \ - src/main.rs \ - --crate-name tmp_test \ - --crate-type bin \ - -g \ - --out-dir "$DIR"/target/debug \ - --emit=dep-info,link \ - -L dependency="$DIR"/target/debug/deps \ - --extern serde_json=$(echo "$DIR"/target/debug/deps/libserde_json-*.rlib) \ - --extern serde=$(echo "$DIR"/target/debug/deps/libserde-*.rlib) \ - --extern serde_derive="$DIR"/target/debug/deps/libserde_derive.so From 87a402a7513892f432f5342b5816472b65cd7fce Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 1 Sep 2016 11:17:35 -0700 Subject: [PATCH 5/7] Remove rustc_macro test crate --- tmp_test/Cargo.toml | 9 --------- tmp_test/src/main.rs | 16 ---------------- 2 files changed, 25 deletions(-) delete mode 100644 tmp_test/Cargo.toml delete mode 100644 tmp_test/src/main.rs diff --git a/tmp_test/Cargo.toml b/tmp_test/Cargo.toml deleted file mode 100644 index ba3866cb..00000000 --- a/tmp_test/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "tmp-test" -version = "0.1.0" -authors = ["David Tolnay "] - -[dependencies] -serde = "0.8" -serde_derive = { path = "../serde_derive" } -serde_json = "0.8" diff --git a/tmp_test/src/main.rs b/tmp_test/src/main.rs deleted file mode 100644 index 8e4c43b6..00000000 --- a/tmp_test/src/main.rs +++ /dev/null @@ -1,16 +0,0 @@ -#![feature(rustc_macro)] - -#[macro_use] -extern crate serde_derive; -extern crate serde_json; - -#[derive(Serialize, Deserialize)] -enum Macros { - #[serde(rename = "macros 1.1")] - OnePointOne, -} - -fn main() { - let s = Macros::OnePointOne; - println!("{}", serde_json::to_string(&s).unwrap()); -} From 88d845c4d1ff8453a7c321b4efa1fb95b6aa0d99 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 1 Sep 2016 21:28:40 -0700 Subject: [PATCH 6/7] Include! test suite for serde_derive --- serde_derive/Cargo.toml | 5 +++++ serde_derive/src/lib.rs | 1 + serde_derive/tests/test.rs | 8 ++++++++ 3 files changed, 14 insertions(+) create mode 100644 serde_derive/tests/test.rs diff --git a/serde_derive/Cargo.toml b/serde_derive/Cargo.toml index 50629ffc..6384da20 100644 --- a/serde_derive/Cargo.toml +++ b/serde_derive/Cargo.toml @@ -16,3 +16,8 @@ rustc-macro = true [dependencies] serde_codegen = { version = "=0.8.5", path = "../serde_codegen" } + +[dev-dependencies] +fnv = "1.0" +serde = { version = "0.8.5", path = "../serde" } +serde_test = { version = "0.8.5", path = "../serde_test" } diff --git a/serde_derive/src/lib.rs b/serde_derive/src/lib.rs index f4d592d6..aa7bba60 100644 --- a/serde_derive/src/lib.rs +++ b/serde_derive/src/lib.rs @@ -1,4 +1,5 @@ #![feature(rustc_macro, rustc_macro_lib)] +#![cfg(not(test))] extern crate rustc_macro; extern crate serde_codegen; diff --git a/serde_derive/tests/test.rs b/serde_derive/tests/test.rs new file mode 100644 index 00000000..ff8ac572 --- /dev/null +++ b/serde_derive/tests/test.rs @@ -0,0 +1,8 @@ +#![feature(test, rustc_macro, rustc_attrs)] + +#[macro_use] +extern crate serde_derive; + +extern crate test; + +include!("../../testing/tests/test.rs.in"); From ac1128a64711f309cf02afae2a9156523083ddd7 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 1 Sep 2016 21:28:58 -0700 Subject: [PATCH 7/7] Update serde_derive to 0.8.5 --- serde_derive/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serde_derive/Cargo.toml b/serde_derive/Cargo.toml index 6384da20..314080d1 100644 --- a/serde_derive/Cargo.toml +++ b/serde_derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "serde_derive" -version = "0.8.4" +version = "0.8.5" authors = ["Erick Tryzelaar "] license = "MIT/Apache-2.0" description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"