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 KDAB#517
  • Loading branch information
ahayzen-kdab committed Apr 28, 2023
1 parent 8a18a51 commit f4f4e84
Show file tree
Hide file tree
Showing 12 changed files with 291 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased](https://github.com/KDAB/cxx-qt/compare/v0.5.2...HEAD)

### Added

- Ensure that generated Rust code works when `#![deny(missing_docs)]` is enabled

### Changed

- `QDateTime` API to use `current_date_time` rather than `current_date`
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 @@ -197,6 +200,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 @@ -226,6 +231,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 @@ -255,6 +262,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 @@ -284,6 +293,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
11 changes: 11 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,7 @@ 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();

RustFragmentPair {
cxx_bridge: vec![quote! {
Expand All @@ -32,20 +33,30 @@ 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"]
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
48 changes: 48 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 @@ -109,6 +109,10 @@ mod tests {
generated.cxx_qt_mod_contents[0],
tokens_to_syn::<syn::Item>(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 @@ -119,6 +123,8 @@ mod tests {
generated.cxx_qt_mod_contents[1],
tokens_to_syn::<syn::Item>(quote! {
impl MyObjectQt {
#[doc = "Getter for the Q_PROPERTY "]
#[doc = "trivial_property"]
pub fn trivial_property(&self) -> &i32 {
&self.rust().trivial_property
}
Expand All @@ -129,6 +135,10 @@ mod tests {
generated.cxx_qt_mod_contents[2],
tokens_to_syn::<syn::Item>(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"]
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 @@ -150,6 +160,10 @@ mod tests {
generated.cxx_qt_mod_contents[3],
tokens_to_syn::<syn::Item>(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 @@ -160,6 +174,8 @@ mod tests {
generated.cxx_qt_mod_contents[4],
tokens_to_syn::<syn::Item>(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 Down Expand Up @@ -200,6 +216,10 @@ mod tests {
generated.cxx_qt_mod_contents[5],
tokens_to_syn::<syn::Item>(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 @@ -210,6 +230,8 @@ mod tests {
generated.cxx_qt_mod_contents[6],
tokens_to_syn::<syn::Item>(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 @@ -220,6 +242,10 @@ mod tests {
generated.cxx_qt_mod_contents[7],
tokens_to_syn::<syn::Item>(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"]
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 @@ -241,6 +267,10 @@ mod tests {
generated.cxx_qt_mod_contents[8],
tokens_to_syn::<syn::Item>(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 @@ -251,6 +281,8 @@ mod tests {
generated.cxx_qt_mod_contents[9],
tokens_to_syn::<syn::Item>(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 Down Expand Up @@ -291,6 +323,10 @@ mod tests {
generated.cxx_qt_mod_contents[10],
tokens_to_syn::<syn::Item>(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 @@ -301,6 +337,8 @@ mod tests {
generated.cxx_qt_mod_contents[11],
tokens_to_syn::<syn::Item>(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 @@ -311,6 +349,10 @@ mod tests {
generated.cxx_qt_mod_contents[12],
tokens_to_syn::<syn::Item>(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"]
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 @@ -332,6 +374,10 @@ mod tests {
generated.cxx_qt_mod_contents[13],
tokens_to_syn::<syn::Item>(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 @@ -342,6 +388,8 @@ mod tests {
generated.cxx_qt_mod_contents[14],
tokens_to_syn::<syn::Item>(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 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
10 changes: 10 additions & 0 deletions crates/cxx-qt-gen/src/generator/rust/signals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,14 @@ pub fn generate_rust_signals(
}

// Add the Rust method using the enum to call the methods
let qobject_ident_str = qobject_idents.rust_struct.rust.to_string();
let signal_enum_ident_str = signal_enum_ident.to_string();
generated.cxx_qt_mod_contents.push(syn::parse2(quote! {
impl #cpp_class_name_rust {
#[doc = "Emit the signal from the enum "]
#[doc = #signal_enum_ident_str]
#[doc = " on the QObject "]
#[doc = #qobject_ident_str]
pub fn emit(self: Pin<&mut Self>, signal: #signal_enum_ident) {
match signal {
#(#signal_matches),*
Expand Down Expand Up @@ -214,6 +220,10 @@ mod tests {
&generated.cxx_qt_mod_contents[1],
quote! {
impl MyObjectQt {
#[doc = "Emit the signal from the enum "]
#[doc = "MySignals"]
#[doc = " on the QObject "]
#[doc = "MyObject"]
pub fn emit(self: Pin<&mut Self>, signal: MySignals) {
match signal {
MySignals::Ready {} => { self.emit_ready() },
Expand Down
Loading

0 comments on commit f4f4e84

Please sign in to comment.