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 | 86 ++++++++++++++++++++++++---------------- 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, 146 insertions(+), 35 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 fcdc6f4e5..55318af6e 100644 --- a/serde_codegen/src/lib.rs +++ b/serde_codegen/src/lib.rs @@ -36,51 +36,67 @@ include!(concat!(env!("OUT_DIR"), "/lib.rs")); include!("lib.rs.in"); #[cfg(feature = "with-syntex")] -pub fn expand(src: S, dst: D) -> Result<(), syntex::Error> - where S: AsRef, - D: AsRef, -{ - let src = src.as_ref().to_owned(); - 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 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; } + _ => {} } - fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac { - fold::noop_fold_mac(mac, self) - } + Some(attr) } - fold::Folder::fold_crate(&mut StripAttributeFolder, krate) + fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac { + fold::noop_fold_mac(mac, self) + } } - let mut reg = syntex::Registry::new(); + 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 +} - reg.add_attr("feature(custom_derive)"); - reg.add_attr("feature(custom_attribute)"); +#[cfg(feature = "with-syntex")] +pub fn expand_str(src: &str) -> Result { + let src = src.to_owned(); - reg.add_decorator("derive_Serialize", ser::expand_derive_serialize); - reg.add_decorator("derive_Deserialize", de::expand_derive_deserialize); + let expand_thread = move || { + syntex_registry().expand_str("", "", &src) + }; - reg.add_post_expansion_pass(strip_attributes); + syntex::with_extra_stack(expand_thread) +} - reg.expand("", src, dst) +#[cfg(feature = "with-syntex")] +pub fn expand(src: S, dst: D) -> Result<(), syntex::Error> + where S: AsRef, + D: AsRef, +{ + let src = src.as_ref().to_owned(); + let dst = dst.as_ref().to_owned(); + + let expand_thread = move || { + 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 000000000..8702b2673 --- /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 000000000..d0cc0ef90 --- /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 000000000..ba3866cb5 --- /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 000000000..a2ed781bb --- /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 000000000..bc3e30d40 --- /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 d0cc0ef90..f4d592d63 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 bc3e30d40..8e4c43b64 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 8702b2673..50629ffc9 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 a2ed781bb..000000000 --- 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 ba3866cb5..000000000 --- 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 8e4c43b64..000000000 --- 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 50629ffc9..6384da209 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 f4d592d63..aa7bba608 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 000000000..ff8ac572c --- /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 6384da209..314080d14 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)]"