Skip to content

Commit dc6da06

Browse files
committed
Implement ext trait on IsA<T>, don't generate overridden methods
1 parent d1fdc2e commit dc6da06

File tree

2 files changed

+21
-72
lines changed

2 files changed

+21
-72
lines changed

glib-macros/src/properties.rs

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,9 @@ impl PropDesc {
332332
is_construct_only,
333333
})
334334
}
335+
fn is_overriding(&self) -> bool {
336+
self.override_class.is_some() || self.override_interface.is_some()
337+
}
335338
}
336339

337340
fn expand_param_spec(prop: &PropDesc) -> TokenStream2 {
@@ -558,7 +561,7 @@ fn strip_raw_prefix_from_name(name: &LitStr) -> LitStr {
558561

559562
fn expand_impl_getset_properties(props: &[PropDesc]) -> Vec<syn::ImplItemFn> {
560563
let crate_ident = crate_ident_new();
561-
let defs = props.iter().map(|p| {
564+
let defs = props.iter().filter(|p| !p.is_overriding()).map(|p| {
562565
let name = &p.name;
563566
let stripped_name = strip_raw_prefix_from_name(name);
564567
let ident = name_to_ident(name);
@@ -604,7 +607,7 @@ fn expand_impl_getset_properties(props: &[PropDesc]) -> Vec<syn::ImplItemFn> {
604607

605608
fn expand_impl_connect_prop_notify(props: &[PropDesc]) -> Vec<syn::ImplItemFn> {
606609
let crate_ident = crate_ident_new();
607-
let connection_fns = props.iter().map(|p| -> syn::ImplItemFn {
610+
let connection_fns = props.iter().filter(|p| !p.is_overriding()).map(|p| -> syn::ImplItemFn {
608611
let name = &p.name;
609612
let stripped_name = strip_raw_prefix_from_name(name);
610613
let fn_ident = format_ident!("connect_{}_notify", name_to_ident(name));
@@ -618,16 +621,16 @@ fn expand_impl_connect_prop_notify(props: &[PropDesc]) -> Vec<syn::ImplItemFn> {
618621
connection_fns.collect::<Vec<_>>()
619622
}
620623

621-
fn expand_impl_notify_prop(props: &[PropDesc]) -> Vec<syn::ImplItemFn> {
624+
fn expand_impl_notify_prop(wrapper_type: &syn::Path, props: &[PropDesc]) -> Vec<syn::ImplItemFn> {
622625
let crate_ident = crate_ident_new();
623-
let emit_fns = props.iter().map(|p| -> syn::ImplItemFn {
626+
let emit_fns = props.iter().filter(|p| !p.is_overriding()).map(|p| -> syn::ImplItemFn {
624627
let name = strip_raw_prefix_from_name(&p.name);
625628
let fn_ident = format_ident!("notify_{}", name_to_ident(&name));
626629
let span = p.attrs_span;
627630
let enum_ident = name_to_enum_ident(name.value());
628631
parse_quote_spanned!(span=> pub fn #fn_ident(&self) {
629632
self.notify_by_pspec(
630-
&<<Self as #crate_ident::object::ObjectSubclassIs>::Subclass
633+
&<<#wrapper_type as #crate_ident::object::ObjectSubclassIs>::Subclass
631634
as #crate_ident::subclass::object::DerivedObjectProperties>::derived_properties()
632635
[DerivedPropertiesEnum::#enum_ident as usize]
633636
);
@@ -692,7 +695,7 @@ pub fn impl_derive_props(input: PropsMacroInput) -> TokenStream {
692695
let fn_set_property = expand_set_property_fn(&input.props);
693696
let getset_properties = expand_impl_getset_properties(&input.props);
694697
let connect_prop_notify = expand_impl_connect_prop_notify(&input.props);
695-
let notify_prop = expand_impl_notify_prop(&input.props);
698+
let notify_prop = expand_impl_notify_prop(&wrapper_type, &input.props);
696699
let properties_enum = expand_properties_enum(&input.props);
697700

698701
let rust_interface = if let Some(ext_trait) = input.ext_trait {
@@ -704,17 +707,7 @@ pub fn impl_derive_props(input: PropsMacroInput) -> TokenStream {
704707
wrapper_type.segments.last().unwrap().ident
705708
)
706709
};
707-
let signatures = getset_properties
708-
.iter()
709-
.chain(connect_prop_notify.iter())
710-
.chain(notify_prop.iter())
711-
.map(|item| &item.sig);
712-
let trait_def = quote! {
713-
pub trait #trait_ident {
714-
#(#signatures;)*
715-
}
716-
};
717-
let impls = getset_properties
710+
let fns_without_visibility_modifier = getset_properties
718711
.into_iter()
719712
.chain(connect_prop_notify)
720713
.chain(notify_prop)
@@ -723,10 +716,10 @@ pub fn impl_derive_props(input: PropsMacroInput) -> TokenStream {
723716
item
724717
});
725718
quote! {
726-
#trait_def
727-
impl #trait_ident for #wrapper_type {
728-
#(#impls)*
719+
pub trait #trait_ident: #crate_ident::IsA<#wrapper_type> {
720+
#(#fns_without_visibility_modifier)*
729721
}
722+
impl<T: #crate_ident::IsA<#wrapper_type>> #trait_ident for T {}
730723
}
731724
} else {
732725
quote! {

glib-macros/tests/properties.rs

Lines changed: 8 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ mod base {
1414
use super::*;
1515

1616
#[derive(Properties, Default)]
17-
#[properties(wrapper_type = super::Base)]
17+
#[properties(wrapper_type = super::Base, ext_trait)]
1818
pub struct Base {
1919
#[property(get = Self::not_overridden)]
2020
overridden: PhantomData<u32>,
@@ -388,59 +388,15 @@ fn props() {
388388
);
389389
}
390390

391-
mod ext_trait {
392-
use glib::subclass::object::DerivedObjectProperties;
393-
use glib::ObjectExt;
394-
395-
use glib::subclass::{prelude::ObjectImpl, types::ObjectSubclass};
396-
use glib_macros::Properties;
397-
use std::cell::RefCell;
398-
399-
pub mod imp {
400-
use super::*;
401-
402-
#[derive(Properties, Default)]
403-
#[properties(wrapper_type = super::Author, ext_trait)]
404-
pub struct Author {
405-
#[property(get, set)]
406-
firstname: RefCell<String>,
407-
#[property(get, set)]
408-
lastname: RefCell<String>,
409-
}
410-
411-
#[glib::derived_properties]
412-
impl ObjectImpl for Author {}
413-
414-
#[glib::object_subclass]
415-
impl ObjectSubclass for Author {
416-
const NAME: &'static str = "Author";
417-
type Type = super::Author;
418-
}
419-
}
420-
421-
glib::wrapper! {
422-
pub struct Author(ObjectSubclass<imp::Author>);
423-
}
424-
impl Author {
425-
pub fn new() -> Self {
426-
glib::Object::builder().build()
427-
}
428-
}
429-
impl Default for Author {
430-
fn default() -> Self {
431-
Self::new()
432-
}
433-
}
434-
}
435-
436391
#[test]
437392
fn ext_trait() {
438-
use ext_trait::imp::AuthorPropertiesExt;
439-
let author = ext_trait::Author::new();
440-
AuthorPropertiesExt::set_firstname(&author, "John");
441-
AuthorPropertiesExt::set_lastname(&author, "Doe");
442-
assert_eq!(AuthorPropertiesExt::firstname(&author), "John");
443-
assert_eq!(AuthorPropertiesExt::lastname(&author), "Doe");
393+
use base::imp::BasePropertiesExt;
394+
let base: base::Base = glib::object::Object::builder().build();
395+
assert_eq!(BasePropertiesExt::overridden(&base), 42);
396+
397+
let foo: foo::Foo = glib::object::Object::builder().build();
398+
assert_eq!(BasePropertiesExt::overridden(&foo), 43);
399+
assert_eq!(foo.overridden(), 43);
444400
}
445401

446402
#[test]

0 commit comments

Comments
 (0)