Skip to content

Commit

Permalink
cxx-qt-gen: refactor MethodFields
Browse files Browse the repository at this point in the history
* Introduce method_fields to 3 structs
* Update mocking functions and clean up imports
* Simplify generation for signals using the improved parse function
* Move common method field into MethodFields, refactoring parse functions
* Add comment to ParsedMethod to indicate why it doesn't include a docs field like the other 2 method types
  • Loading branch information
BenFordTytherington authored Sep 5, 2024
1 parent 0efcd6c commit 86d00e5
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 188 deletions.
16 changes: 3 additions & 13 deletions crates/cxx-qt-gen/src/generator/cpp/property/signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use syn::ForeignItemFn;

use crate::naming::Name;
use crate::syntax::attribute::attribute_take_path;
use crate::syntax::safety::Safety;
use crate::{
generator::naming::property::{NameState, QPropertyNames},
parser::signals::ParsedSignal,
Expand All @@ -19,23 +19,13 @@ pub fn generate(idents: &QPropertyNames, qobject_name: &Name) -> Option<ParsedSi
let cpp_class_rust = &qobject_name.rust_unqualified();
let notify_cpp = notify.cxx_unqualified();
let notify_rust = notify.rust_unqualified();
let mut method: ForeignItemFn = syn::parse_quote! {
let method: ForeignItemFn = syn::parse_quote! {
#[doc = "Notify for the Q_PROPERTY"]
#[cxx_name = #notify_cpp]
fn #notify_rust(self: Pin<&mut #cpp_class_rust>);
};

let mut docs = vec![];
while let Some(doc) = attribute_take_path(&mut method.attrs, &["doc"]) {
docs.push(doc);
}

Some(ParsedSignal::from_property_method(
method,
notify.clone(),
qobject_name.rust_unqualified().clone(),
docs,
))
Some(ParsedSignal::parse(method, Safety::Safe).unwrap())
} else {
None
}
Expand Down
10 changes: 5 additions & 5 deletions crates/cxx-qt-gen/src/generator/cpp/signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ mod tests {
let method: ForeignItemFn = parse_quote! {
fn data_changed(self: Pin<&mut MyObject>, trivial: i32, opaque: UniquePtr<QColor>);
};
let signal = ParsedSignal::mock_with_method(&method);
let signal = ParsedSignal::mock(&method);
let signals = vec![&signal];
let qobject_idents = create_qobjectname();

Expand Down Expand Up @@ -304,7 +304,7 @@ mod tests {
let method: ForeignItemFn = parse_quote! {
fn data_changed(self: Pin<&mut MyObject>, mapped: A);
};
let signal = ParsedSignal::mock_with_method(&method);
let signal = ParsedSignal::mock(&method);
let signals = vec![&signal];
let qobject_idents = create_qobjectname();

Expand Down Expand Up @@ -384,7 +384,7 @@ mod tests {
};
let signal = ParsedSignal {
inherit: true,
..ParsedSignal::mock_with_method(&method)
..ParsedSignal::mock(&method)
};

let signals = vec![&signal];
Expand Down Expand Up @@ -459,7 +459,7 @@ mod tests {
};
let signal = ParsedSignal {
inherit: true,
..ParsedSignal::mock_with_method(&method)
..ParsedSignal::mock(&method)
};

let mut type_names = TypeNames::default();
Expand Down Expand Up @@ -537,7 +537,7 @@ mod tests {
};
let signal = ParsedSignal {
inherit: true,
..ParsedSignal::mock_with_method(&method)
..ParsedSignal::mock(&method)
};

let mut type_names = TypeNames::default();
Expand Down
2 changes: 1 addition & 1 deletion crates/cxx-qt-gen/src/generator/naming/property.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use quote::format_ident;
use syn::{Ident, Result};

use crate::generator::structuring::StructuredQObject;
use std::ops::Deref;
use core::ops::Deref;

#[derive(Debug)]
pub enum NameState {
Expand Down
4 changes: 2 additions & 2 deletions crates/cxx-qt-gen/src/generator/naming/signals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ mod tests {
let method = parse_quote! {
fn data_changed(self: Pin<&mut MyObject>);
};
let qsignal = ParsedSignal::mock_with_method(&method);
let qsignal = ParsedSignal::mock(&method);

let names = QSignalNames::from(&qsignal);
assert_eq!(names.name.cxx_unqualified(), "dataChanged");
Expand All @@ -132,7 +132,7 @@ mod tests {
#[cxx_name = "baseName"]
fn existing_signal(self: Pin<&mut MyObject>);
};
let qsignal = ParsedSignal::mock_with_method(&method);
let qsignal = ParsedSignal::mock(&method);

let names = QSignalNames::from(&qsignal);
assert_eq!(names.name.cxx_unqualified(), "baseName");
Expand Down
16 changes: 3 additions & 13 deletions crates/cxx-qt-gen/src/generator/rust/property/signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

use syn::ForeignItemFn;

use crate::syntax::attribute::attribute_take_path;
use crate::syntax::safety::Safety;
use crate::{
generator::naming::{
property::{NameState, QPropertyNames},
Expand All @@ -22,23 +22,13 @@ pub fn generate(idents: &QPropertyNames, qobject_names: &QObjectNames) -> Option
let notify_rust = notify.rust_unqualified();
let notify_cpp_str = notify.cxx_unqualified();

let mut method: ForeignItemFn = syn::parse_quote! {
let method: ForeignItemFn = syn::parse_quote! {
#[doc = "Notify for the Q_PROPERTY"]
#[cxx_name = #notify_cpp_str]
fn #notify_rust(self: Pin<&mut #cpp_class_rust>);
};

let mut docs = vec![];
while let Some(doc) = attribute_take_path(&mut method.attrs, &["doc"]) {
docs.push(doc);
}

Some(ParsedSignal::from_property_method(
method,
notify.clone(),
qobject_names.name.rust_unqualified().clone(),
docs,
))
Some(ParsedSignal::parse(method, Safety::Safe).unwrap())
} else {
None
}
Expand Down
20 changes: 11 additions & 9 deletions crates/cxx-qt-gen/src/generator/rust/signals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ mod tests {
use super::*;

use crate::generator::naming::qobject::tests::create_qobjectname;
use crate::parser::method::MethodFields;
use crate::tests::assert_tokens_eq;
use quote::{format_ident, quote};
use syn::{parse_quote, ForeignItemFn, Item};
Expand Down Expand Up @@ -378,7 +379,7 @@ mod tests {
let method: ForeignItemFn = parse_quote! {
fn ready(self: Pin<&mut MyObject>);
};
let qsignal = ParsedSignal::mock_with_method(&method);
let qsignal = ParsedSignal::mock(&method);

let type_names = TypeNames::mock();

Expand Down Expand Up @@ -412,7 +413,7 @@ mod tests {
let method: ForeignItemFn = parse_quote! {
fn data_changed(self: Pin<&mut MyObject>, trivial: i32, opaque: UniquePtr<QColor>);
};
let qsignal = ParsedSignal::mock_with_method(&method);
let qsignal = ParsedSignal::mock(&method);
let qobject_names = create_qobjectname();

let mut type_names = TypeNames::mock();
Expand Down Expand Up @@ -553,10 +554,7 @@ mod tests {
let method = parse_quote! {
unsafe fn unsafe_signal(self: Pin<&mut MyObject>, param: *mut T);
};
let qsignal = ParsedSignal {
safe: false,
..ParsedSignal::mock_with_method(&method)
};
let qsignal = ParsedSignal::mock(&method);
let qobject_names = create_qobjectname();

let mut type_names = TypeNames::mock();
Expand Down Expand Up @@ -700,7 +698,7 @@ mod tests {
};
let qsignal = ParsedSignal {
inherit: true,
..ParsedSignal::mock_with_method(&method)
..ParsedSignal::mock(&method)
};
let qobject_names = create_qobjectname();

Expand Down Expand Up @@ -838,10 +836,14 @@ mod tests {
let method: ForeignItemFn = parse_quote! {
fn ready(self: Pin<&mut MyObject>);
};
let mock = ParsedSignal::mock(&method);
let qsignal = ParsedSignal {
name: Name::new(format_ident!("ready")),
method_fields: MethodFields {
name: Name::new(format_ident!("ready")),
..mock.method_fields
},
private: true,
..ParsedSignal::mock_with_method(&method)
..mock
};

let type_names = TypeNames::mock();
Expand Down
50 changes: 18 additions & 32 deletions crates/cxx-qt-gen/src/parser/inherit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,15 @@

use crate::parser::method::MethodFields;
use crate::parser::{check_safety, separate_docs};
use crate::{
naming::Name,
parser::parameter::ParsedFunctionParameter,
syntax::{attribute::attribute_take_path, safety::Safety},
};
use crate::syntax::{attribute::attribute_take_path, safety::Safety};
use core::ops::Deref;
use quote::format_ident;
use syn::{Attribute, ForeignItemFn, Ident, Result};

/// Describes a method found in an extern "RustQt" with #[inherit]
pub struct ParsedInheritedMethod {
/// The original [syn::ForeignItemFn] of the inherited method declaration
pub method: ForeignItemFn,
/// The type of the self argument
pub qobject_ident: Ident,
/// whether the inherited method is marked as mutable
pub mutable: bool,
/// Whether the method is safe to call.
pub safe: bool,
/// the parameters of the method, without the `self` argument
pub parameters: Vec<ParsedFunctionParameter>,
/// the name of the function in Rust, as well as C++
pub name: Name,
/// The common fields which are available on all callable types
pub method_fields: MethodFields,
/// All the docs (each line) of the inherited method
pub docs: Vec<Attribute>,
}
Expand All @@ -36,24 +23,15 @@ impl ParsedInheritedMethod {
check_safety(&method, &safety)?;

let docs = separate_docs(&mut method);
let invokable_fields = MethodFields::parse(&method, docs)?;
let mut fields = MethodFields::parse(method)?;

// This block seems unnecessary but since attrs are passed through on generator/rust/inherit.rs a duplicate attr would occur without it
attribute_take_path(&mut method.attrs, &["cxx_name"]);
attribute_take_path(&mut fields.method.attrs, &["cxx_name"]);

Ok(Self::from_invokable_fields(invokable_fields, method))
}

fn from_invokable_fields(fields: MethodFields, method: ForeignItemFn) -> Self {
Self {
method,
qobject_ident: fields.qobject_ident,
mutable: fields.mutable,
safe: fields.safe,
parameters: fields.parameters,
name: fields.name,
docs: fields.docs,
}
Ok(Self {
method_fields: fields,
docs,
})
}

/// the name of the wrapper function in C++
Expand All @@ -62,6 +40,14 @@ impl ParsedInheritedMethod {
}
}

impl Deref for ParsedInheritedMethod {
type Target = MethodFields;

fn deref(&self) -> &Self::Target {
&self.method_fields
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
Loading

0 comments on commit 86d00e5

Please sign in to comment.