@@ -46,7 +46,8 @@ pub(crate) struct TypedHandle<'a> {
4646 /// `#[prebindgen]` fn idents promoted to instance methods on this
4747 /// class. The matching opaque first parameter is dropped from the
4848 /// signature; the method uses inherited `withPtr` / `consume`. An
49- /// empty slice emits a pure shell (just `close()` + `freePtrViaJNI`).
49+ /// empty slice emits a pure shell (just `free()` + the matching
50+ /// `freePtr<jni_method_suffix>` extern).
5051 pub functions : & ' a [ & ' a str ] ,
5152}
5253
@@ -234,7 +235,7 @@ impl JniExt {
234235 /// class instead). Opaque-handle parameters become `NativeHandle`;
235236 /// the wrapper body nests `withPtr` / `consume` per the
236237 /// type-conversion rule (`&T` → `withPtr`, `T` → `consume`), then
237- /// delegates to the matching `JNINative.<name>ViaJNI (...)`.
238+ /// delegates to the matching `JNINative.<name><jni_method_suffix> (...)`.
238239 /// Non-opaque parameters pass through with the Kotlin type from
239240 /// `kotlin_types`. Opaque-handle return values are wrapped in
240241 /// `NativeHandle(...)` before being returned.
@@ -260,7 +261,7 @@ impl JniExt {
260261
261262 /// Emit one Kotlin file per entry in `handles` — each becomes a
262263 /// `public class <ClassName>(initialPtr: Long) : NativeHandle(initialPtr)`
263- /// with the standard `close ()` + `private external fun freePtrViaJNI (ptr: Long)`
264+ /// with the standard `free ()` + `private external fun freePtr<jni_method_suffix> (ptr: Long)`
264265 /// destructor pair, plus one instance method per `#[prebindgen]` fn
265266 /// listed in [`TypedHandle::functions`]. The promoted method's first
266267 /// opaque parameter matching the handle's Rust type is dropped — the
@@ -330,6 +331,7 @@ impl JniExt {
330331 rust_key. as_deref ( ) ,
331332 registry,
332333 & merged_types,
334+ & self . jni_method_suffix ,
333335 ) ,
334336 package,
335337 class_name,
@@ -608,7 +610,8 @@ public open class NativeHandle(initial: Long) {
608610 . to_string ( )
609611}
610612
611- /// Render one typed-handle Kotlin source file. Pure-shell form:
613+ /// Render one typed-handle Kotlin source file. Pure-shell form
614+ /// (assuming `jni_method_suffix = "ViaJNI"`):
612615///
613616/// ```kotlin
614617/// public class JNIFoo(initialPtr: Long) : NativeHandle(initialPtr) {
@@ -623,9 +626,10 @@ public open class NativeHandle(initial: Long) {
623626/// signature, and its `withPtr` / `consume` wrapper uses the
624627/// inherited [`NativeHandle`] scope.
625628///
626- /// The Kotlin/JVM JNI name mangler binds `freePtrViaJNI` to the
627- /// `Java_<pkg>_<class>_freePtrViaJNI` extern emitted on the Rust
628- /// side — same convention as before, no Rust-side change needed.
629+ /// The free-pointer extern name is built as `freePtr<jni_method_suffix>`.
630+ /// Kotlin/JVM's JNI name mangler binds it to the matching
631+ /// `Java_<pkg>_<class>_freePtr<jni_method_suffix>` extern on the Rust
632+ /// side (the hand-written destructor).
629633fn render_typed_handle_source (
630634 package : & str ,
631635 class_name : & str ,
@@ -634,6 +638,7 @@ fn render_typed_handle_source(
634638 promoted_rust_key : Option < & str > ,
635639 registry : & Registry < KotlinMeta > ,
636640 kotlin_types : & KotlinTypeMap ,
641+ jni_method_suffix : & str ,
637642) -> String {
638643 // Build method bodies first so we can collect imports up front.
639644 let mut imports: BTreeSet < String > = BTreeSet :: new ( ) ;
@@ -653,6 +658,7 @@ fn render_typed_handle_source(
653658 kotlin_types,
654659 & mut imports,
655660 promoted_rust_key,
661+ jni_method_suffix,
656662 )
657663 . unwrap_or_else ( || {
658664 panic ! (
@@ -709,8 +715,13 @@ fn render_typed_handle_source(
709715 "public class {}(initialPtr: Long) : NativeHandle(initialPtr) {{\n " ,
710716 class_name
711717 ) ) ;
712- s. push_str ( " public fun free() = free { freePtrViaJNI(it) }\n " ) ;
713- s. push_str ( " private external fun freePtrViaJNI(ptr: Long)\n " ) ;
718+ let free_extern = format ! ( "freePtr{jni_method_suffix}" ) ;
719+ s. push_str ( & format ! (
720+ " public fun free() = free {{ {free_extern}(it) }}\n "
721+ ) ) ;
722+ s. push_str ( & format ! (
723+ " private external fun {free_extern}(ptr: Long)\n "
724+ ) ) ;
714725 if !methods_body. is_empty ( ) {
715726 s. push ( '\n' ) ;
716727 s. push_str ( & methods_body) ;
@@ -725,7 +736,7 @@ fn render_typed_handle_source(
725736/// the wrapper body nests `withPtr` / `consume` per the syntactic
726737/// shape. Non-opaque parameters pass through with the Kotlin type from
727738/// `kotlin_types`. The wrappers delegate to
728- /// `JNINative.<name>ViaJNI (...)`.
739+ /// `JNINative.<name><jni_method_suffix> (...)`.
729740fn render_jni_wrappers_source (
730741 ext : & JniExt ,
731742 registry : & Registry < KotlinMeta > ,
@@ -756,14 +767,20 @@ fn render_jni_wrappers_source(
756767 for ident in idents {
757768 // Skip functions promoted to a typed-handle class — their
758769 // top-level wrapper lives on the handle instead. The Rust-side
759- // `JNINative.<name>ViaJNI` extern is still emitted by the
760- // legacy `KotlinInterfaceGenerator`; only the Kotlin-side
761- // safe wrapper moves.
770+ // `JNINative.<name><jni_method_suffix>` extern still exists;
771+ // only the Kotlin-side safe wrapper moves.
762772 if promoted. contains ( & ident. to_string ( ) ) {
763773 continue ;
764774 }
765775 let ( item_fn, _loc) = & registry. functions [ ident] ;
766- if let Some ( block) = render_wrapper_fn ( item_fn, registry, & merged_types, & mut imports, None ) {
776+ if let Some ( block) = render_wrapper_fn (
777+ item_fn,
778+ registry,
779+ & merged_types,
780+ & mut imports,
781+ None ,
782+ & ext. jni_method_suffix ,
783+ ) {
767784 body. push_str ( & block) ;
768785 body. push ( '\n' ) ;
769786 }
@@ -814,12 +831,13 @@ fn render_wrapper_fn(
814831 kotlin_types : & KotlinTypeMap ,
815832 imports : & mut BTreeSet < String > ,
816833 promoted_handle : Option < & str > ,
834+ jni_method_suffix : & str ,
817835) -> Option < String > {
818836 use std:: fmt:: Write ;
819837
820838 let rust_name = f. sig . ident . to_string ( ) ;
821839 let kt_name = snake_to_camel ( & rust_name) ;
822- let jni_call = format ! ( "{kt_name}ViaJNI " ) ;
840+ let jni_call = format ! ( "{kt_name}{jni_method_suffix} " ) ;
823841
824842 // Pre-parse the promoted Rust type-key (if any) so per-param matching
825843 // is whitespace-normalised against the canonical form.
0 commit comments