Skip to content

Commit

Permalink
cxx-qt-gen: remove qobject:: from impl a trait for a qobject in a bridge
Browse files Browse the repository at this point in the history
Related to #559
  • Loading branch information
ahayzen-kdab authored and Be-ing committed Jul 18, 2023
1 parent 11d6dcf commit 8652992
Show file tree
Hide file tree
Showing 16 changed files with 37 additions and 59 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `#[qproperty]` is now defined as an attribute on the qobject rather than the field
- QObject struct is now split between the bridge and implementation outside via a type alias
- `qobject` module is no longer generated
- `impl cxx_qt::trait for qobject::T` inside the bridge is now `impl cxx_qt::trait for T`

### Fixed

Expand Down
40 changes: 14 additions & 26 deletions crates/cxx-qt-gen/src/parser/cxxqtdata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@ use crate::{
};
use std::collections::BTreeMap;
use syn::ForeignItem;
use syn::{
spanned::Spanned, Attribute, Error, Ident, Item, ItemForeignMod, ItemImpl, Result, Type,
TypePath,
};
use syn::{Attribute, Error, Ident, Item, ItemForeignMod, ItemImpl, Result, Type, TypePath};

use super::invokable::ParsedQInvokable;

Expand Down Expand Up @@ -260,27 +257,18 @@ impl ParsedCxxQtData {
/// Parse a [syn::ItemImpl] into the qobjects if it's a CXX-Qt implementation
/// otherwise return as a [syn::Item] to pass through.
fn parse_impl(&mut self, imp: ItemImpl) -> Result<Option<Item>> {
// If the implementation has a qobject::T
// If the implementation has a T
// then this is the block of methods to be implemented on the C++ object
if let Type::Path(TypePath { path, .. }) = imp.self_ty.as_ref() {
// Find if we are a impl qobject::T
if path.segments.len() == 2 && path.segments[0].ident == "qobject" {
if let Some(qobject) = self.qobjects.get_mut(&path.segments[1].ident) {
if imp.trait_.is_some() {
qobject.parse_trait_impl(imp)?;
return Ok(None);
}

// non trait impls fall through
// Find if we are an impl block for a qobject
if let Some(qobject) = self.qobjects.get_mut(&path_to_single_ident(path)?) {
// If we are a trait then process it otherwise add to others
if imp.trait_.is_some() {
qobject.parse_trait_impl(imp)?;
} else {
return Err(Error::new(
imp.span(),
"No matching QObject found for the given qobject::T impl block.",
));
qobject.others.push(Item::Impl(imp));
}
// Find if we are an impl block for a qobject
} else if let Some(qobject) = self.qobjects.get_mut(&path_to_single_ident(path)?) {
qobject.others.push(Item::Impl(imp));

return Ok(None);
}
}
Expand Down Expand Up @@ -490,13 +478,13 @@ mod tests {
let mut cxx_qt_data = create_parsed_cxx_qt_data();

let item: Item = parse_quote! {
impl qobject::UnknownObj {
impl UnknownObj {
#[qinvokable]
fn invokable() {}
}
};
let result = cxx_qt_data.parse_cxx_qt_item(item);
assert!(result.is_err());
let result = cxx_qt_data.parse_cxx_qt_item(item).unwrap();
assert!(result.is_some());
}

#[test]
Expand Down Expand Up @@ -544,7 +532,7 @@ mod tests {
assert!(!cxx_qt_data.qobjects[&qobject_ident()].threading);

let item: Item = parse_quote! {
impl cxx_qt::Threading for qobject::MyObject {}
impl cxx_qt::Threading for MyObject {}
};
let result = cxx_qt_data.parse_cxx_qt_item(item).unwrap();
assert!(result.is_none());
Expand Down Expand Up @@ -883,7 +871,7 @@ mod tests {
assert!(!qobject.threading);

let threading_block: Item = parse_quote! {
impl cxx_qt::Threading for qobject::MyObject {}
impl cxx_qt::Threading for MyObject {}
};

cxxqtdata.parse_cxx_qt_item(threading_block).unwrap();
Expand Down
10 changes: 5 additions & 5 deletions crates/cxx-qt-gen/src/parser/qobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ pub mod tests {
fn test_parse_trait_impl_valid() {
let mut qobject = create_parsed_qobject();
let item: ItemImpl = parse_quote! {
impl cxx_qt::Threading for qobject::MyObject {}
impl cxx_qt::Threading for MyObject {}
};
assert!(!qobject.threading);
assert!(qobject.parse_trait_impl(item).is_ok());
Expand All @@ -346,27 +346,27 @@ pub mod tests {

// must be a trait
let item: ItemImpl = parse_quote! {
impl qobject::T {}
impl T {}
};
assert!(qobject.parse_trait_impl(item).is_err());

// no attribute allowed
let item: ItemImpl = parse_quote! {
#[attr]
impl cxx_qt::Threading for qobject::T {}
impl cxx_qt::Threading for T {}
};
assert!(qobject.parse_trait_impl(item).is_err());

// Threading cannot be negative
let item: ItemImpl = parse_quote! {
impl !cxx_qt::Threading for qobject::T {}
impl !cxx_qt::Threading for T {}
};
assert!(qobject.parse_trait_impl(item).is_err());

// must be a known trait
let item: ItemImpl = parse_quote! {
#[attr]
impl cxx_qt::ABC for qobject::T {}
impl cxx_qt::ABC for T {}
};
assert!(qobject.parse_trait_impl(item).is_err());
}
Expand Down
4 changes: 2 additions & 2 deletions crates/cxx-qt-gen/test_inputs/invokables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@ mod ffi {
fn invokable_virtual(self: &qobject::MyObject);
}

impl cxx_qt::Threading for qobject::MyObject {}
impl cxx_qt::Threading for MyObject {}

impl
cxx_qt::Constructor<
(i32, *mut QObject),
BaseArguments = (*mut QObject,),
NewArguments = (i32,),
> for qobject::MyObject
> for MyObject
{
}
}
8 changes: 1 addition & 7 deletions crates/cxx-qt-gen/test_inputs/passthrough_and_naming.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,19 +93,13 @@ pub mod ffi {
fn invokable_name(self: Pin<&mut qobject::MyObject>);
}

impl MyTrait for MyObject {
fn my_func() -> String {
"Hello".to_owned()
}
}

extern "RustQt" {
#[cxx_qt::qobject]
#[qproperty(i32, property_name)]
type SecondObject = super::SecondObjectRust;
}

unsafe impl !cxx_qt::Locking for qobject::SecondObject {}
unsafe impl !cxx_qt::Locking for SecondObject {}

unsafe extern "RustQt" {
#[my_attribute]
Expand Down
5 changes: 0 additions & 5 deletions crates/cxx-qt-gen/test_outputs/passthrough_and_naming.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,11 +215,6 @@ pub mod cxx_qt_ffi {
#[doc(hidden)]
type UniquePtr<T> = cxx::UniquePtr<T>;
use super::MyTrait;
impl MyTrait for MyObject {
fn my_func() -> String {
"Hello".to_owned()
}
}
type MyObjectRust = super::MyObjectRust;
impl MyObjectRust {
#[doc(hidden)]
Expand Down
6 changes: 3 additions & 3 deletions crates/cxx-qt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub trait CxxQtType {
///
/// By default, CXX-Qt will guard all access to the generated QObject with a recursive mutex.
/// For performance reasons it may be desirable to disable this behavior for certain QObjects.
/// You can do so by negative implementing this trait `unsafe impl !cxx_qt::Locking for qobject::T {}`.
/// You can do so by negative implementing this trait `unsafe impl !cxx_qt::Locking for T {}`.
///
/// However, this is unsafe, as it may lead to concurrent mutable access to the QObject from C++.
/// You are responsible for ensuring this does not happen!
Expand All @@ -52,7 +52,7 @@ pub trait Locking {
/// Indicates that the object implements threading and has a method which returns a [CxxQtThread].
///
/// This trait is implemented by CxxQt automatically.
/// To enable this for a `qobject::T`, add `impl cxx_qt::Threading for qobject::T {}` to your [`#[cxx_qt::bridge]`](bridge).
/// To enable this for a `T`, add `impl cxx_qt::Threading for T {}` to your [`#[cxx_qt::bridge]`](bridge).
pub trait Threading: Locking + Sized {
#[doc(hidden)]
type BoxedQueuedFn;
Expand Down Expand Up @@ -101,7 +101,7 @@ pub trait Threading: Locking + Sized {
/// // Declare that we want to use a custom constructor
/// // Note that the arguments must be a tuple of CXX types.
/// // Any associated types that aren't included here are assumed to be `()`.
/// impl cxx_qt::Constructor<(i32, String), NewArguments=(i32, String)> for qobject::MyStruct {}
/// impl cxx_qt::Constructor<(i32, String), NewArguments=(i32, String)> for MyStruct {}
/// }
///
/// // Struct without `Default` implementation
Expand Down
4 changes: 2 additions & 2 deletions examples/demo_threading/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ mod qobject {
}

// Enabling threading on the qobject
impl cxx_qt::Threading for qobject::EnergyUsage {}
impl cxx_qt::Threading for EnergyUsage {}

unsafe extern "RustQt" {
/// A new sensor has been detected
Expand All @@ -46,7 +46,7 @@ mod qobject {
fn sensor_power(self: Pin<&mut qobject::EnergyUsage>, uuid: &QString) -> f64;
}

impl cxx_qt::Constructor<()> for qobject::EnergyUsage {}
impl cxx_qt::Constructor<()> for EnergyUsage {}
}

use crate::{
Expand Down
2 changes: 1 addition & 1 deletion examples/qml_features/rust/src/custom_base_class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub mod qobject {
// ANCHOR_END: book_inherit_qalm

// Enabling threading on the qobject
impl cxx_qt::Threading for qobject::CustomBaseClass {}
impl cxx_qt::Threading for CustomBaseClass {}

// ANCHOR: book_qsignals_inherit
unsafe extern "RustQt" {
Expand Down
2 changes: 1 addition & 1 deletion examples/qml_features/rust/src/custom_parent_class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ mod qobject {
fn update(self: Pin<&mut qobject::CustomParentClass>);
}

impl cxx_qt::Constructor<()> for qobject::CustomParentClass {}
impl cxx_qt::Constructor<()> for CustomParentClass {}
}

use core::pin::Pin;
Expand Down
4 changes: 2 additions & 2 deletions examples/qml_features/rust/src/multiple_qobjects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub mod qobject {
}

// Enabling threading on the qobject
impl cxx_qt::Threading for qobject::FirstObject {}
impl cxx_qt::Threading for FirstObject {}

unsafe extern "RustQt" {
/// Accepted Q_SIGNAL
Expand All @@ -51,7 +51,7 @@ pub mod qobject {
}

// Enabling threading on the qobject
impl cxx_qt::Threading for qobject::SecondObject {}
impl cxx_qt::Threading for SecondObject {}

unsafe extern "RustQt" {
/// Accepted Q_SIGNAL
Expand Down
2 changes: 1 addition & 1 deletion examples/qml_features/rust/src/nested_qobjects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub mod qobject {
fn reset(self: Pin<&mut qobject::OuterObject>);
}

impl cxx_qt::Constructor<()> for qobject::OuterObject {}
impl cxx_qt::Constructor<()> for OuterObject {}
}

use core::pin::Pin;
Expand Down
2 changes: 1 addition & 1 deletion examples/qml_features/rust/src/signals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub mod qobject {
}
// ANCHOR_END: book_rust_obj_impl

impl cxx_qt::Constructor<()> for qobject::RustSignals {}
impl cxx_qt::Constructor<()> for RustSignals {}
}

use core::pin::Pin;
Expand Down
2 changes: 1 addition & 1 deletion examples/qml_features/rust/src/threading.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub mod qobject {

// ANCHOR: book_threading_trait
// Enabling threading on the qobject
impl cxx_qt::Threading for qobject::ThreadingWebsite {}
impl cxx_qt::Threading for ThreadingWebsite {}
// ANCHOR_END: book_threading_trait

unsafe extern "RustQt" {
Expand Down
2 changes: 1 addition & 1 deletion tests/basic_cxx_qt/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ mod qobject {
}

// Enabling threading on the qobject
impl cxx_qt::Threading for qobject::MyObject {}
impl cxx_qt::Threading for MyObject {}

unsafe extern "RustQt" {
#[qinvokable]
Expand Down
2 changes: 1 addition & 1 deletion tests/basic_cxx_qt/rust/src/locking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub mod qobject {
fn increment(self: Pin<&mut qobject::RustLockingDisabled>);
}

unsafe impl !cxx_qt::Locking for qobject::RustLockingDisabled {}
unsafe impl !cxx_qt::Locking for RustLockingDisabled {}
}

use core::pin::Pin;
Expand Down

0 comments on commit 8652992

Please sign in to comment.