From 95aaef80bc2c8c2c688f3b51ebcd3230213f47a0 Mon Sep 17 00:00:00 2001 From: Kozlov Maxim Date: Mon, 6 Nov 2023 03:22:51 +0600 Subject: [PATCH] finished moving functions to collectors --- .../collectors/call_as_func.rs | 63 +++++++ .../collectors/call_as_proc.rs | 56 +++++++ .../collectors/find_method.rs | 6 +- .../collectors/get_method_name.rs | 52 ++++++ .../collectors/get_n_methods.rs | 40 +++++ .../collectors/get_n_params.rs | 53 ++++++ .../collectors/get_param_def_value.rs | 94 +++++++++++ .../collectors/has_ret_val.rs | 49 ++++++ .../src/function_processing/collectors/mod.rs | 18 +- native_api_1c_macro/src/lib.rs | 156 ++---------------- 10 files changed, 444 insertions(+), 143 deletions(-) create mode 100644 native_api_1c_macro/src/function_processing/collectors/call_as_func.rs create mode 100644 native_api_1c_macro/src/function_processing/collectors/call_as_proc.rs create mode 100644 native_api_1c_macro/src/function_processing/collectors/get_method_name.rs create mode 100644 native_api_1c_macro/src/function_processing/collectors/get_n_methods.rs create mode 100644 native_api_1c_macro/src/function_processing/collectors/get_n_params.rs create mode 100644 native_api_1c_macro/src/function_processing/collectors/get_param_def_value.rs create mode 100644 native_api_1c_macro/src/function_processing/collectors/has_ret_val.rs diff --git a/native_api_1c_macro/src/function_processing/collectors/call_as_func.rs b/native_api_1c_macro/src/function_processing/collectors/call_as_func.rs new file mode 100644 index 0000000..2b946e9 --- /dev/null +++ b/native_api_1c_macro/src/function_processing/collectors/call_as_func.rs @@ -0,0 +1,63 @@ +use proc_macro2::TokenStream; +use quote::quote; +use syn::Ident; + +use crate::function_processing::{generate::func_call_tkn, FuncDesc, ReturnType}; + +use super::{empty_func_collector_error, FunctionCollector}; + +pub struct CallAsFuncCollector { + generated: Result, +} + +impl Default for CallAsFuncCollector { + fn default() -> Self { + Self { + generated: Err(empty_func_collector_error()), + } + } +} + +impl<'a> FromIterator<(usize, &'a FuncDesc)> for CallAsFuncCollector { + fn from_iter>(iter: T) -> Self { + let mut call_as_func_body = TokenStream::new(); + + for (func_index, func_desc) in iter { + let has_ret_val = !matches!(func_desc.return_value.ty, ReturnType::None); + if !has_ret_val { + continue; + } + + let return_val_ident = Ident::new("val", proc_macro2::Span::call_site()); + let call_func = func_call_tkn(func_desc, Some(&return_val_ident)); + call_as_func_body.extend(quote! { + if method_num == #func_index { + #call_func + return true; + }; + }); + } + + let call_as_func_definition = quote! { + fn call_as_func( + &mut self, + method_num: usize, + params: &mut [native_api_1c::native_api_1c_core::ffi::provided_types::ParamValue], + val: native_api_1c::native_api_1c_core::ffi::provided_types::ReturnValue, + ) -> bool { + #call_as_func_body + false + } + }; + + Self { + generated: Ok(call_as_func_definition), + } + } +} + +impl FunctionCollector<'_> for CallAsFuncCollector { + fn release(self) -> Result { + self.generated + } +} diff --git a/native_api_1c_macro/src/function_processing/collectors/call_as_proc.rs b/native_api_1c_macro/src/function_processing/collectors/call_as_proc.rs new file mode 100644 index 0000000..14616c4 --- /dev/null +++ b/native_api_1c_macro/src/function_processing/collectors/call_as_proc.rs @@ -0,0 +1,56 @@ +use proc_macro2::TokenStream; +use quote::quote; + +use crate::function_processing::{generate::func_call_tkn, FuncDesc}; + +use super::{empty_func_collector_error, FunctionCollector}; + +pub struct CallAsProcCollector { + generated: Result, +} + +impl Default for CallAsProcCollector { + fn default() -> Self { + Self { + generated: Err(empty_func_collector_error()), + } + } +} + +impl<'a> FromIterator<(usize, &'a FuncDesc)> for CallAsProcCollector { + fn from_iter>(iter: T) -> Self { + let mut call_as_proc_body = TokenStream::new(); + + for (func_index, func_desc) in iter { + let call_proc = func_call_tkn(func_desc, None); + + call_as_proc_body.extend(quote! { + if method_num == #func_index { + #call_proc + return true; + }; + }); + } + + let call_as_proc_definition = quote! { + fn call_as_proc( + &mut self, + method_num: usize, + params: &mut [native_api_1c::native_api_1c_core::ffi::provided_types::ParamValue], + ) -> bool { + #call_as_proc_body + false + } + }; + + Self { + generated: Ok(call_as_proc_definition), + } + } +} + +impl FunctionCollector<'_> for CallAsProcCollector { + fn release(self) -> Result { + self.generated + } +} diff --git a/native_api_1c_macro/src/function_processing/collectors/find_method.rs b/native_api_1c_macro/src/function_processing/collectors/find_method.rs index 4b424ae..b0a09b9 100644 --- a/native_api_1c_macro/src/function_processing/collectors/find_method.rs +++ b/native_api_1c_macro/src/function_processing/collectors/find_method.rs @@ -3,7 +3,7 @@ use quote::quote; use crate::function_processing::FuncDesc; -use super::empty_func_collector_error; +use super::{empty_func_collector_error, FunctionCollector}; pub struct FindMethodCollector { generated: Result, @@ -44,8 +44,8 @@ impl<'a> FromIterator<(usize, &'a FuncDesc)> for FindMethodCollector { } } -impl FindMethodCollector { - pub fn generated(self) -> Result { +impl FunctionCollector<'_> for FindMethodCollector { + fn release(self) -> Result { self.generated } } diff --git a/native_api_1c_macro/src/function_processing/collectors/get_method_name.rs b/native_api_1c_macro/src/function_processing/collectors/get_method_name.rs new file mode 100644 index 0000000..0e73173 --- /dev/null +++ b/native_api_1c_macro/src/function_processing/collectors/get_method_name.rs @@ -0,0 +1,52 @@ +use proc_macro2::TokenStream; +use quote::quote; + +use crate::function_processing::FuncDesc; + +use super::{empty_func_collector_error, FunctionCollector}; + +pub struct GetMethodNameCollector { + generated: Result, +} + +impl Default for GetMethodNameCollector { + fn default() -> Self { + Self { + generated: Err(empty_func_collector_error()), + } + } +} + +impl<'a> FromIterator<(usize, &'a FuncDesc)> for GetMethodNameCollector { + fn from_iter>(iter: T) -> Self { + let mut get_func_name_body = TokenStream::new(); + + for (func_index, func_desc) in iter { + let name_literal = func_desc.name_literal.clone(); + let name_ru_literal = func_desc.name_ru_literal.clone(); + + get_func_name_body.extend(quote! { + #get_func_name_body + if num == #func_index && alias == 0 { return Some(native_api_1c::native_api_1c_core::ffi::string_utils::os_string_nil(#name_literal).into()) }; + if num == #func_index { return Some(native_api_1c::native_api_1c_core::ffi::string_utils::os_string_nil(#name_ru_literal).into()) }; + }); + } + + let get_func_name_definition = quote! { + fn get_method_name(&self, num: usize, alias: usize) -> Option> { + #get_func_name_body + None + } + }; + + Self { + generated: Ok(get_func_name_definition), + } + } +} + +impl FunctionCollector<'_> for GetMethodNameCollector { + fn release(self) -> Result { + self.generated + } +} diff --git a/native_api_1c_macro/src/function_processing/collectors/get_n_methods.rs b/native_api_1c_macro/src/function_processing/collectors/get_n_methods.rs new file mode 100644 index 0000000..18f9d87 --- /dev/null +++ b/native_api_1c_macro/src/function_processing/collectors/get_n_methods.rs @@ -0,0 +1,40 @@ +use proc_macro2::TokenStream; +use quote::quote; + +use crate::function_processing::FuncDesc; + +use super::{empty_func_collector_error, FunctionCollector}; + +pub struct GetNMethodsCollector { + generated: Result, +} + +impl Default for GetNMethodsCollector { + fn default() -> Self { + Self { + generated: Err(empty_func_collector_error()), + } + } +} + +impl<'a> FromIterator<(usize, &'a FuncDesc)> for GetNMethodsCollector { + fn from_iter>(iter: T) -> Self { + let number_of_func = iter.into_iter().count(); + + let find_method_definition = quote! { + fn get_n_methods(&self) -> usize { + #number_of_func + } + }; + + Self { + generated: Ok(find_method_definition), + } + } +} + +impl FunctionCollector<'_> for GetNMethodsCollector { + fn release(self) -> Result { + self.generated + } +} diff --git a/native_api_1c_macro/src/function_processing/collectors/get_n_params.rs b/native_api_1c_macro/src/function_processing/collectors/get_n_params.rs new file mode 100644 index 0000000..d7603ab --- /dev/null +++ b/native_api_1c_macro/src/function_processing/collectors/get_n_params.rs @@ -0,0 +1,53 @@ +use proc_macro2::TokenStream; +use quote::quote; + +use crate::function_processing::{FuncDesc, ParamType}; + +use super::{empty_func_collector_error, FunctionCollector}; + +pub struct GetNParamsCollector { + generated: Result, +} + +impl Default for GetNParamsCollector { + fn default() -> Self { + Self { + generated: Err(empty_func_collector_error()), + } + } +} + +impl<'a> FromIterator<(usize, &'a FuncDesc)> for GetNParamsCollector { + fn from_iter>(iter: T) -> Self { + let mut get_n_params_body = TokenStream::new(); + + for (func_index, func_desc) in iter { + let number_of_params = func_desc + .params + .iter() + .filter(|p| !matches!(p.ty, ParamType::SelfType)) + .count(); + get_n_params_body.extend(quote! { + #get_n_params_body + if num == #func_index { return #number_of_params }; + }); + } + + let find_method_definition = quote! { + fn get_n_params(&self, num: usize) -> usize { + #get_n_params_body + 0 + } + }; + + Self { + generated: Ok(find_method_definition), + } + } +} + +impl FunctionCollector<'_> for GetNParamsCollector { + fn release(self) -> Result { + self.generated + } +} diff --git a/native_api_1c_macro/src/function_processing/collectors/get_param_def_value.rs b/native_api_1c_macro/src/function_processing/collectors/get_param_def_value.rs new file mode 100644 index 0000000..005333f --- /dev/null +++ b/native_api_1c_macro/src/function_processing/collectors/get_param_def_value.rs @@ -0,0 +1,94 @@ +use proc_macro2::TokenStream; +use quote::{quote, ToTokens}; + +use crate::{ + common_generators::{param_ty_to_ffi_return, SettableTypes}, + function_processing::FuncDesc, + utils::macros::tkn_err_inner, +}; + +use super::{empty_func_collector_error, FunctionCollector}; + +pub struct GetParamDefValueCollector { + generated: Result, +} + +impl Default for GetParamDefValueCollector { + fn default() -> Self { + Self { + generated: Err(empty_func_collector_error()), + } + } +} + +impl<'a> FromIterator<(usize, &'a FuncDesc)> for GetParamDefValueCollector { + fn from_iter>(iter: T) -> Self { + let mut get_param_def_value_body = TokenStream::new(); + + for (func_index, func_desc) in iter { + let mut this_get_param_def_value_body = quote! {}; + for (i, arg_desc) in func_desc.params.iter().enumerate() { + match &arg_desc.default { + Some(expr) => { + let prop_settable: SettableTypes = + match (&arg_desc.ty).try_into().map_err(|_| { + tkn_err_inner!( + "Incorrectly attempted to convert type to settable", + &func_desc.ident.span() + ) + }) { + Ok(st) => st, + Err(err) => { + return Self { + generated: Err(err), + } + } + }; + let value_setter = param_ty_to_ffi_return( + &prop_settable, + quote! { value }, + expr.into_token_stream(), + ); + this_get_param_def_value_body = quote! { + #this_get_param_def_value_body + if param_num == #i { + #value_setter; + return true; + } + } + } + None => {} + } + } + get_param_def_value_body = quote! { + #get_param_def_value_body + if method_num == #func_index { + #this_get_param_def_value_body + return false; + }; + }; + } + + let find_method_definition = quote! { + fn get_param_def_value( + &self, + method_num: usize, + param_num: usize, + value: native_api_1c::native_api_1c_core::ffi::provided_types::ReturnValue, + ) -> bool { + #get_param_def_value_body + false + } + }; + + Self { + generated: Ok(find_method_definition), + } + } +} + +impl FunctionCollector<'_> for GetParamDefValueCollector { + fn release(self) -> Result { + self.generated + } +} diff --git a/native_api_1c_macro/src/function_processing/collectors/has_ret_val.rs b/native_api_1c_macro/src/function_processing/collectors/has_ret_val.rs new file mode 100644 index 0000000..5783898 --- /dev/null +++ b/native_api_1c_macro/src/function_processing/collectors/has_ret_val.rs @@ -0,0 +1,49 @@ +use proc_macro2::TokenStream; +use quote::quote; + +use crate::function_processing::{FuncDesc, ReturnType}; + +use super::{empty_func_collector_error, FunctionCollector}; + +pub struct HasReturnValueCollector { + generated: Result, +} + +impl Default for HasReturnValueCollector { + fn default() -> Self { + Self { + generated: Err(empty_func_collector_error()), + } + } +} + +impl<'a> FromIterator<(usize, &'a FuncDesc)> for HasReturnValueCollector { + fn from_iter>(iter: T) -> Self { + let mut has_ret_val_body = TokenStream::new(); + + for (func_index, func_desc) in iter { + let has_ret_val = !matches!(func_desc.return_value.ty, ReturnType::None); + has_ret_val_body.extend(quote! { + #has_ret_val_body + if method_num == #func_index { return #has_ret_val }; + }); + } + + let has_ret_val_definition = quote! { + fn has_ret_val(&self, method_num: usize) -> bool { + #has_ret_val_body + false + } + }; + + Self { + generated: Ok(has_ret_val_definition), + } + } +} + +impl FunctionCollector<'_> for HasReturnValueCollector { + fn release(self) -> Result { + self.generated + } +} diff --git a/native_api_1c_macro/src/function_processing/collectors/mod.rs b/native_api_1c_macro/src/function_processing/collectors/mod.rs index 81ee328..564fe96 100644 --- a/native_api_1c_macro/src/function_processing/collectors/mod.rs +++ b/native_api_1c_macro/src/function_processing/collectors/mod.rs @@ -3,10 +3,26 @@ use proc_macro2::TokenStream; use super::FuncDesc; use crate::utils::macros::tkn_err_inner; +pub mod call_as_func; +pub mod call_as_proc; pub mod find_method; +pub mod get_method_name; +pub mod get_n_methods; +pub mod get_n_params; +pub mod get_param_def_value; +pub mod has_ret_val; + +pub use call_as_func::CallAsFuncCollector; +pub use call_as_proc::CallAsProcCollector; +pub use find_method::FindMethodCollector; +pub use get_method_name::GetMethodNameCollector; +pub use get_n_methods::GetNMethodsCollector; +pub use get_n_params::GetNParamsCollector; +pub use get_param_def_value::GetParamDefValueCollector; +pub use has_ret_val::HasReturnValueCollector; pub trait FunctionCollector<'a>: FromIterator<(usize, &'a FuncDesc)> + Default { - fn release(&self) -> Result; + fn release(self) -> Result; } pub fn empty_func_collector_error() -> darling::Error { diff --git a/native_api_1c_macro/src/lib.rs b/native_api_1c_macro/src/lib.rs index d5e0e33..2ac9cc6 100644 --- a/native_api_1c_macro/src/lib.rs +++ b/native_api_1c_macro/src/lib.rs @@ -1,12 +1,9 @@ use common_generators::{param_ty_to_ffi_return, SettableTypes}; -use proc_macro2::{Ident, TokenStream}; -use quote::{quote, ToTokens}; +use proc_macro2::TokenStream; +use quote::quote; use syn::{parse_macro_input, DeriveInput}; -use function_processing::{ - collectors::find_method::FindMethodCollector, generate::func_call_tkn, parse::parse_functions, - ParamType, ReturnType, -}; +use function_processing::{collectors::*, parse::parse_functions}; use props_processing::{generate::param_ty_to_ffi_set, parse::parse_props}; use utils::{ macros::{tkn_err, tkn_err_inner}, @@ -55,7 +52,6 @@ fn build_impl_block(input: &DeriveInput) -> Result Result().generated()?; - - let mut get_func_name_body = quote! {}; - let mut has_ret_val_body = quote! {}; - let mut get_n_params_body = quote! {}; - let mut call_as_proc_body = quote! {}; - let mut call_as_func_body = quote! {}; - let mut get_param_def_value_body = quote! {}; - - for func in &functions { - let name_literal = str_literal_token(&func.name, struct_ident)?; - let name_ru_literal = str_literal_token(&func.name_ru, struct_ident)?; - let has_ret_val = !matches!(func.return_value.ty, ReturnType::None); - let func_index = functions.iter().position(|p| p.name == func.name).unwrap(); - let number_of_params = func - .params - .iter() - .filter(|p| !matches!(p.ty, ParamType::SelfType)) - .count(); - - get_func_name_body = quote! { - #get_func_name_body - if num == #func_index && alias == 0 { return Some(native_api_1c::native_api_1c_core::ffi::string_utils::os_string_nil(#name_literal).into()) }; - if num == #func_index { return Some(native_api_1c::native_api_1c_core::ffi::string_utils::os_string_nil(#name_ru_literal).into()) }; - }; - has_ret_val_body = quote! { - #has_ret_val_body - if method_num == #func_index { return #has_ret_val }; - }; - get_n_params_body = quote! { - #get_n_params_body - if num == #func_index { return #number_of_params }; - }; - - let call_proc = func_call_tkn(func, None); - call_as_proc_body = quote! { - #call_as_proc_body - if method_num == #func_index { - #call_proc - return true; - }; - }; - - if has_ret_val { - let return_val_ident = Ident::new("val", proc_macro2::Span::call_site()); - let call_func = func_call_tkn(func, Some(&return_val_ident)); - call_as_func_body = quote! { - #call_as_func_body - if method_num == #func_index { - #call_func - return true; - }; - }; - } - - let mut this_get_param_def_value_body = quote! {}; - for (i, arg_desc) in func.params.iter().enumerate() { - match &arg_desc.default { - Some(expr) => { - let prop_settable: SettableTypes = (&arg_desc.ty).try_into().map_err(|_| { - tkn_err_inner!( - "Incorrectly attempted to convert type to settable", - &func.ident.span() - ) - })?; - let value_setter = param_ty_to_ffi_return( - &prop_settable, - quote! { value }, - expr.into_token_stream(), - ); - this_get_param_def_value_body = quote! { - #this_get_param_def_value_body - if param_num == #i { - #value_setter; - return true; - } - } - } - None => {} - } - } - get_param_def_value_body = quote! { - #get_param_def_value_body - if method_num == #func_index { - #this_get_param_def_value_body - return false; - }; - }; - } + let func_definitions = [ + fi.clone().collect::().release()?, + fi.clone().collect::().release()?, + fi.clone().collect::().release()?, + fi.clone().collect::().release()?, + fi.clone().collect::().release()?, + fi.clone().collect::().release()?, + fi.clone().collect::().release()?, + fi.clone() + .collect::() + .release()?, + ]; let result = quote! { impl native_api_1c::native_api_1c_core::interface::AddInWrapper for #struct_ident { @@ -258,48 +177,7 @@ fn build_impl_block(input: &DeriveInput) -> Result usize { - #number_of_func - } - fn get_method_name(&self, num: usize, alias: usize) -> Option> { - #get_func_name_body - None - } - fn get_n_params(&self, num: usize) -> usize { - #get_n_params_body - 0 - } - fn get_param_def_value( - &self, - method_num: usize, - param_num: usize, - value: native_api_1c::native_api_1c_core::ffi::provided_types::ReturnValue, - ) -> bool { - #get_param_def_value_body - false - } - fn has_ret_val(&self, method_num: usize) -> bool { - #has_ret_val_body - false - } - fn call_as_proc( - &mut self, - method_num: usize, - params: &mut [native_api_1c::native_api_1c_core::ffi::provided_types::ParamValue], - ) -> bool { - #call_as_proc_body - false - } - fn call_as_func( - &mut self, - method_num: usize, - params: &mut [native_api_1c::native_api_1c_core::ffi::provided_types::ParamValue], - val: native_api_1c::native_api_1c_core::ffi::provided_types::ReturnValue, - ) -> bool { - #call_as_func_body - false - } + #(#func_definitions)* fn set_locale(&mut self, loc: &[u16]) { } fn set_user_interface_language_code(&mut self, lang: &[u16]) {