pub mod all;
pub mod ctor;
pub mod destructor;
pub mod method;
use crate::lang::TypeId;
use crate::lang::types::kind::TypeKind;
use crate::pass::{model, output};
pub(super) fn resolve_ptr_to_service_name(type_id: TypeId, types: &model::common::types::all::Pass) -> Option<String> {
let ty = types.get(type_id)?;
if let TypeKind::Pointer(p) = &ty.kind {
let target = types.get(p.target)?;
if matches!(&target.kind, TypeKind::Service) {
return Some(target.name.clone());
}
}
None
}
fn resolve_double_ptr_to_service_name(type_id: TypeId, types: &model::common::types::all::Pass) -> Option<String> {
let ty = types.get(type_id)?;
if let TypeKind::Pointer(outer) = &ty.kind {
let inner = types.get(outer.target)?;
if let TypeKind::Pointer(p) = &inner.kind {
let target = types.get(p.target)?;
if matches!(&target.kind, TypeKind::Service) {
return Some(target.name.clone());
}
}
}
None
}
pub(super) fn service_aware_args(
func: &crate::lang::functions::Function,
types: &model::common::types::all::Pass,
unmanaged_names: &output::common::conversion::unmanaged_names::Pass,
unmanaged_conversion: &output::common::conversion::unmanaged_conversion::Pass,
) -> (String, String) {
let args: Vec<String> = func
.signature
.arguments
.iter()
.filter_map(|arg| {
let ty_name = unmanaged_names.name(arg.ty)?;
Some(format!("{ty_name} {}", arg.name))
})
.collect();
let forward: Vec<String> = func
.signature
.arguments
.iter()
.map(|a| {
if let Some(svc_name) = resolve_ptr_to_service_name(a.ty, types) {
format!("new {svc_name}.Unmanaged {{ _handle = {} }}.IntoManaged()", a.name)
} else if let Some(svc_name) = resolve_double_ptr_to_service_name(a.ty, types) {
format!("new {svc_name}.Unmanaged {{ _handle = Marshal.ReadIntPtr({}) }}.AsManaged()", a.name)
} else {
format!("{}{}", a.name, unmanaged_conversion.to_managed_suffix(a.ty))
}
})
.collect();
(args.join(", "), forward.join(", "))
}
pub(super) fn service_aware_args_except_last(
func: &crate::lang::functions::Function,
types: &model::common::types::all::Pass,
unmanaged_names: &output::common::conversion::unmanaged_names::Pass,
unmanaged_conversion: &output::common::conversion::unmanaged_conversion::Pass,
) -> (String, String) {
let n = func.signature.arguments.len().saturating_sub(1);
let args: Vec<String> = func
.signature
.arguments
.iter()
.filter_map(|arg| {
let ty_name = unmanaged_names.name(arg.ty)?;
Some(format!("{ty_name} {}", arg.name))
})
.collect();
let forward: Vec<String> = func
.signature
.arguments
.iter()
.take(n)
.map(|a| {
if let Some(svc_name) = resolve_ptr_to_service_name(a.ty, types) {
format!("new {svc_name}.Unmanaged {{ _handle = {} }}.IntoManaged()", a.name)
} else if let Some(svc_name) = resolve_double_ptr_to_service_name(a.ty, types) {
format!("new {svc_name}.Unmanaged {{ _handle = Marshal.ReadIntPtr({}) }}.AsManaged()", a.name)
} else {
format!("{}{}", a.name, unmanaged_conversion.to_managed_suffix(a.ty))
}
})
.collect();
(args.join(", "), forward.join(", "))
}