Skip to content

Commit

Permalink
Move helpers to generator/mod.rs for clarity as they are only used in…
Browse files Browse the repository at this point in the history
… generation phase
  • Loading branch information
BenFordTytherington authored and ahayzen-kdab committed Jul 31, 2024
1 parent dcc2129 commit 78554ec
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 92 deletions.
3 changes: 2 additions & 1 deletion crates/cxx-qt-gen/src/generator/cpp/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//
// SPDX-License-Identifier: MIT OR Apache-2.0

use crate::generator::get_cpp_params;
use crate::{
generator::{
cpp::{
Expand All @@ -29,7 +30,7 @@ pub fn generate_cpp_methods(
let idents = QMethodName::try_from(invokable)?;
let return_cxx_ty = syn_type_to_cpp_return_type(&invokable.method.sig.output, type_names)?;

let parameters: Vec<CppNamedType> = invokable.get_cpp_params(type_names)?;
let parameters: Vec<CppNamedType> = get_cpp_params(&invokable.method, type_names)?;

let body = format!(
"{ident}({parameter_names})",
Expand Down
67 changes: 67 additions & 0 deletions crates/cxx-qt-gen/src/generator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,74 @@
//
// SPDX-License-Identifier: MIT OR Apache-2.0

use crate::generator::cpp::fragment::CppNamedType;
use crate::naming::cpp::syn_type_to_cpp_type;
use crate::naming::TypeNames;
use crate::parser::parameter::ParsedFunctionParameter;
use proc_macro2::{Ident, TokenStream};
use quote::quote;
use syn::spanned::Spanned;
use syn::{Error, FnArg, ForeignItemFn, Pat, PatIdent, PatType, Result};

pub mod cpp;
pub mod naming;
pub mod rust;
pub mod structuring;

pub fn get_params_tokens(
mutable: bool,
parameters: &[ParsedFunctionParameter],
class_name: &Ident,
) -> TokenStream {
let struct_sig = if mutable {
quote! { Pin<&mut #class_name> }
} else {
quote! { &#class_name }
};
if parameters.is_empty() {
quote! { self: #struct_sig }
} else {
let parameters = parameters
.iter()
.map(|parameter| {
let ident = &parameter.ident;
let ty = &parameter.ty;
quote! { #ident: #ty }
})
.collect::<Vec<TokenStream>>();
quote! { self: #struct_sig, #(#parameters),* }
}
}

/// Returns a vector of the names and types ([CppNamedType] of the parameters of this method, used in cpp generation step
pub fn get_cpp_params(method: &ForeignItemFn, type_names: &TypeNames) -> Result<Vec<CppNamedType>> {
method
.sig
.inputs
.iter()
.map(|input| {
// Match parameters to extract their idents
if let FnArg::Typed(PatType { pat, ty, .. }) = input {
let ident = if let Pat::Ident(PatIdent { ident, .. }) = &**pat {
ident
} else {
return Err(Error::new(input.span(), "Unknown pattern for type"));
};

// If the name of the argument is self then ignore,
// as this is likely the self: Pin<T>
if ident == "self" {
Ok(None)
} else {
Ok(Some(CppNamedType {
ident: ident.to_string(),
ty: syn_type_to_cpp_type(ty, type_names)?,
}))
}
} else {
Ok(None)
}
})
.filter_map(|result| result.map_or_else(|e| Some(Err(e)), |v| v.map(Ok)))
.collect()
}
7 changes: 6 additions & 1 deletion crates/cxx-qt-gen/src/generator/rust/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//
// SPDX-License-Identifier: MIT OR Apache-2.0

use crate::generator::get_params_tokens;
use crate::{
generator::{
naming::{method::QMethodName, qobject::QObjectNames},
Expand All @@ -28,7 +29,11 @@ pub fn generate_rust_methods(
// TODO: once we aren't using qobject::T in the extern "RustQt"
// we can just pass through the original ExternFn block and add the attribute?

let parameter_signatures = invokable.get_params_tokens(cpp_class_name_rust);
let parameter_signatures = get_params_tokens(
invokable.mutable,
&invokable.parameters,
cpp_class_name_rust,
);

let return_type = &invokable.method.sig.output;

Expand Down
4 changes: 3 additions & 1 deletion crates/cxx-qt-gen/src/generator/rust/signals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//
// SPDX-License-Identifier: MIT OR Apache-2.0

use crate::generator::get_params_tokens;
use crate::{
generator::{
naming::{
Expand Down Expand Up @@ -91,7 +92,8 @@ pub fn generate_rust_signal(
let doc_comments = &signal.docs;

let signal_ident_cpp = idents.name.rust_unqualified();
let parameter_signatures = signal.get_params_tokens(rust_class_name);
let parameter_signatures =
get_params_tokens(signal.mutable, &signal.parameters, rust_class_name);

let return_type = &signal.method.sig.output;

Expand Down
64 changes: 1 addition & 63 deletions crates/cxx-qt-gen/src/parser/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,13 @@
//
// SPDX-License-Identifier: MIT OR Apache-2.0

use crate::generator::cpp::fragment::CppNamedType;
use crate::naming::cpp::syn_type_to_cpp_type;
use crate::naming::TypeNames;
use crate::{
naming::Name,
parser::parameter::ParsedFunctionParameter,
syntax::{attribute::attribute_take_path, foreignmod, safety::Safety, types},
};
use proc_macro2::TokenStream;
use quote::quote;
use std::collections::HashSet;
use syn::{spanned::Spanned, Error, FnArg, ForeignItemFn, Ident, Pat, PatIdent, PatType, Result};
use syn::{spanned::Spanned, Error, ForeignItemFn, Ident, Result};

#[cfg(test)]
use quote::format_ident;
Expand Down Expand Up @@ -111,63 +106,6 @@ impl ParsedMethod {
})
}

/// Returns a [TokenStream] of the methods parameters, which can be used in generation stage
/// class_name is the rust class name which this method is defined for
pub fn get_params_tokens(&self, class_name: &Ident) -> TokenStream {
let struct_sig = if self.mutable {
quote! { Pin<&mut #class_name> }
} else {
quote! { &#class_name }
};
if self.parameters.is_empty() {
quote! { self: #struct_sig }
} else {
let parameters = self
.parameters
.iter()
.map(|parameter| {
let ident = &parameter.ident;
let ty = &parameter.ty;
quote! { #ident: #ty }
})
.collect::<Vec<TokenStream>>();
quote! { self: #struct_sig, #(#parameters),* }
}
}

/// Returns a vector of the names and types ([CppNamedType] of the parameters of this method, used in cpp generation step
pub fn get_cpp_params(&self, type_names: &TypeNames) -> Result<Vec<CppNamedType>> {
self.method
.sig
.inputs
.iter()
.map(|input| {
// Match parameters to extract their idents
if let FnArg::Typed(PatType { pat, ty, .. }) = input {
let ident = if let Pat::Ident(PatIdent { ident, .. }) = &**pat {
ident
} else {
return Err(Error::new(input.span(), "Unknown pattern for type"));
};

// If the name of the argument is self then ignore,
// as this is likely the self: Pin<T>
if ident == "self" {
Ok(None)
} else {
Ok(Some(CppNamedType {
ident: ident.to_string(),
ty: syn_type_to_cpp_type(ty, type_names)?,
}))
}
} else {
Ok(None)
}
})
.filter_map(|result| result.map_or_else(|e| Some(Err(e)), |v| v.map(Ok)))
.collect()
}

#[cfg(test)]
pub fn from_method_and_params(
method: &ForeignItemFn,
Expand Down
26 changes: 0 additions & 26 deletions crates/cxx-qt-gen/src/parser/signals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ use crate::{
attribute::attribute_take_path, foreignmod, path::path_compare_str, safety::Safety, types,
},
};
use proc_macro2::TokenStream;
use quote::quote;
use syn::{spanned::Spanned, Attribute, Error, ForeignItemFn, Ident, Result, Visibility};

#[cfg(test)]
Expand Down Expand Up @@ -132,30 +130,6 @@ impl ParsedSignal {
docs,
})
}

/// Returns a [TokenStream] of the signals parameters, which can be used in generation stage
/// class_name is the rust class name which this method is defined for
pub fn get_params_tokens(&self, class_name: &Ident) -> TokenStream {
let struct_sig = if self.mutable {
quote! { Pin<&mut #class_name> }
} else {
quote! { &#class_name }
};
if self.parameters.is_empty() {
quote! { self: #struct_sig }
} else {
let parameters = self
.parameters
.iter()
.map(|parameter| {
let ident = &parameter.ident;
let ty = &parameter.ty;
quote! { #ident: #ty }
})
.collect::<Vec<TokenStream>>();
quote! { self: #struct_sig, #(#parameters),* }
}
}
}

#[cfg(test)]
Expand Down

0 comments on commit 78554ec

Please sign in to comment.