Drop aster dependency

This commit is contained in:
David Tolnay 2017-02-20 13:18:38 -08:00
parent 3bf8cda994
commit bac593573c
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
5 changed files with 95 additions and 42 deletions

View File

@ -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"] }

View File

@ -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<F>(item: &Item,
@ -32,12 +58,14 @@ pub fn with_where_predicates_from_fields<F>(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<F>(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
}

View File

@ -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))
}
}
}

View File

@ -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;

View File

@ -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!({