Skip to content

Commit

Permalink
cxx-qt-gen: generate docs for public generated items
Browse files Browse the repository at this point in the history
Closes #517
  • Loading branch information
ahayzen-kdab authored and Be-ing committed May 17, 2023
1 parent 89ac86f commit b20d7e5
Show file tree
Hide file tree
Showing 14 changed files with 602 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- Allow associated constants, types and macro invocations within `impl qobject::T` blocks
- Ensure that generated Rust code works when `#![deny(missing_docs)]` is enabled

### Changed

Expand Down
11 changes: 11 additions & 0 deletions crates/cxx-qt-gen/src/generator/rust/invokable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub fn generate_rust_invokables(
let wrapper_ident_cpp = idents.wrapper.cpp.to_string();
let wrapper_ident_rust = &idents.wrapper.rust;
let invokable_ident_rust = &idents.name.rust;
let invokable_ident_rust_str = invokable_ident_rust.to_string();
let original_method = &invokable.method;

let cpp_struct = if invokable.mutable {
Expand Down Expand Up @@ -94,6 +95,8 @@ pub fn generate_rust_invokables(
// TODO: not all methods have a wrapper
quote! {
impl #rust_struct_name_rust {
#[doc = "Generated CXX-Qt wrapper method for the Q_INVOKABLE"]
#[doc = #invokable_ident_rust_str]
pub #has_unsafe fn #wrapper_ident_rust(#parameter_signatures) #return_type {
#has_return cpp.#invokable_ident_rust(#(#parameter_names),*);
}
Expand Down Expand Up @@ -194,6 +197,8 @@ mod tests {
&generated.cxx_qt_mod_contents[0],
quote! {
impl MyObject {
#[doc = "Generated CXX-Qt wrapper method for the Q_INVOKABLE"]
#[doc = "void_invokable"]
pub fn void_invokable_wrapper(self: &MyObject, cpp: &MyObjectQt) {
cpp.void_invokable();
}
Expand Down Expand Up @@ -223,6 +228,8 @@ mod tests {
&generated.cxx_qt_mod_contents[2],
quote! {
impl MyObject {
#[doc = "Generated CXX-Qt wrapper method for the Q_INVOKABLE"]
#[doc = "trivial_invokable"]
pub fn trivial_invokable_wrapper(self: &MyObject, cpp: &MyObjectQt, param: i32) -> i32 {
return cpp.trivial_invokable(param);
}
Expand Down Expand Up @@ -252,6 +259,8 @@ mod tests {
&generated.cxx_qt_mod_contents[4],
quote! {
impl MyObject {
#[doc = "Generated CXX-Qt wrapper method for the Q_INVOKABLE"]
#[doc = "opaque_invokable"]
pub fn opaque_invokable_wrapper(self: &mut MyObject, cpp: Pin<&mut MyObjectQt>, param: &QColor) -> UniquePtr<QColor> {
return cpp.opaque_invokable(param);
}
Expand Down Expand Up @@ -281,6 +290,8 @@ mod tests {
&generated.cxx_qt_mod_contents[6],
quote! {
impl MyObject {
#[doc = "Generated CXX-Qt wrapper method for the Q_INVOKABLE"]
#[doc = "unsafe_invokable"]
pub unsafe fn unsafe_invokable_wrapper(self: &MyObject, cpp: &MyObjectQt, param: *mut T) -> *mut T {
return cpp.unsafe_invokable(param);
}
Expand Down
15 changes: 15 additions & 0 deletions crates/cxx-qt-gen/src/generator/rust/property/getter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ pub fn generate(
let getter_rust = &idents.getter.rust;
let getter_mutable_rust = &idents.getter_mutable.rust;
let ident = &idents.name.rust;
let ident_str = ident.to_string();
let notify_ident_str = idents.notify.rust.to_string();

RustFragmentPair {
cxx_bridge: vec![quote! {
Expand All @@ -32,20 +34,33 @@ pub fn generate(
implementation: vec![
quote! {
impl #rust_struct_name_rust {
#[doc = "Getter for the Q_PROPERTY "]
#[doc = #ident_str]
#[doc = "\n"]
#[doc = "This is an internal method used by C++ to retrieve the value of the Q_PROPERTY in the Rust struct"]
pub fn #getter_rust<'a>(&'a self, cpp: &'a #cpp_class_name_rust) -> &'a #ty {
cpp.#getter_rust()
}
}
},
quote! {
impl #cpp_class_name_rust {
#[doc = "Getter for the Q_PROPERTY "]
#[doc = #ident_str]
pub fn #getter_rust(&self) -> &#ty {
&self.rust().#ident
}
}
},
quote! {
impl #cpp_class_name_rust {
#[doc = "unsafe getter for the Q_PROPERTY "]
#[doc = #ident_str]
#[doc = "\n"]
#[doc = "This allows for modifying the Q_PROPERTY without calling the property changed Q_SIGNAL"]
#[doc = "\n"]
#[doc = "After modifying the property, make sure to call the corresponding changed signal: "]
#[doc = #notify_ident_str]
pub unsafe fn #getter_mutable_rust<'a>(mut self: Pin<&'a mut Self>) -> &'a mut #ty {
&mut self.rust_mut().get_unchecked_mut().#ident
}
Expand Down
75 changes: 75 additions & 0 deletions crates/cxx-qt-gen/src/generator/rust/property/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ mod tests {
generated.cxx_qt_mod_contents[0],
parse_quote! {
impl MyObject {
#[doc = "Getter for the Q_PROPERTY "]
#[doc = "trivial_property"]
#[doc = "\n"]
#[doc = "This is an internal method used by C++ to retrieve the value of the Q_PROPERTY in the Rust struct"]
pub fn trivial_property<'a>(&'a self, cpp: &'a MyObjectQt) -> &'a i32 {
cpp.trivial_property()
}
Expand All @@ -120,6 +124,8 @@ mod tests {
generated.cxx_qt_mod_contents[1],
parse_quote! {
impl MyObjectQt {
#[doc = "Getter for the Q_PROPERTY "]
#[doc = "trivial_property"]
pub fn trivial_property(&self) -> &i32 {
&self.rust().trivial_property
}
Expand All @@ -130,6 +136,13 @@ mod tests {
generated.cxx_qt_mod_contents[2],
parse_quote! {
impl MyObjectQt {
#[doc = "unsafe getter for the Q_PROPERTY "]
#[doc = "trivial_property"]
#[doc = "\n"]
#[doc = "This allows for modifying the Q_PROPERTY without calling the property changed Q_SIGNAL"]
#[doc = "\n"]
#[doc = "After modifying the property, make sure to call the corresponding changed signal: "]
#[doc = "trivial_property_changed"]
pub unsafe fn trivial_property_mut<'a>(mut self: Pin<&'a mut Self>) -> &'a mut i32 {
&mut self.rust_mut().get_unchecked_mut().trivial_property
}
Expand All @@ -151,6 +164,10 @@ mod tests {
generated.cxx_qt_mod_contents[3],
parse_quote! {
impl MyObject {
#[doc = "Setter for the Q_PROPERTY "]
#[doc = "trivial_property"]
#[doc = "\n"]
#[doc = "This is an internal method used by C++ to set the value of the Q_PROPERTY in the Rust struct"]
pub fn set_trivial_property(&mut self, cpp: Pin<&mut MyObjectQt>, value: i32) {
cpp.set_trivial_property(value);
}
Expand All @@ -161,6 +178,8 @@ mod tests {
generated.cxx_qt_mod_contents[4],
parse_quote! {
impl MyObjectQt {
#[doc = "Setter for the Q_PROPERTY "]
#[doc = "trivial_property"]
pub fn set_trivial_property(mut self: Pin<&mut Self>, value: i32) {
if self.rust().trivial_property == value {
return;
Expand All @@ -179,6 +198,12 @@ mod tests {
generated.cxx_mod_contents[2],
parse_quote! {
unsafe extern "C++" {
#[doc = "Notify signal for the Q_PROPERTY"]
#[doc = "trivial_property"]
#[doc = "\n"]
#[doc = "This can be used to manually notify a change when the unsafe mutable getter,"]
#[doc = "trivial_property_mut"]
#[doc = ", is used."]
#[rust_name = "trivial_property_changed"]
fn trivialPropertyChanged(self: Pin<&mut MyObjectQt>);
}
Expand All @@ -201,6 +226,10 @@ mod tests {
generated.cxx_qt_mod_contents[5],
parse_quote! {
impl MyObject {
#[doc = "Getter for the Q_PROPERTY "]
#[doc = "opaque_property"]
#[doc = "\n"]
#[doc = "This is an internal method used by C++ to retrieve the value of the Q_PROPERTY in the Rust struct"]
pub fn opaque_property<'a>(&'a self, cpp: &'a MyObjectQt) -> &'a UniquePtr<QColor> {
cpp.opaque_property()
}
Expand All @@ -211,6 +240,8 @@ mod tests {
generated.cxx_qt_mod_contents[6],
parse_quote! {
impl MyObjectQt {
#[doc = "Getter for the Q_PROPERTY "]
#[doc = "opaque_property"]
pub fn opaque_property(&self) -> &UniquePtr<QColor> {
&self.rust().opaque_property
}
Expand All @@ -221,6 +252,13 @@ mod tests {
generated.cxx_qt_mod_contents[7],
parse_quote! {
impl MyObjectQt {
#[doc = "unsafe getter for the Q_PROPERTY "]
#[doc = "opaque_property"]
#[doc = "\n"]
#[doc = "This allows for modifying the Q_PROPERTY without calling the property changed Q_SIGNAL"]
#[doc = "\n"]
#[doc = "After modifying the property, make sure to call the corresponding changed signal: "]
#[doc = "opaque_property_changed"]
pub unsafe fn opaque_property_mut<'a>(mut self: Pin<&'a mut Self>) -> &'a mut UniquePtr<QColor> {
&mut self.rust_mut().get_unchecked_mut().opaque_property
}
Expand All @@ -242,6 +280,10 @@ mod tests {
generated.cxx_qt_mod_contents[8],
parse_quote! {
impl MyObject {
#[doc = "Setter for the Q_PROPERTY "]
#[doc = "opaque_property"]
#[doc = "\n"]
#[doc = "This is an internal method used by C++ to set the value of the Q_PROPERTY in the Rust struct"]
pub fn set_opaque_property(&mut self, cpp: Pin<&mut MyObjectQt>, value: UniquePtr<QColor>) {
cpp.set_opaque_property(value);
}
Expand All @@ -252,6 +294,8 @@ mod tests {
generated.cxx_qt_mod_contents[9],
parse_quote! {
impl MyObjectQt {
#[doc = "Setter for the Q_PROPERTY "]
#[doc = "opaque_property"]
pub fn set_opaque_property(mut self: Pin<&mut Self>, value: UniquePtr<QColor>) {
if self.rust().opaque_property == value {
return;
Expand All @@ -270,6 +314,12 @@ mod tests {
generated.cxx_mod_contents[5],
parse_quote! {
unsafe extern "C++" {
#[doc = "Notify signal for the Q_PROPERTY"]
#[doc = "opaque_property"]
#[doc = "\n"]
#[doc = "This can be used to manually notify a change when the unsafe mutable getter,"]
#[doc = "opaque_property_mut"]
#[doc = ", is used."]
#[rust_name = "opaque_property_changed"]
fn opaquePropertyChanged(self: Pin<&mut MyObjectQt>);
}
Expand All @@ -292,6 +342,10 @@ mod tests {
generated.cxx_qt_mod_contents[10],
parse_quote! {
impl MyObject {
#[doc = "Getter for the Q_PROPERTY "]
#[doc = "unsafe_property"]
#[doc = "\n"]
#[doc = "This is an internal method used by C++ to retrieve the value of the Q_PROPERTY in the Rust struct"]
pub fn unsafe_property<'a>(&'a self, cpp: &'a MyObjectQt) -> &'a *mut T {
cpp.unsafe_property()
}
Expand All @@ -302,6 +356,8 @@ mod tests {
generated.cxx_qt_mod_contents[11],
parse_quote! {
impl MyObjectQt {
#[doc = "Getter for the Q_PROPERTY "]
#[doc = "unsafe_property"]
pub fn unsafe_property(&self) -> &*mut T {
&self.rust().unsafe_property
}
Expand All @@ -312,6 +368,13 @@ mod tests {
generated.cxx_qt_mod_contents[12],
parse_quote! {
impl MyObjectQt {
#[doc = "unsafe getter for the Q_PROPERTY "]
#[doc = "unsafe_property"]
#[doc = "\n"]
#[doc = "This allows for modifying the Q_PROPERTY without calling the property changed Q_SIGNAL"]
#[doc = "\n"]
#[doc = "After modifying the property, make sure to call the corresponding changed signal: "]
#[doc = "unsafe_property_changed"]
pub unsafe fn unsafe_property_mut<'a>(mut self: Pin<&'a mut Self>) -> &'a mut *mut T {
&mut self.rust_mut().get_unchecked_mut().unsafe_property
}
Expand All @@ -333,6 +396,10 @@ mod tests {
generated.cxx_qt_mod_contents[13],
parse_quote! {
impl MyObject {
#[doc = "Setter for the Q_PROPERTY "]
#[doc = "unsafe_property"]
#[doc = "\n"]
#[doc = "This is an internal method used by C++ to set the value of the Q_PROPERTY in the Rust struct"]
pub fn set_unsafe_property(&mut self, cpp: Pin<&mut MyObjectQt>, value: *mut T) {
cpp.set_unsafe_property(value);
}
Expand All @@ -343,6 +410,8 @@ mod tests {
generated.cxx_qt_mod_contents[14],
parse_quote! {
impl MyObjectQt {
#[doc = "Setter for the Q_PROPERTY "]
#[doc = "unsafe_property"]
pub fn set_unsafe_property(mut self: Pin<&mut Self>, value: *mut T) {
if self.rust().unsafe_property == value {
return;
Expand All @@ -361,6 +430,12 @@ mod tests {
generated.cxx_mod_contents[8],
parse_quote! {
unsafe extern "C++" {
#[doc = "Notify signal for the Q_PROPERTY"]
#[doc = "unsafe_property"]
#[doc = "\n"]
#[doc = "This can be used to manually notify a change when the unsafe mutable getter,"]
#[doc = "unsafe_property_mut"]
#[doc = ", is used."]
#[rust_name = "unsafe_property_changed"]
fn unsafePropertyChanged(self: Pin<&mut MyObjectQt>);
}
Expand Down
7 changes: 7 additions & 0 deletions crates/cxx-qt-gen/src/generator/rust/property/setter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub fn generate(
let setter_cpp = idents.setter.cpp.to_string();
let setter_rust = &idents.setter.rust;
let ident = &idents.name.rust;
let ident_str = ident.to_string();
let notify_ident = &idents.notify.rust;

// Determine if unsafe is required due to an unsafe type
Expand All @@ -39,13 +40,19 @@ pub fn generate(
implementation: vec![
quote! {
impl #rust_struct_name_rust {
#[doc = "Setter for the Q_PROPERTY "]
#[doc = #ident_str]
#[doc = "\n"]
#[doc = "This is an internal method used by C++ to set the value of the Q_PROPERTY in the Rust struct"]
pub fn #setter_rust(&mut self, cpp: Pin<&mut #cpp_class_name_rust>, value: #ty) {
cpp.#setter_rust(value);
}
}
},
quote! {
impl #cpp_class_name_rust {
#[doc = "Setter for the Q_PROPERTY "]
#[doc = #ident_str]
pub fn #setter_rust(mut self: Pin<&mut Self>, value: #ty) {
if self.rust().#ident == value {
// don't want to set the value again and reemit the signal,
Expand Down
8 changes: 8 additions & 0 deletions crates/cxx-qt-gen/src/generator/rust/property/signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,18 @@ pub fn generate(idents: &QPropertyName, qobject_idents: &QObjectName) -> RustFra
let cpp_class_name_rust = &qobject_idents.cpp_class.rust;
let notify_cpp = &idents.notify.cpp;
let notify_rust = idents.notify.rust.to_string();
let ident_str = idents.name.rust.to_string();
let getter_mutable_rust_str = idents.getter_mutable.rust.to_string();

RustFragmentPair {
cxx_bridge: vec![quote! {
unsafe extern "C++" {
#[doc = "Notify signal for the Q_PROPERTY"]
#[doc = #ident_str]
#[doc = "\n"]
#[doc = "This can be used to manually notify a change when the unsafe mutable getter,"]
#[doc = #getter_mutable_rust_str]
#[doc = ", is used."]
#[rust_name = #notify_rust]
fn #notify_cpp(self: Pin<&mut #cpp_class_name_rust>);
}
Expand Down
13 changes: 13 additions & 0 deletions crates/cxx-qt-gen/src/generator/rust/qobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,17 @@ fn generate_qobject_definitions(
let cpp_class_name_rust = &qobject_idents.cpp_class.rust;
let rust_struct_name_cpp = &qobject_idents.rust_struct.cpp.to_string();
let rust_struct_name_rust = &qobject_idents.rust_struct.rust;
let rust_struct_name_rust_str = rust_struct_name_rust.to_string();
let fragment = RustFragmentPair {
cxx_bridge: vec![
quote! {
unsafe extern "C++" {
#[doc = "The C++ type for the QObject "]
#[doc = #rust_struct_name_rust_str]
#[doc = "\n"]
#[doc = "Use type when referring to the QObject as a pointer"]
#[doc = "\n"]
#[doc = "See the book for more information: <https://kdab.github.io/cxx-qt/book/qobject/generated-qobject.html>"]
#[cxx_name = #cpp_class_name_cpp]
type #cpp_class_name_rust;
}
Expand Down Expand Up @@ -254,6 +261,12 @@ mod tests {
&rust.blocks.cxx_mod_contents[0],
quote! {
unsafe extern "C++" {
#[doc = "The C++ type for the QObject "]
#[doc = "MyObject"]
#[doc = "\n"]
#[doc = "Use type when referring to the QObject as a pointer"]
#[doc = "\n"]
#[doc = "See the book for more information: <https://kdab.github.io/cxx-qt/book/qobject/generated-qobject.html>"]
#[cxx_name = "MyObject"]
type MyObjectQt;
}
Expand Down
Loading

0 comments on commit b20d7e5

Please sign in to comment.