From bac593573c47f7078078528b6199edcc37e8b1e2 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 20 Feb 2017 13:18:38 -0800 Subject: [PATCH] Drop aster dependency --- serde_derive/Cargo.toml | 2 +- serde_derive/src/bound.rs | 108 +++++++++++++++++++++++++++++--------- serde_derive/src/de.rs | 8 +-- serde_derive/src/lib.rs | 1 + serde_derive/src/ser.rs | 18 ++----- 5 files changed, 95 insertions(+), 42 deletions(-) diff --git a/serde_derive/Cargo.toml b/serde_derive/Cargo.toml index de74c259..16f7b53a 100644 --- a/serde_derive/Cargo.toml +++ b/serde_derive/Cargo.toml @@ -23,4 +23,4 @@ proc-macro = true [dependencies] quote = "0.3.8" serde_codegen_internals = { version = "=0.13.0", default-features = false, path = "../serde_codegen_internals" } -syn = { version = "0.11", features = ["aster", "visit"] } +syn = { version = "0.11", features = ["visit"] } diff --git a/serde_derive/src/bound.rs b/serde_derive/src/bound.rs index e386e2a3..1a7f1998 100644 --- a/serde_derive/src/bound.rs +++ b/serde_derive/src/bound.rs @@ -1,10 +1,36 @@ use std::collections::HashSet; -use syn::{self, aster, visit}; +use syn::{self, visit}; use internals::ast::Item; use internals::attr; +macro_rules! path { + ($first:ident $(:: $rest:ident)*) => { + syn::Path { + global: false, + segments: vec![ + stringify!($first).into(), + $( + stringify!($rest).into(), + )* + ], + } + }; + + (::$first:ident $(:: $rest:ident)*) => { + syn::Path { + global: true, + segments: vec![ + stringify!($first).into(), + $( + stringify!($rest).into(), + )* + ], + } + }; +} + // Remove the default from every type parameter because in the generated impls // they look like associated types: "error: associated type bindings are not // allowed here". @@ -21,9 +47,9 @@ pub fn without_defaults(generics: &syn::Generics) -> syn::Generics { pub fn with_where_predicates(generics: &syn::Generics, predicates: &[syn::WherePredicate]) -> syn::Generics { - aster::from_generics(generics.clone()) - .with_predicates(predicates.to_vec()) - .build() + let mut generics = generics.clone(); + generics.where_clause.predicates.extend_from_slice(predicates); + generics } pub fn with_where_predicates_from_fields(item: &Item, @@ -32,12 +58,14 @@ pub fn with_where_predicates_from_fields(item: &Item, -> syn::Generics where F: Fn(&attr::Field) -> Option<&[syn::WherePredicate]> { - aster::from_generics(generics.clone()) - .with_predicates(item.body - .all_fields() - .flat_map(|field| from_field(&field.attrs)) - .flat_map(|predicates| predicates.to_vec())) - .build() + let predicates = item.body + .all_fields() + .flat_map(|field| from_field(&field.attrs)) + .flat_map(|predicates| predicates.to_vec()); + + let mut generics = generics.clone(); + generics.where_clause.predicates.extend(predicates); + generics } // Puts the given bound on any generic type parameters that are used in fields @@ -104,18 +132,50 @@ pub fn with_bound(item: &Item, visit::walk_ty(&mut visitor, ty); } - aster::from_generics(generics.clone()) - .with_predicates(generics.ty_params - .iter() - .map(|ty_param| ty_param.ident.clone()) - .filter(|id| visitor.relevant_ty_params.contains(id)) - .map(|id| { - aster::where_predicate() - // the type parameter that is being bounded e.g. T - .bound().build(aster::ty().id(id)) - // the bound e.g. Serialize - .bound().trait_(bound.clone()).build() - .build() - })) - .build() + let new_predicates = generics.ty_params + .iter() + .map(|ty_param| ty_param.ident.clone()) + .filter(|id| visitor.relevant_ty_params.contains(id)) + .map(|id| { + syn::WherePredicate::BoundPredicate(syn::WhereBoundPredicate { + bound_lifetimes: Vec::new(), + // the type parameter that is being bounded e.g. T + bounded_ty: syn::Ty::Path(None, id.into()), + // the bound e.g. Serialize + bounds: vec![syn::TyParamBound::Trait( + syn::PolyTraitRef { + bound_lifetimes: Vec::new(), + trait_ref: bound.clone(), + }, + syn::TraitBoundModifier::None + )], + }) + }); + + let mut generics = generics.clone(); + generics.where_clause.predicates.extend(new_predicates); + generics } + +pub fn with_lifetime_bound(generics: &syn::Generics, + lifetime: &str) + -> syn::Generics { + let mut generics = generics.clone(); + + for lifetime_def in &mut generics.lifetimes { + lifetime_def.bounds.push(syn::Lifetime::new(lifetime)); + } + + for ty_param in &mut generics.ty_params { + ty_param.bounds.push(syn::TyParamBound::Region(syn::Lifetime::new(lifetime))); + } + + generics.lifetimes.push(syn::LifetimeDef { + attrs: Vec::new(), + lifetime: syn::Lifetime::new(lifetime), + bounds: Vec::new(), + }); + + generics +} + diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index db6befe9..a550f661 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -1,4 +1,4 @@ -use syn::{self, aster, Ident}; +use syn::{self, Ident}; use quote::{self, Tokens}; use bound; @@ -41,7 +41,7 @@ fn build_generics(item: &Item) -> syn::Generics { let generics = bound::without_defaults(item.generics); let generics = - bound::with_where_predicates_from_fields(item, &generics, |attrs| attrs.de_bound()); + bound::with_where_predicates_from_fields(item, &generics, attr::Field::de_bound); match item.attrs.de_bound() { Some(predicates) => bound::with_where_predicates(&generics, predicates), @@ -50,11 +50,11 @@ fn build_generics(item: &Item) -> syn::Generics { bound::with_bound(item, &generics, needs_deserialize_bound, - &aster::path().ids(&["_serde", "Deserialize"]).build()); + &path!(_serde::Deserialize)); bound::with_bound(item, &generics, requires_default, - &aster::path().global().ids(&["std", "default", "Default"]).build()) + &path!(_serde::export::Default)) } } } diff --git a/serde_derive/src/lib.rs b/serde_derive/src/lib.rs index 6e6a8c3a..421d7d84 100644 --- a/serde_derive/src/lib.rs +++ b/serde_derive/src/lib.rs @@ -13,6 +13,7 @@ extern crate serde_codegen_internals as internals; extern crate proc_macro; use proc_macro::TokenStream; +#[macro_use] mod bound; mod de; mod ser; diff --git a/serde_derive/src/ser.rs b/serde_derive/src/ser.rs index 4fe469cd..95708b2a 100644 --- a/serde_derive/src/ser.rs +++ b/serde_derive/src/ser.rs @@ -1,4 +1,4 @@ -use syn::{self, aster, Ident}; +use syn::{self, Ident}; use quote::Tokens; use bound; @@ -38,7 +38,7 @@ fn build_generics(item: &Item) -> syn::Generics { let generics = bound::without_defaults(item.generics); let generics = - bound::with_where_predicates_from_fields(item, &generics, |attrs| attrs.ser_bound()); + bound::with_where_predicates_from_fields(item, &generics, attr::Field::ser_bound); match item.attrs.ser_bound() { Some(predicates) => bound::with_where_predicates(&generics, predicates), @@ -46,7 +46,7 @@ fn build_generics(item: &Item) -> syn::Generics { bound::with_bound(item, &generics, needs_serialize_bound, - &aster::path().ids(&["_serde", "Serialize"]).build()) + &path!(_serde::Serialize)) } } } @@ -469,11 +469,7 @@ fn serialize_adjacently_tagged_variant(ident: &syn::Ident, let (_, ty_generics, where_clause) = generics.split_for_impl(); - let wrapper_generics = aster::from_generics(generics.clone()) - .add_lifetime_bound("'__a") - .lifetime_name("'__a") - .build(); - + let wrapper_generics = bound::with_lifetime_bound(generics, "'__a"); let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl(); quote!({ @@ -771,11 +767,7 @@ fn wrap_serialize_with(ident: &syn::Ident, -> Tokens { let (_, ty_generics, where_clause) = generics.split_for_impl(); - let wrapper_generics = aster::from_generics(generics.clone()) - .add_lifetime_bound("'__a") - .lifetime_name("'__a") - .build(); - + let wrapper_generics = bound::with_lifetime_bound(generics, "'__a"); let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl(); quote!({