aboutsummaryrefslogtreecommitdiffstats
path: root/components/style_derive/parse.rs
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <emilio@crisal.io>2020-05-21 13:48:36 +0000
committerEmilio Cobos Álvarez <emilio@crisal.io>2020-06-04 01:50:36 +0200
commit66185e81f66c59dc1d26cbf91dc78bb3701f2b94 (patch)
tree41d82c55f77b64425d834eaadb5976196df878f4 /components/style_derive/parse.rs
parent35546aea54e73ef1428d6921c0ec059a7250d526 (diff)
downloadservo-66185e81f66c59dc1d26cbf91dc78bb3701f2b94.tar.gz
servo-66185e81f66c59dc1d26cbf91dc78bb3701f2b94.zip
style: Support field_bound in #[derive(Parse)].
Differential Revision: https://phabricator.services.mozilla.com/D76268
Diffstat (limited to 'components/style_derive/parse.rs')
-rw-r--r--components/style_derive/parse.rs41
1 files changed, 28 insertions, 13 deletions
diff --git a/components/style_derive/parse.rs b/components/style_derive/parse.rs
index 80c214bd734..6dc2c8a715b 100644
--- a/components/style_derive/parse.rs
+++ b/components/style_derive/parse.rs
@@ -15,7 +15,14 @@ pub struct ParseVariantAttrs {
pub condition: Option<Path>,
}
+#[darling(attributes(parse), default)]
+#[derive(Default, FromField)]
+pub struct ParseFieldAttrs {
+ field_bound: bool,
+}
+
fn parse_non_keyword_variant(
+ where_clause: &mut Option<syn::WhereClause>,
name: &syn::Ident,
variant: &VariantInfo,
variant_attrs: &CssVariantAttrs,
@@ -32,7 +39,14 @@ fn parse_non_keyword_variant(
"We only support deriving parse for simple variants"
);
let variant_name = &variant.ast().ident;
- let ty = &bindings[0].ast().ty;
+ let binding_ast = &bindings[0].ast();
+ let ty = &binding_ast.ty;
+
+ let field_attrs = cg::parse_field_attrs::<ParseFieldAttrs>(binding_ast);
+ if field_attrs.field_bound {
+ cg::add_predicate(where_clause, parse_quote!(#ty: crate::parser::Parse));
+ }
+
let mut parse = if skip_try {
quote! {
let v = <#ty as crate::parser::Parse>::parse(context, input)?;
@@ -67,15 +81,12 @@ fn parse_non_keyword_variant(
}
pub fn derive(mut input: DeriveInput) -> TokenStream {
- {
- let mut where_clause = input.generics.where_clause.take();
- for param in input.generics.type_params() {
- cg::add_predicate(
- &mut where_clause,
- parse_quote!(#param: crate::parser::Parse),
- );
- }
- input.generics.where_clause = where_clause;
+ let mut where_clause = input.generics.where_clause.take();
+ for param in input.generics.type_params() {
+ cg::add_predicate(
+ &mut where_clause,
+ parse_quote!(#param: crate::parser::Parse),
+ );
}
let name = &input.ident;
@@ -88,12 +99,13 @@ pub fn derive(mut input: DeriveInput) -> TokenStream {
let mut effective_variants = 0;
for variant in s.variants().iter() {
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 {
continue;
}
effective_variants += 1;
+ let parse_attrs = cg::parse_variant_attrs_from_ast::<ParseVariantAttrs>(&variant.ast());
+
saw_condition |= parse_attrs.condition.is_some();
if !variant.bindings().is_empty() {
@@ -143,7 +155,7 @@ pub fn derive(mut input: DeriveInput) -> TokenStream {
for (i, (variant, css_attrs, parse_attrs)) in non_keywords.iter().enumerate() {
let skip_try = !has_keywords && i == non_keywords.len() - 1;
let parse_variant =
- parse_non_keyword_variant(name, variant, css_attrs, parse_attrs, skip_try);
+ parse_non_keyword_variant(&mut where_clause, name, variant, css_attrs, parse_attrs, skip_try);
parse_non_keywords.extend(parse_variant);
}
@@ -171,6 +183,9 @@ pub fn derive(mut input: DeriveInput) -> TokenStream {
quote! { Self::parse(input) }
};
+ let has_non_keywords = !non_keywords.is_empty();
+
+ input.generics.where_clause = where_clause;
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
let parse_trait_impl = quote! {
@@ -189,7 +204,7 @@ pub fn derive(mut input: DeriveInput) -> TokenStream {
return parse_trait_impl;
}
- assert!(non_keywords.is_empty());
+ assert!(!has_non_keywords);
// TODO(emilio): It'd be nice to get rid of these, but that makes the
// conversion harder...