Skip to content
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## Unreleased
* Kotlin: use `@JvmSynthetic` annotation for Kotlin internal elements whenever possible to hide them from Java code.
* Kotlin: allow the usage of 'RequiresOptIn' and 'OptIn' annotations for internal API via CLI parameters. This way error is generated when the code, which is not intended to access the internal API uses it. Three new CLI parameters are available: 'androidrequiresoptinannotation', 'androidoptinannotation' and 'androidinternalapiannotationname'.
* Kotlin: for external types usage in Kotlin, use 'internal' keyword for the types, which are generated by Gluecodium as their 'internal' representation.

## 14.0.0
Release date 2025-12-01
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ class ExternalTypesTest {
assertEquals(77, result)
}

@OptIn(com.here.android.lorem.ipsum.FunctionalTestsInternalAPI::class)
@org.junit.Test
fun createSomeSerializableExternalStruct() {
val struct = ExternalMarkedAsSerializable(42)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,17 @@
*/
package com.here.android.test

object BooleanConverter {
@JvmStatic
fun convertFromInternal(internalBoolean: VeryBoolean) : Boolean? {
import com.here.android.lorem.ipsum.FunctionalTestsInternalAPI

@FunctionalTestsInternalAPI
internal object BooleanConverter {
@JvmStatic @JvmSynthetic @JvmName("convertFromInternal")
internal fun convertFromInternal(internalBoolean: VeryBoolean) : Boolean? {
return internalBoolean.value
}

@JvmStatic
fun convertToInternal(systemBoolean: Boolean?) : VeryBoolean {
@JvmStatic @JvmSynthetic @JvmName("convertToInternal")
internal fun convertToInternal(systemBoolean: Boolean?) : VeryBoolean {
return VeryBoolean(systemBoolean!!)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@
*/
package com.here.android.test

import com.here.android.lorem.ipsum.FunctionalTestsInternalAPI
import kotlin.math.round

object ColorConverter {
@JvmStatic
fun convertFromInternal(internalColor: SystemColor): Int? {
@FunctionalTestsInternalAPI
internal object ColorConverter {
@JvmStatic @JvmSynthetic @JvmName("convertFromInternal")
internal fun convertFromInternal(internalColor: SystemColor): Int? {
return android.graphics.Color.argb(
round(internalColor.alpha * 255).toInt(),
round(internalColor.red * 255).toInt(),
Expand All @@ -31,8 +33,8 @@ object ColorConverter {
)
}

@JvmStatic
fun convertToInternal(color: Int?): SystemColor {
@JvmStatic @JvmSynthetic @JvmName("convertToInternal")
internal fun convertToInternal(color: Int?): SystemColor {
val systemColor: Int = color!!
return SystemColor(
android.graphics.Color.red(systemColor) / 255.0f,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@
*/
package com.here.android.test

object ExternalStructMarkedAsSerializableConverter {
@JvmStatic
fun convertFromInternal(struct: ExternalMarkedAsSerializable) = AnExternalStruct(struct.field)
import com.here.android.lorem.ipsum.FunctionalTestsInternalAPI

@JvmStatic
fun convertToInternal(s: com.here.android.test.AnExternalStruct) = ExternalMarkedAsSerializable(s.mData)
@FunctionalTestsInternalAPI
internal object ExternalStructMarkedAsSerializableConverter {
@JvmStatic @JvmSynthetic @JvmName("convertFromInternal")
internal fun convertFromInternal(struct: ExternalMarkedAsSerializable) = AnExternalStruct(struct.field)

@JvmStatic @JvmSynthetic @JvmName("convertToInternal")
internal fun convertToInternal(s: com.here.android.test.AnExternalStruct) = ExternalMarkedAsSerializable(s.mData)
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@
*/
package com.here.android.test

import com.here.android.lorem.ipsum.FunctionalTestsInternalAPI

@FunctionalTestsInternalAPI
object SeasonConverter {
@JvmStatic
fun convertFromInternal(season: Season) = season.name
@JvmStatic @JvmSynthetic @JvmName("convertFromInternal")
internal fun convertFromInternal(season: Season) = season.name

@JvmStatic
fun convertToInternal(seasonString: String) = Season.valueOf(seasonString)
@JvmStatic @JvmSynthetic @JvmName("convertToInternal")
internal fun convertToInternal(seasonString: String) = Season.valueOf(seasonString)
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ internal class KotlinImportResolver(

private fun resolveInternalTypeImport(limeType: LimeType): List<String> {
return when {
internalApiAnnotation != null && CommonGeneratorPredicates.isInternal(limeType, KOTLIN) -> listOf(internalApiAnnotationImport)
internalApiAnnotation != null && (CommonGeneratorPredicates.isInternal(limeType, KOTLIN) || limeType.external?.kotlin != null)
-> listOf(internalApiAnnotationImport)
else -> emptyList()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@
!
!}}
{{>kotlin/KotlinDocComment}}{{>kotlin/KotlinAttributes}}
{{>kotlin/KotlinTypeVisibility}}{{!!
{{#if external.kotlin.converter}}{{!!
}}{{#internalApiAnnotation}}{{#unless this.isEmpty}}@{{this}}
{{/unless}}{{/internalApiAnnotation}}internal {{!!
}}{{/if}}{{!!
}}{{#unless external.kotlin.converter}}{{>kotlin/KotlinTypeVisibility}}{{/unless}}{{!!
}}enum class {{resolveName}}(@JvmField {{resolveName "visibility"}}val value: Int) {
{{joinPartial uniqueEnumerators "kotlin/KotlinEnumerator" ",
"}}{{#if uniqueEnumerators}};{{/if}}{{#if aliasEnumerators}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@
}}{{#resolveName "visibility"}}{{#unless this.isEmpty}}@JvmSynthetic {{/unless}}{{/resolveName}}{{!!
}}{{#unless override}}{{#unless isInterface}}{{#ifPredicate "isInternal"}}@JvmName("{{resolveName}}") {{/ifPredicate}}{{/unless}}{{/unless}}{{!!
}}{{#if override}}override {{/if}}{{!!
}}{{#unless isInterface}}{{resolveName "visibility"}}external {{/unless}}fun {{resolveName}}({{!!
}}{{#unless isInterface}}{{!!
}}{{#unless this.isConstructor}}{{resolveName "visibility"}}{{/unless}}{{!!
}}{{#if this.isConstructor}}private {{/if}}{{!!
}}external {{!!
}}{{/unless}}fun {{resolveName}}({{!!
}}{{#parameters}}{{!!
}}{{>kotlin/KotlinAttributesInline}}{{resolveName}}: {{resolveName typeRef}}{{#if iter.hasNext}}, {{/if}}{{!!
}}{{/parameters}}) : {{!!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import java.util.concurrent.ConcurrentHashMap
import java.util.logging.Level
import java.util.logging.Logger

/*
/**
* Internal base class for public non-POD objects to manage the lifecycle of underlying C++ objects.
* While the class is public for technical reasons, but should be considered **internal** and not
* part of the public API and thus not used directly.
Expand All @@ -68,7 +68,12 @@ import java.util.logging.Logger
public abstract class NativeBase {
private val nativeHandle: Long

constructor(nativeHandle: Long, disposer: (Long) -> Unit) {
/**
* @suppress
* @param nativeHandle The native handle
* @param disposer The disposer
*/
protected constructor(nativeHandle: Long, disposer: (Long) -> Unit) {
this.nativeHandle = nativeHandle
REFERENCES.add(DisposableReference(this, nativeHandle, disposer))
}
Expand All @@ -91,7 +96,13 @@ public abstract class NativeBase {
}

companion object {
/**
* Controls whether exceptions related to cleanup of C++ objects tied with Kotlin objects
* are propagated to the user application.
* @suppress
*/
@JvmField public var propagateCleanupException: Boolean = false

private val LOGGER = Logger.getLogger(NativeBase::class.java.name)

// The set is to keep DisposableReference itself from being garbage-collected.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@
!
!}}
{{>kotlin/KotlinDocComment}}{{>kotlin/KotlinAttributes}}
{{#unless external.kotlin.converter}}{{>kotlin/KotlinTypeVisibility}}{{/unless}}{{!!
{{#if external.kotlin.converter}}{{!!
}}{{#internalApiAnnotation}}{{#unless this.isEmpty}}@{{this}}
{{/unless}}{{/internalApiAnnotation}}internal {{!!
}}{{/if}}{{!!
}}{{#unless external.kotlin.converter}}{{>kotlin/KotlinTypeVisibility}}{{/unless}}{{!!
}}class {{resolveName}}{{!!
}}{{#unless external.kotlin.name}}{{!!
}}{{#if attributes.serializable}} : Parcelable{{/if}}{{!!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import java.util.concurrent.ConcurrentHashMap
import java.util.logging.Level
import java.util.logging.Logger

/*
/**
* Internal base class for public non-POD objects to manage the lifecycle of underlying C++ objects.
* While the class is public for technical reasons, but should be considered **internal** and not
* part of the public API and thus not used directly.
Expand All @@ -48,7 +48,12 @@ import java.util.logging.Logger
public abstract class NativeBase {
private val nativeHandle: Long

constructor(nativeHandle: Long, disposer: (Long) -> Unit) {
/**
* @suppress
* @param nativeHandle The native handle
* @param disposer The disposer
*/
protected constructor(nativeHandle: Long, disposer: (Long) -> Unit) {
this.nativeHandle = nativeHandle
REFERENCES.add(DisposableReference(this, nativeHandle, disposer))
}
Expand All @@ -71,7 +76,13 @@ public abstract class NativeBase {
}

companion object {
/**
* Controls whether exceptions related to cleanup of C++ objects tied with Kotlin objects
* are propagated to the user application.
* @suppress
*/
@JvmField public var propagateCleanupException: Boolean = false

private val LOGGER = Logger.getLogger(NativeBase::class.java.name)

// The set is to keep DisposableReference itself from being garbage-collected.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

@file:JvmName("CtorLinksExtensions")


package com.example.smoke

import com.example.NativeBase
Expand Down Expand Up @@ -42,10 +43,11 @@ class CtorLinks : NativeBase {
companion object {
@JvmStatic private external fun disposeNativeHandle(nativeHandle: Long)

@JvmStatic external fun create() : Long
@JvmStatic private external fun create() : Long
}
}


/**
* This class has just one constructor with one argument [com.example.smoke.CtorLinks.SingleCtorWithOneArgument.SingleCtorWithOneArgument].
*/
Expand Down Expand Up @@ -77,10 +79,11 @@ class CtorLinks : NativeBase {
companion object {
@JvmStatic private external fun disposeNativeHandle(nativeHandle: Long)

@JvmStatic external fun create(arg: Int) : Long
@JvmStatic private external fun create(arg: Int) : Long
}
}


/**
* This class has just one constructor with two argument [com.example.smoke.CtorLinks.SingleCtorWithTwoArgument.SingleCtorWithTwoArgument].
*/
Expand Down Expand Up @@ -112,10 +115,11 @@ class CtorLinks : NativeBase {
companion object {
@JvmStatic private external fun disposeNativeHandle(nativeHandle: Long)

@JvmStatic external fun create(arg: Int, arg2: String) : Long
@JvmStatic private external fun create(arg: Int, arg2: String) : Long
}
}


class OverloadedCtors : NativeBase {


Expand Down Expand Up @@ -154,14 +158,15 @@ class CtorLinks : NativeBase {
companion object {
@JvmStatic private external fun disposeNativeHandle(nativeHandle: Long)

@JvmStatic external fun create(input: String) : Long
@JvmStatic private external fun create(input: String) : Long

@JvmStatic external fun create(input: String, flag: Boolean) : Long
@JvmStatic private external fun create(input: String, flag: Boolean) : Long
}
}




/**
* For internal use only.
* @suppress
Expand All @@ -182,3 +187,4 @@ class CtorLinks : NativeBase {
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

@file:JvmName("ChildConstructorsExtensions")


package com.example.smoke


Expand Down Expand Up @@ -40,9 +41,10 @@ class ChildConstructors : Constructors {

companion object {

@JvmStatic external fun createNoArgsChild() : Long
@JvmStatic private external fun createNoArgsChild() : Long

@JvmStatic external fun createCopyFromParent(other: Constructors) : Long
@JvmStatic private external fun createCopyFromParent(other: Constructors) : Long
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

@file:JvmName("ConstructorsExtensions")


package com.example.smoke

import com.example.NativeBase
Expand Down Expand Up @@ -70,17 +71,17 @@ open class Constructors : NativeBase {
companion object {
@JvmStatic private external fun disposeNativeHandle(nativeHandle: Long)

@JvmStatic external fun create() : Long
@JvmStatic private external fun create() : Long

@JvmStatic external fun create(other: Constructors) : Long
@JvmStatic private external fun create(other: Constructors) : Long

@JvmStatic external fun create(foo: String, bar: Long) : Long
@JvmStatic private external fun create(foo: String, bar: Long) : Long
@Throws(Constructors.ConstructorExplodedException::class)
@JvmStatic external fun create(input: String) : Long
@JvmStatic private external fun create(input: String) : Long

@JvmStatic external fun create(input: List<@JvmSuppressWildcards Double>) : Long
@JvmStatic private external fun create(input: List<@JvmSuppressWildcards Double>) : Long

@JvmStatic external fun create(input: Long) : Long
@JvmStatic private external fun create(input: Long) : Long
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

@file:JvmName("classExtensions")


package com.example.package

import com.example.NativeBase
Expand Down Expand Up @@ -44,7 +45,7 @@ class Class : NativeBase, Interface {
companion object {
@JvmStatic private external fun disposeNativeHandle(nativeHandle: Long)

@JvmStatic external fun Constructor() : Long
@JvmStatic private external fun Constructor() : Long
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@

@file:JvmName("ExternalMarkedAsSerializableExtensions")


package com.example.kotlinsmoke

import android.os.Parcel
import android.os.Parcelable

class ExternalMarkedAsSerializable {
internal class ExternalMarkedAsSerializable {
@JvmField var field: Int


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@

@file:JvmName("SeasonExtensions")


package com.example.kotlinsmoke


enum class Season(@JvmField val value: Int) {
internal enum class Season(@JvmField val value: Int) {
WINTER(0),
SPRING(1),
SUMMER(2),
Expand Down
Loading