Skip to content

Commit

Permalink
Format component of style_derive
Browse files Browse the repository at this point in the history
  • Loading branch information
chansuke committed Sep 7, 2018
1 parent 51283cf commit 25bc998
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 127 deletions.
2 changes: 1 addition & 1 deletion components/style_derive/animate.rs
Expand Up @@ -31,7 +31,7 @@ pub fn derive(mut input: DeriveInput) -> Tokens {
Err(()) => {
append_error_clause = true;
return body;
}
},
};
quote! { #body #arm }
});
Expand Down
172 changes: 92 additions & 80 deletions components/style_derive/cg.rs
Expand Up @@ -11,23 +11,21 @@ use syn::{TypeParam, TypeParen, TypePath, TypeSlice, TypeTuple};
use syn::{Variant, WherePredicate};
use synstructure::{self, BindingInfo, BindStyle, VariantAst, VariantInfo};

pub fn add_predicate(
where_clause: &mut Option<syn::WhereClause>,
pred: WherePredicate,
) {
where_clause.get_or_insert(parse_quote!(where)).predicates.push(pred);
pub fn add_predicate(where_clause: &mut Option<syn::WhereClause>, pred: WherePredicate) {
where_clause
.get_or_insert(parse_quote!(where))
.predicates
.push(pred);
}

pub fn fmap_match<F>(
input: &DeriveInput,
bind_style: BindStyle,
mut f: F,
) -> Tokens
pub fn fmap_match<F>(input: &DeriveInput, bind_style: BindStyle, mut f: F) -> Tokens
where
F: FnMut(BindingInfo) -> Tokens,
{
let mut s = synstructure::Structure::new(input);
s.variants_mut().iter_mut().for_each(|v| { v.bind_with(|_| bind_style); });
s.variants_mut().iter_mut().for_each(|v| {
v.bind_with(|_| bind_style);
});
s.each_variant(|variant| {
let (mapped, mapped_fields) = value(variant, "mapped");
let fields_pairs = variant.bindings().into_iter().zip(mapped_fields);
Expand All @@ -41,31 +39,30 @@ where
})
}

pub fn fmap_trait_output(
input: &DeriveInput,
trait_path: &Path,
trait_output: Ident,
) -> Path {
pub fn fmap_trait_output(input: &DeriveInput, trait_path: &Path, trait_output: Ident) -> Path {
let segment = PathSegment {
ident: input.ident.clone(),
arguments: PathArguments::AngleBracketed(AngleBracketedGenericArguments {
args: input.generics.params.iter().map(|arg| {
match arg {
&GenericParam::Lifetime(ref data) => GenericArgument::Lifetime(data.lifetime.clone()),
args: input
.generics
.params
.iter()
.map(|arg| match arg {
&GenericParam::Lifetime(ref data) => {
GenericArgument::Lifetime(data.lifetime.clone())
},
&GenericParam::Type(ref data) => {
let ident = data.ident;
GenericArgument::Type(
parse_quote!(<#ident as ::#trait_path>::#trait_output),
)
},
ref arg => panic!("arguments {:?} cannot be mapped yet", arg)
}
}).collect(),
ref arg => panic!("arguments {:?} cannot be mapped yet", arg),
}).collect(),
colon2_token: Default::default(),
gt_token: Default::default(),
lt_token: Default::default(),

})
}),
};
segment.into()
}
Expand All @@ -75,44 +72,55 @@ where
F: FnMut(&Ident) -> Type,
{
match *ty {
Type::Slice(ref inner) => {
Type::from(TypeSlice { elem: Box::new(map_type_params(&inner.elem, params, f)), ..inner.clone() })
},
Type::Array(ref inner) => { //ref ty, ref expr) => {
Type::from(TypeArray { elem: Box::new(map_type_params(&inner.elem, params, f)), ..inner.clone() })
Type::Slice(ref inner) => Type::from(TypeSlice {
elem: Box::new(map_type_params(&inner.elem, params, f)),
..inner.clone()
}),
Type::Array(ref inner) => {
//ref ty, ref expr) => {
Type::from(TypeArray {
elem: Box::new(map_type_params(&inner.elem, params, f)),
..inner.clone()
})
},
ref ty @ Type::Never(_) => ty.clone(),
Type::Tuple(ref inner) => {
Type::from(
TypeTuple {
elems: inner.elems.iter().map(|ty| map_type_params(&ty, params, f)).collect(),
..inner.clone()
}
)
},
Type::Path(TypePath { qself: None, ref path }) => {
Type::Tuple(ref inner) => Type::from(TypeTuple {
elems: inner
.elems
.iter()
.map(|ty| map_type_params(&ty, params, f))
.collect(),
..inner.clone()
}),
Type::Path(TypePath {
qself: None,
ref path,
}) => {
if let Some(ident) = path_to_ident(path) {
if params.iter().any(|param| param.ident == ident) {
return f(ident);
}
}
Type::from(TypePath { qself: None, path: map_type_params_in_path(path, params, f) })
}
Type::Path(TypePath { ref qself, ref path }) => {
Type::from(TypePath {
qself: qself.as_ref().map(|qself| {
QSelf {
ty: Box::new(map_type_params(&qself.ty, params, f)),
position: qself.position,
..qself.clone()
}
}),
qself: None,
path: map_type_params_in_path(path, params, f),
})
},
Type::Paren(ref inner) => {
Type::from(TypeParen { elem: Box::new(map_type_params(&inner.elem, params, f)), ..inner.clone() })
},
Type::Path(TypePath {
ref qself,
ref path,
}) => Type::from(TypePath {
qself: qself.as_ref().map(|qself| QSelf {
ty: Box::new(map_type_params(&qself.ty, params, f)),
position: qself.position,
..qself.clone()
}),
path: map_type_params_in_path(path, params, f),
}),
Type::Paren(ref inner) => Type::from(TypeParen {
elem: Box::new(map_type_params(&inner.elem, params, f)),
..inner.clone()
}),
ref ty => panic!("type {:?} cannot be mapped yet", ty),
}
}
Expand All @@ -123,41 +131,48 @@ where
{
Path {
leading_colon: path.leading_colon,
segments: path.segments.iter().map(|segment| {
PathSegment {
segments: path
.segments
.iter()
.map(|segment| PathSegment {
ident: segment.ident.clone(),
arguments: match segment.arguments {
PathArguments::AngleBracketed(ref data) => {
PathArguments::AngleBracketed(AngleBracketedGenericArguments {
args: data.args.iter().map(|arg| {
match arg {
args: data
.args
.iter()
.map(|arg| match arg {
ty @ &GenericArgument::Lifetime(_) => ty.clone(),
&GenericArgument::Type(ref data) => {
GenericArgument::Type(map_type_params(data, params, f))
},
&GenericArgument::Binding(ref data) => GenericArgument::Binding(Binding {
ty: map_type_params(&data.ty, params, f),
..data.clone()
}),
ref arg => panic!("arguments {:?} cannot be mapped yet", arg)
}
}).collect(),
&GenericArgument::Binding(ref data) => {
GenericArgument::Binding(Binding {
ty: map_type_params(&data.ty, params, f),
..data.clone()
})
},
ref arg => panic!("arguments {:?} cannot be mapped yet", arg),
}).collect(),
..data.clone()
})
},
ref arg @ PathArguments::None => arg.clone(),
ref parameters => {
panic!("parameters {:?} cannot be mapped yet", parameters)
}
ref parameters => panic!("parameters {:?} cannot be mapped yet", parameters),
},
}
}).collect(),
}).collect(),
}
}

fn path_to_ident(path: &Path) -> Option<&Ident> {
match *path {
Path { leading_colon: None, ref segments } if segments.len() == 1 => {
Path {
leading_colon: None,
ref segments,
}
if segments.len() == 1 =>
{
if segments[0].arguments.is_empty() {
Some(&segments[0].ident)
} else {
Expand Down Expand Up @@ -203,31 +218,28 @@ where

pub fn parse_variant_attrs<A>(variant: &Variant) -> A
where
A: FromVariant
A: FromVariant,
{
match A::from_variant(variant) {
Ok(attrs) => attrs,
Err(e) => panic!("failed to parse variant attributes: {}", e),
}
}


pub fn ref_pattern<'a>(
variant: &'a VariantInfo,
prefix: &str,
) -> (Tokens, Vec<BindingInfo<'a>>) {
pub fn ref_pattern<'a>(variant: &'a VariantInfo, prefix: &str) -> (Tokens, Vec<BindingInfo<'a>>) {
let mut v = variant.clone();
v.bind_with(|_| BindStyle::Ref);
v.bindings_mut().iter_mut().for_each(|b| { b.binding = Ident::from(format!("{}_{}", b.binding, prefix)) });
v.bindings_mut()
.iter_mut()
.for_each(|b| b.binding = Ident::from(format!("{}_{}", b.binding, prefix)));
(v.pat(), v.bindings().iter().cloned().collect())
}

pub fn value<'a>(
variant: &'a VariantInfo,
prefix: &str,
) -> (Tokens, Vec<BindingInfo<'a>>) {
pub fn value<'a>(variant: &'a VariantInfo, prefix: &str) -> (Tokens, Vec<BindingInfo<'a>>) {
let mut v = variant.clone();
v.bindings_mut().iter_mut().for_each(|b| { b.binding = Ident::from(format!("{}_{}", b.binding, prefix)) });
v.bindings_mut()
.iter_mut()
.for_each(|b| b.binding = Ident::from(format!("{}_{}", b.binding, prefix)));
v.bind_with(|_| BindStyle::Move);
(v.pat(), v.bindings().iter().cloned().collect())
}
Expand Down
9 changes: 6 additions & 3 deletions components/style_derive/lib.rs
Expand Up @@ -4,10 +4,13 @@

#![recursion_limit = "128"]

#[macro_use] extern crate darling;
#[macro_use]
extern crate darling;
extern crate proc_macro;
#[macro_use] extern crate quote;
#[macro_use] extern crate syn;
#[macro_use]
extern crate quote;
#[macro_use]
extern crate syn;
extern crate synstructure;

use proc_macro::TokenStream;
Expand Down
13 changes: 6 additions & 7 deletions components/style_derive/parse.rs
Expand Up @@ -27,23 +27,23 @@ pub fn derive(input: DeriveInput) -> Tokens {
"Parse is only supported for single-variant enums for now"
);

let css_variant_attrs =
cg::parse_variant_attrs_from_ast::<CssVariantAttrs>(&variant.ast());
let parse_attrs =
cg::parse_variant_attrs_from_ast::<ParseVariantAttrs>(&variant.ast());
let css_variant_attrs = cg::parse_variant_attrs_from_ast::<CssVariantAttrs>(&variant.ast());
let parse_attrs = cg::parse_variant_attrs_from_ast::<ParseVariantAttrs>(&variant.ast());
if css_variant_attrs.skip {
return match_body;
}

let identifier = cg::to_css_identifier(
&css_variant_attrs.keyword.unwrap_or(variant.ast().ident.as_ref().into()),
&css_variant_attrs
.keyword
.unwrap_or(variant.ast().ident.as_ref().into()),
);
let ident = &variant.ast().ident;

saw_condition |= parse_attrs.condition.is_some();
let condition = match parse_attrs.condition {
Some(ref p) => quote! { if #p(context) },
None => quote! { },
None => quote!{},
};

let mut body = quote! {
Expand Down Expand Up @@ -87,7 +87,6 @@ pub fn derive(input: DeriveInput) -> Tokens {
quote! { Self::parse(input) }
};


let parse_trait_impl = quote! {
impl ::parser::Parse for #name {
#[inline]
Expand Down
24 changes: 15 additions & 9 deletions components/style_derive/specified_value_info.rs
Expand Up @@ -17,8 +17,8 @@ pub fn derive(mut input: DeriveInput) -> Tokens {
let input_name = || cg::to_css_identifier(input_ident.as_ref());
if let Some(function) = css_attrs.function {
values.push(function.explicit().unwrap_or_else(input_name));
// If the whole value is wrapped in a function, value types of
// its fields should not be propagated.
// If the whole value is wrapped in a function, value types of
// its fields should not be propagated.
} else {
let mut where_clause = input.generics.where_clause.take();
for param in input.generics.type_params() {
Expand Down Expand Up @@ -66,12 +66,12 @@ pub fn derive(mut input: DeriveInput) -> Tokens {
}
}
}
}
},
Data::Struct(ref s) => {
if !derive_struct_fields(&s.fields, &mut types, &mut values) {
values.push(input_name());
}
}
},
Data::Union(_) => unreachable!("union is not supported"),
}
}
Expand All @@ -84,13 +84,17 @@ pub fn derive(mut input: DeriveInput) -> Tokens {
}

let mut types_value = quote!(0);
types_value.append_all(types.iter().map(|ty| quote! {
| <#ty as ::style_traits::SpecifiedValueInfo>::SUPPORTED_TYPES
types_value.append_all(types.iter().map(|ty| {
quote! {
| <#ty as ::style_traits::SpecifiedValueInfo>::SUPPORTED_TYPES
}
}));

let mut nested_collects = quote!();
nested_collects.append_all(types.iter().map(|ty| quote! {
<#ty as ::style_traits::SpecifiedValueInfo>::collect_completion_keywords(_f);
nested_collects.append_all(types.iter().map(|ty| {
quote! {
<#ty as ::style_traits::SpecifiedValueInfo>::collect_completion_keywords(_f);
}
}));

if let Some(ty) = info_attrs.ty {
Expand Down Expand Up @@ -144,7 +148,9 @@ fn derive_struct_fields<'a>(
}
let css_attrs = cg::parse_field_attrs::<CssFieldAttrs>(field);
if css_attrs.represents_keyword {
let ident = field.ident.as_ref()
let ident = field
.ident
.as_ref()
.expect("only named field should use represents_keyword");
values.push(cg::to_css_identifier(ident.as_ref()));
return None;
Expand Down

0 comments on commit 25bc998

Please sign in to comment.