Skip to content

Commit 2d0a490

Browse files
committed
improve errors of missing properties, refactor
1 parent 465b648 commit 2d0a490

File tree

1 file changed

+71
-66
lines changed

1 file changed

+71
-66
lines changed

glib-macros/src/properties.rs

Lines changed: 71 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,12 @@ impl Parse for PropsMacroInput {
4242
.attrs
4343
.iter()
4444
.find(|x| x.path.is_ident("properties"))
45-
.expect("missing #[properties(wrapper_type = ...)]");
45+
.ok_or_else(|| {
46+
syn::Error::new(
47+
derive_input.span(),
48+
"missing #[properties(wrapper_type = ...)]",
49+
)
50+
})?;
4651
let wrapper_ty: PropertiesAttr = wrapper_ty.parse_args()?;
4752
let props: Vec<_> = match derive_input.data {
4853
syn::Data::Struct(struct_data) => parse_fields(struct_data.fields)?,
@@ -258,7 +263,6 @@ impl PropDesc {
258263
));
259264
}
260265

261-
262266
// Fill needed, but missing, attributes with calculated default values
263267
let name = name.unwrap_or_else(|| {
264268
syn::LitStr::new(
@@ -285,65 +289,66 @@ impl PropDesc {
285289
}
286290
}
287291

288-
fn expand_properties_fn(props: &[PropDesc]) -> TokenStream2 {
289-
let n_props = props.len();
292+
fn expand_param_spec(prop: &PropDesc) -> TokenStream2 {
290293
let crate_ident = crate_ident_new();
291-
let properties_build_phase = props.iter().map(|prop| {
292-
let PropDesc {
293-
ty, name, builder, ..
294-
} = prop;
295-
296-
let rw_flags = match (&prop.get, &prop.set) {
297-
(Some(_), Some(_)) => quote!(.readwrite()),
298-
(Some(_), None) => quote!(.read_only()),
299-
(None, Some(_)) => quote!(.write_only()),
300-
(None, None) => unreachable!("No `get` or `set` specified"),
301-
};
294+
let PropDesc {
295+
ty, name, builder, ..
296+
} = prop;
297+
298+
match (&prop.override_class, &prop.override_interface) {
299+
(Some(c), None) => return quote!(#crate_ident::ParamSpecOverride::for_class::<#c>(#name)),
300+
(None, Some(i)) => {
301+
return quote!(#crate_ident::ParamSpecOverride::for_interface::<#i>(#name))
302+
}
303+
(Some(_), Some(_)) => {
304+
unreachable!("Both `override_class` and `override_interface` specified")
305+
}
306+
(None, None) => (),
307+
};
302308

303-
match (&prop.override_class, &prop.override_interface) {
304-
(Some(c), None) => {
305-
return quote!(#crate_ident::ParamSpecOverride::for_class::<#c>(#name))
306-
}
307-
(None, Some(i)) => {
308-
return quote!(#crate_ident::ParamSpecOverride::for_interface::<#i>(#name))
309-
}
310-
(Some(_), Some(_)) => {
311-
unreachable!("Both `override_class` and `override_interface` specified")
312-
}
313-
(None, None) => (),
314-
};
309+
let rw_flags = match (&prop.get, &prop.set) {
310+
(Some(_), Some(_)) => quote!(.readwrite()),
311+
(Some(_), None) => quote!(.read_only()),
312+
(None, Some(_)) => quote!(.write_only()),
313+
(None, None) => unreachable!("No `get` or `set` specified"),
314+
};
315315

316-
let builder_call = builder
317-
.as_ref()
318-
.cloned()
319-
.map(|(mut required_params, chained_methods)| {
320-
let name_expr = syn::ExprLit {
321-
attrs: vec![],
322-
lit: syn::Lit::Str(name.to_owned()),
323-
};
324-
required_params.insert(0, name_expr.into());
325-
let required_params = required_params.iter();
326-
327-
quote!((#(#required_params,)*)#chained_methods)
328-
})
329-
.unwrap_or(quote!((#name)));
316+
let builder_call = builder
317+
.as_ref()
318+
.cloned()
319+
.map(|(mut required_params, chained_methods)| {
320+
let name_expr = syn::ExprLit {
321+
attrs: vec![],
322+
lit: syn::Lit::Str(name.to_owned()),
323+
};
324+
required_params.insert(0, name_expr.into());
325+
let required_params = required_params.iter();
330326

331-
let builder_fields = prop.builder_fields.iter().map(|(k, v)| quote!(.#k(#v)));
327+
quote!((#(#required_params,)*)#chained_methods)
328+
})
329+
.unwrap_or(quote!((#name)));
332330

333-
let span = prop.attrs_span;
334-
quote_spanned! {span=>
335-
<<#ty as #crate_ident::Property>::Value as #crate_ident::HasParamSpec>
336-
::param_spec_builder() #builder_call
337-
#rw_flags
338-
#(#builder_fields)*
339-
.build()
340-
}
341-
});
331+
let builder_fields = prop.builder_fields.iter().map(|(k, v)| quote!(.#k(#v)));
332+
333+
let span = prop.attrs_span;
334+
quote_spanned! {span=>
335+
<<#ty as #crate_ident::Property>::Value as #crate_ident::HasParamSpec>
336+
::param_spec_builder() #builder_call
337+
#rw_flags
338+
#(#builder_fields)*
339+
.build()
340+
}
341+
}
342+
343+
fn expand_properties_fn(props: &[PropDesc]) -> TokenStream2 {
344+
let n_props = props.len();
345+
let crate_ident = crate_ident_new();
346+
let param_specs = props.iter().map(expand_param_spec);
342347
quote!(
343348
fn derived_properties() -> &'static [#crate_ident::ParamSpec] {
344349
use #crate_ident::once_cell::sync::Lazy;
345350
static PROPERTIES: Lazy<[#crate_ident::ParamSpec; #n_props]> = Lazy::new(|| [
346-
#(#properties_build_phase,)*
351+
#(#param_specs,)*
347352
]);
348353
PROPERTIES.as_ref()
349354
}
@@ -393,10 +398,10 @@ fn expand_property_fn(props: &[PropDesc]) -> TokenStream2 {
393398
pspec: &#crate_ident::ParamSpec
394399
) -> #crate_ident::Value {
395400
let prop = DerivedPropertiesEnum::try_from(id-1)
396-
.unwrap_or_else(|_| panic!("missing handler for property {}", pspec.name()));
401+
.unwrap_or_else(|_| panic!("property not defined {}", pspec.name()));
397402
match prop {
398403
#(#match_branch_get,)*
399-
_ => unreachable!(),
404+
_ => panic!("missing getter for property {}", pspec.name()),
400405
}
401406
}
402407
)
@@ -451,10 +456,10 @@ fn expand_set_property_fn(props: &[PropDesc]) -> TokenStream2 {
451456
pspec: &#crate_ident::ParamSpec
452457
){
453458
let prop = DerivedPropertiesEnum::try_from(id-1)
454-
.unwrap_or_else(|_| panic!("missing handler for property {}", pspec.name()));;
459+
.unwrap_or_else(|_| panic!("property not defined {}", pspec.name()));
455460
match prop {
456461
#(#match_branch_set,)*
457-
_ => unreachable!(),
462+
_ => panic!("missing setter for property {}", pspec.name()),
458463
}
459464
}
460465
)
@@ -476,7 +481,7 @@ fn parse_fields(fields: syn::Fields) -> syn::Result<Vec<PropDesc>> {
476481
span,
477482
ident.as_ref().unwrap().clone(),
478483
ty.clone(),
479-
prop_attrs.parse_args()?
484+
prop_attrs.parse_args()?,
480485
)
481486
})
482487
})
@@ -488,7 +493,7 @@ fn name_to_ident(name: &syn::LitStr) -> syn::Ident {
488493
format_ident!("{}", name.value().replace('-', "_"))
489494
}
490495

491-
fn expand_getset_properties_impl(props: &[PropDesc]) -> TokenStream2 {
496+
fn expand_wrapper_getset_properties(props: &[PropDesc]) -> TokenStream2 {
492497
let crate_ident = crate_ident_new();
493498
let defs = props.iter().map(|p| {
494499
let name = &p.name;
@@ -516,7 +521,7 @@ fn expand_getset_properties_impl(props: &[PropDesc]) -> TokenStream2 {
516521
quote!(#(#defs)*)
517522
}
518523

519-
fn expand_connect_prop_notify_impl(props: &[PropDesc]) -> TokenStream2 {
524+
fn expand_wrapper_connect_prop_notify(props: &[PropDesc]) -> TokenStream2 {
520525
let crate_ident = crate_ident_new();
521526
let connection_fns = props.iter().map(|p| {
522527
let name = &p.name;
@@ -531,7 +536,7 @@ fn expand_connect_prop_notify_impl(props: &[PropDesc]) -> TokenStream2 {
531536
quote!(#(#connection_fns)*)
532537
}
533538

534-
fn expand_notify_impl(props: &[PropDesc]) -> TokenStream2 {
539+
fn expand_wrapper_notify_prop(props: &[PropDesc]) -> TokenStream2 {
535540
let crate_ident = crate_ident_new();
536541
let emit_fns = props.iter().map(|p| {
537542
let name = &p.name;
@@ -601,9 +606,9 @@ pub fn impl_derive_props(input: PropsMacroInput) -> TokenStream {
601606
let fn_properties = expand_properties_fn(&input.props);
602607
let fn_property = expand_property_fn(&input.props);
603608
let fn_set_property = expand_set_property_fn(&input.props);
604-
let getset_properties_impl = expand_getset_properties_impl(&input.props);
605-
let connect_prop_notify_impl = expand_connect_prop_notify_impl(&input.props);
606-
let notify_impl = expand_notify_impl(&input.props);
609+
let getset_properties = expand_wrapper_getset_properties(&input.props);
610+
let connect_prop_notify = expand_wrapper_connect_prop_notify(&input.props);
611+
let notify_prop = expand_wrapper_notify_prop(&input.props);
607612
let properties_enum = expand_properties_enum(&input.props);
608613

609614
let expanded = quote! {
@@ -618,9 +623,9 @@ pub fn impl_derive_props(input: PropsMacroInput) -> TokenStream {
618623
}
619624

620625
impl #wrapper_type {
621-
#getset_properties_impl
622-
#connect_prop_notify_impl
623-
#notify_impl
626+
#getset_properties
627+
#connect_prop_notify
628+
#notify_prop
624629
}
625630

626631
};

0 commit comments

Comments
 (0)