use quote::format_ident;
use super::JniPrim;
pub(crate) const KOTLIN_PRIM_ARRAYS: [(&str, &str); 8] = [
("BooleanArray", "[Z"),
("ByteArray", "[B"),
("CharArray", "[C"),
("ShortArray", "[S"),
("IntArray", "[I"),
("LongArray", "[J"),
("FloatArray", "[F"),
("DoubleArray", "[D"),
];
pub(crate) fn kotlin_array_descriptor(name: &str) -> Option<&'static str> {
KOTLIN_PRIM_ARRAYS
.iter()
.find(|(n, _)| *n == name)
.map(|(_, d)| *d)
}
pub(crate) fn kotlin_array_of_descriptor(descr: &str) -> Option<&'static str> {
KOTLIN_PRIM_ARRAYS
.iter()
.find(|(_, d)| *d == descr)
.map(|(n, _)| *n)
}
pub(crate) fn is_jni_reference_wire(ty: &syn::Type) -> bool {
let syn::Type::Path(tp) = ty else {
return false;
};
let Some(last) = tp.path.segments.last() else {
return false;
};
matches!(
last.ident.to_string().as_str(),
"JObject"
| "JString"
| "JClass"
| "JBooleanArray"
| "JByteArray"
| "JCharArray"
| "JShortArray"
| "JIntArray"
| "JLongArray"
| "JFloatArray"
| "JDoubleArray"
)
}
pub(crate) fn jni_field_access(jni_type: &syn::Type) -> Option<(&'static str, syn::Ident, bool)> {
if let Some(p) = JniPrim::from_wire(jni_type) {
return Some((p.descriptor(), format_ident!("{}", p.unbox_getter()), false));
}
let syn::Type::Path(tp) = jni_type else {
return None;
};
let sig = match tp.path.segments.last()?.ident.to_string().as_str() {
"JString" => "Ljava/lang/String;",
"JBooleanArray" => "[Z",
"JByteArray" => "[B",
"JCharArray" => "[C",
"JShortArray" => "[S",
"JIntArray" => "[I",
"JLongArray" => "[J",
"JFloatArray" => "[F",
"JDoubleArray" => "[D",
_ => return None,
};
Some((sig, format_ident!("l"), true))
}
pub(crate) fn box_descriptor_for_primitive(sig: &str) -> Option<&'static str> {
JniPrim::from_descriptor(sig).map(JniPrim::box_descriptor)
}
pub(crate) fn box_helper_for_wire(wire: &syn::Type) -> Option<syn::Ident> {
JniPrim::from_wire(wire).map(|p| format_ident!("box_{}", p.wire_name()))
}