1
0
mirror of https://github.com/Sebekerga/native_api_1c.git synced 2025-06-14 23:45:13 +02:00

finished moving functions to collectors

This commit is contained in:
Kozlov Maxim
2023-11-06 03:22:51 +06:00
parent 2b47a8d944
commit 95aaef80bc
10 changed files with 444 additions and 143 deletions

View File

@ -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<TokenStream, darling::Error>,
}
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<T: IntoIterator<Item = (usize, &'a FuncDesc)>>(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<TokenStream, darling::Error> {
self.generated
}
}

View File

@ -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<TokenStream, darling::Error>,
}
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<T: IntoIterator<Item = (usize, &'a FuncDesc)>>(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<TokenStream, darling::Error> {
self.generated
}
}

View File

@ -3,7 +3,7 @@ use quote::quote;
use crate::function_processing::FuncDesc; use crate::function_processing::FuncDesc;
use super::empty_func_collector_error; use super::{empty_func_collector_error, FunctionCollector};
pub struct FindMethodCollector { pub struct FindMethodCollector {
generated: Result<TokenStream, darling::Error>, generated: Result<TokenStream, darling::Error>,
@ -44,8 +44,8 @@ impl<'a> FromIterator<(usize, &'a FuncDesc)> for FindMethodCollector {
} }
} }
impl FindMethodCollector { impl FunctionCollector<'_> for FindMethodCollector {
pub fn generated(self) -> Result<TokenStream, darling::Error> { fn release(self) -> Result<TokenStream, darling::Error> {
self.generated self.generated
} }
} }

View File

@ -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<TokenStream, darling::Error>,
}
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<T: IntoIterator<Item = (usize, &'a FuncDesc)>>(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<Vec<u16>> {
#get_func_name_body
None
}
};
Self {
generated: Ok(get_func_name_definition),
}
}
}
impl FunctionCollector<'_> for GetMethodNameCollector {
fn release(self) -> Result<TokenStream, darling::Error> {
self.generated
}
}

View File

@ -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<TokenStream, darling::Error>,
}
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<T: IntoIterator<Item = (usize, &'a FuncDesc)>>(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<TokenStream, darling::Error> {
self.generated
}
}

View File

@ -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<TokenStream, darling::Error>,
}
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<T: IntoIterator<Item = (usize, &'a FuncDesc)>>(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<TokenStream, darling::Error> {
self.generated
}
}

View File

@ -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<TokenStream, darling::Error>,
}
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<T: IntoIterator<Item = (usize, &'a FuncDesc)>>(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<TokenStream, darling::Error> {
self.generated
}
}

View File

@ -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<TokenStream, darling::Error>,
}
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<T: IntoIterator<Item = (usize, &'a FuncDesc)>>(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<TokenStream, darling::Error> {
self.generated
}
}

View File

@ -3,10 +3,26 @@ use proc_macro2::TokenStream;
use super::FuncDesc; use super::FuncDesc;
use crate::utils::macros::tkn_err_inner; use crate::utils::macros::tkn_err_inner;
pub mod call_as_func;
pub mod call_as_proc;
pub mod find_method; 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 { pub trait FunctionCollector<'a>: FromIterator<(usize, &'a FuncDesc)> + Default {
fn release(&self) -> Result<TokenStream, darling::Error>; fn release(self) -> Result<TokenStream, darling::Error>;
} }
pub fn empty_func_collector_error() -> darling::Error { pub fn empty_func_collector_error() -> darling::Error {

View File

@ -1,12 +1,9 @@
use common_generators::{param_ty_to_ffi_return, SettableTypes}; use common_generators::{param_ty_to_ffi_return, SettableTypes};
use proc_macro2::{Ident, TokenStream}; use proc_macro2::TokenStream;
use quote::{quote, ToTokens}; use quote::quote;
use syn::{parse_macro_input, DeriveInput}; use syn::{parse_macro_input, DeriveInput};
use function_processing::{ use function_processing::{collectors::*, parse::parse_functions};
collectors::find_method::FindMethodCollector, generate::func_call_tkn, parse::parse_functions,
ParamType, ReturnType,
};
use props_processing::{generate::param_ty_to_ffi_set, parse::parse_props}; use props_processing::{generate::param_ty_to_ffi_set, parse::parse_props};
use utils::{ use utils::{
macros::{tkn_err, tkn_err_inner}, macros::{tkn_err, tkn_err_inner},
@ -55,7 +52,6 @@ fn build_impl_block(input: &DeriveInput) -> Result<proc_macro2::TokenStream, dar
let functions = parse_functions(struct_data)?; let functions = parse_functions(struct_data)?;
let number_of_props = props.len(); let number_of_props = props.len();
let number_of_func = functions.len();
let mut find_prop_body = quote! {}; let mut find_prop_body = quote! {};
let mut get_prop_name_body = quote! {}; let mut get_prop_name_body = quote! {};
@ -125,97 +121,20 @@ fn build_impl_block(input: &DeriveInput) -> Result<proc_macro2::TokenStream, dar
} }
} }
let func_iter = functions.iter().enumerate(); let fi = functions.iter().enumerate();
let find_method_definition = func_iter.collect::<FindMethodCollector>().generated()?; let func_definitions = [
fi.clone().collect::<FindMethodCollector>().release()?,
let mut get_func_name_body = quote! {}; fi.clone().collect::<GetMethodNameCollector>().release()?,
let mut has_ret_val_body = quote! {}; fi.clone().collect::<GetNMethodsCollector>().release()?,
let mut get_n_params_body = quote! {}; fi.clone().collect::<GetNParamsCollector>().release()?,
let mut call_as_proc_body = quote! {}; fi.clone().collect::<HasReturnValueCollector>().release()?,
let mut call_as_func_body = quote! {}; fi.clone().collect::<CallAsProcCollector>().release()?,
let mut get_param_def_value_body = quote! {}; fi.clone().collect::<CallAsFuncCollector>().release()?,
fi.clone()
for func in &functions { .collect::<GetParamDefValueCollector>()
let name_literal = str_literal_token(&func.name, struct_ident)?; .release()?,
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 result = quote! { let result = quote! {
impl native_api_1c::native_api_1c_core::interface::AddInWrapper for #struct_ident { impl native_api_1c::native_api_1c_core::interface::AddInWrapper for #struct_ident {
@ -258,48 +177,7 @@ fn build_impl_block(input: &DeriveInput) -> Result<proc_macro2::TokenStream, dar
#is_prop_writable_body #is_prop_writable_body
false false
} }
#find_method_definition #(#func_definitions)*
fn get_n_methods(&self) -> usize {
#number_of_func
}
fn get_method_name(&self, num: usize, alias: usize) -> Option<Vec<u16>> {
#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
}
fn set_locale(&mut self, loc: &[u16]) { fn set_locale(&mut self, loc: &[u16]) {
} }
fn set_user_interface_language_code(&mut self, lang: &[u16]) { fn set_user_interface_language_code(&mut self, lang: &[u16]) {