diff --git a/core/commonMain/src/kotlinx/serialization/internal/Primitives.kt b/core/commonMain/src/kotlinx/serialization/internal/Primitives.kt index 71181ded4e..c26a0b831f 100644 --- a/core/commonMain/src/kotlinx/serialization/internal/Primitives.kt +++ b/core/commonMain/src/kotlinx/serialization/internal/Primitives.kt @@ -15,38 +15,9 @@ import kotlin.reflect.* import kotlin.time.Duration import kotlin.uuid.* -@OptIn(ExperimentalUnsignedTypes::class, ExperimentalUuidApi::class) -private val BUILTIN_SERIALIZERS = mapOf( - String::class to String.serializer(), - Char::class to Char.serializer(), - CharArray::class to CharArraySerializer(), - Double::class to Double.serializer(), - DoubleArray::class to DoubleArraySerializer(), - Float::class to Float.serializer(), - FloatArray::class to FloatArraySerializer(), - Long::class to Long.serializer(), - LongArray::class to LongArraySerializer(), - ULong::class to ULong.serializer(), - ULongArray::class to ULongArraySerializer(), - Int::class to Int.serializer(), - IntArray::class to IntArraySerializer(), - UInt::class to UInt.serializer(), - UIntArray::class to UIntArraySerializer(), - Short::class to Short.serializer(), - ShortArray::class to ShortArraySerializer(), - UShort::class to UShort.serializer(), - UShortArray::class to UShortArraySerializer(), - Byte::class to Byte.serializer(), - ByteArray::class to ByteArraySerializer(), - UByte::class to UByte.serializer(), - UByteArray::class to UByteArraySerializer(), - Boolean::class to Boolean.serializer(), - BooleanArray::class to BooleanArraySerializer(), - Unit::class to Unit.serializer(), - Nothing::class to NothingSerializer(), - Duration::class to Duration.serializer(), - Uuid::class to Uuid.serializer() -) +private val BUILTIN_SERIALIZERS = initBuiltins() + +internal expect fun initBuiltins(): Map, KSerializer<*>> internal class PrimitiveSerialDescriptor( override val serialName: String, diff --git a/core/jsMain/src/kotlinx/serialization/internal/Platform.kt b/core/jsMain/src/kotlinx/serialization/internal/Platform.kt index 571c3f7979..e423afca2a 100644 --- a/core/jsMain/src/kotlinx/serialization/internal/Platform.kt +++ b/core/jsMain/src/kotlinx/serialization/internal/Platform.kt @@ -5,7 +5,10 @@ package kotlinx.serialization.internal import kotlinx.serialization.* +import kotlinx.serialization.builtins.* import kotlin.reflect.* +import kotlin.time.* +import kotlin.uuid.* internal actual fun Array.getChecked(index: Int): T { if (index !in indices) throw IndexOutOfBoundsException("Index $index out of bounds $indices") @@ -77,3 +80,36 @@ private val KClass<*>.isInterface: Boolean if (this === Nothing::class) return false return js.asDynamic().`$metadata$`?.kind == "interface" } + +@OptIn(ExperimentalUnsignedTypes::class, ExperimentalUuidApi::class, ExperimentalSerializationApi::class) +internal actual fun initBuiltins(): Map, KSerializer<*>> = mapOf( + String::class to String.serializer(), + Char::class to Char.serializer(), + CharArray::class to CharArraySerializer(), + Double::class to Double.serializer(), + DoubleArray::class to DoubleArraySerializer(), + Float::class to Float.serializer(), + FloatArray::class to FloatArraySerializer(), + Long::class to Long.serializer(), + LongArray::class to LongArraySerializer(), + ULong::class to ULong.serializer(), + ULongArray::class to ULongArraySerializer(), + Int::class to Int.serializer(), + IntArray::class to IntArraySerializer(), + UInt::class to UInt.serializer(), + UIntArray::class to UIntArraySerializer(), + Short::class to Short.serializer(), + ShortArray::class to ShortArraySerializer(), + UShort::class to UShort.serializer(), + UShortArray::class to UShortArraySerializer(), + Byte::class to Byte.serializer(), + ByteArray::class to ByteArraySerializer(), + UByte::class to UByte.serializer(), + UByteArray::class to UByteArraySerializer(), + Boolean::class to Boolean.serializer(), + BooleanArray::class to BooleanArraySerializer(), + Unit::class to Unit.serializer(), + Nothing::class to NothingSerializer(), + Duration::class to Duration.serializer(), + Uuid::class to Uuid.serializer() +) diff --git a/core/jvmMain/src/kotlinx/serialization/internal/Platform.kt b/core/jvmMain/src/kotlinx/serialization/internal/Platform.kt index 5cf32d0e5d..b838a0fe52 100644 --- a/core/jvmMain/src/kotlinx/serialization/internal/Platform.kt +++ b/core/jvmMain/src/kotlinx/serialization/internal/Platform.kt @@ -5,8 +5,11 @@ package kotlinx.serialization.internal import kotlinx.serialization.* +import kotlinx.serialization.builtins.* import java.lang.reflect.* import kotlin.reflect.* +import kotlin.time.* +import kotlin.uuid.* @Suppress("NOTHING_TO_INLINE") internal actual inline fun Array.getChecked(index: Int): T { @@ -158,3 +161,53 @@ private fun Class.findObjectSerializer(): KSerializer? { } internal actual fun isReferenceArray(rootClass: KClass): Boolean = rootClass.java.isArray + +@OptIn(ExperimentalSerializationApi::class) +internal actual fun initBuiltins(): Map, KSerializer<*>> = buildMap { + // Standard classes are always present + put(String::class, String.serializer()) + put(Char::class, Char.serializer()) + put(CharArray::class, CharArraySerializer()) + put(Double::class, Double.serializer()) + put(DoubleArray::class, DoubleArraySerializer()) + put(Float::class, Float.serializer()) + put(FloatArray::class, FloatArraySerializer()) + put(Long::class, Long.serializer()) + put(LongArray::class, LongArraySerializer()) + put(ULong::class, ULong.serializer()) + put(Int::class, Int.serializer()) + put(IntArray::class, IntArraySerializer()) + put(UInt::class, UInt.serializer()) + put(Short::class, Short.serializer()) + put(ShortArray::class, ShortArraySerializer()) + put(UShort::class, UShort.serializer()) + put(Byte::class, Byte.serializer()) + put(ByteArray::class, ByteArraySerializer()) + put(UByte::class, UByte.serializer()) + put(Boolean::class, Boolean.serializer()) + put(BooleanArray::class, BooleanArraySerializer()) + put(Unit::class, Unit.serializer()) + put(Nothing::class, NothingSerializer()) + + // Duration is a stable class, but may be missing in very old stdlibs + loadSafe { put(Duration::class, Duration.serializer()) } + + // Experimental types that may be missing + @OptIn(ExperimentalUnsignedTypes::class) run { + loadSafe { put(ULongArray::class, ULongArraySerializer()) } + loadSafe { put(UIntArray::class, UIntArraySerializer()) } + loadSafe { put(UShortArray::class, UShortArraySerializer()) } + loadSafe { put(UByteArray::class, UByteArraySerializer()) } + } + @OptIn(ExperimentalUuidApi::class) + loadSafe { put(Uuid::class, Uuid.serializer()) } +} + +// Reference classes in [block] ignoring any exceptions related to class loading +private inline fun loadSafe(block: () -> Unit) { + try { + block() + } catch (_: NoClassDefFoundError) { + } catch (_: ClassNotFoundException) { + } +} diff --git a/core/nativeMain/src/kotlinx/serialization/internal/Platform.kt b/core/nativeMain/src/kotlinx/serialization/internal/Platform.kt index ddf690c25c..c2e9fdd7e0 100644 --- a/core/nativeMain/src/kotlinx/serialization/internal/Platform.kt +++ b/core/nativeMain/src/kotlinx/serialization/internal/Platform.kt @@ -5,7 +5,10 @@ package kotlinx.serialization.internal import kotlinx.serialization.* +import kotlinx.serialization.builtins.* import kotlin.reflect.* +import kotlin.time.* +import kotlin.uuid.* @Suppress("NOTHING_TO_INLINE") internal actual inline fun Array.getChecked(index: Int): T { @@ -71,3 +74,36 @@ internal actual fun ArrayList.toNativeArrayImpl(eClass: KCl private fun arrayOfAnyNulls(size: Int): Array = arrayOfNulls(size) as Array internal actual fun isReferenceArray(rootClass: KClass): Boolean = rootClass == Array::class + +@OptIn(ExperimentalUnsignedTypes::class, ExperimentalUuidApi::class, ExperimentalSerializationApi::class) +internal actual fun initBuiltins(): Map, KSerializer<*>> = mapOf( + String::class to String.serializer(), + Char::class to Char.serializer(), + CharArray::class to CharArraySerializer(), + Double::class to Double.serializer(), + DoubleArray::class to DoubleArraySerializer(), + Float::class to Float.serializer(), + FloatArray::class to FloatArraySerializer(), + Long::class to Long.serializer(), + LongArray::class to LongArraySerializer(), + ULong::class to ULong.serializer(), + ULongArray::class to ULongArraySerializer(), + Int::class to Int.serializer(), + IntArray::class to IntArraySerializer(), + UInt::class to UInt.serializer(), + UIntArray::class to UIntArraySerializer(), + Short::class to Short.serializer(), + ShortArray::class to ShortArraySerializer(), + UShort::class to UShort.serializer(), + UShortArray::class to UShortArraySerializer(), + Byte::class to Byte.serializer(), + ByteArray::class to ByteArraySerializer(), + UByte::class to UByte.serializer(), + UByteArray::class to UByteArraySerializer(), + Boolean::class to Boolean.serializer(), + BooleanArray::class to BooleanArraySerializer(), + Unit::class to Unit.serializer(), + Nothing::class to NothingSerializer(), + Duration::class to Duration.serializer(), + Uuid::class to Uuid.serializer() +) diff --git a/core/wasmMain/src/kotlinx/serialization/internal/Platform.kt b/core/wasmMain/src/kotlinx/serialization/internal/Platform.kt index 146845be3a..ecfee8ede8 100644 --- a/core/wasmMain/src/kotlinx/serialization/internal/Platform.kt +++ b/core/wasmMain/src/kotlinx/serialization/internal/Platform.kt @@ -5,7 +5,10 @@ package kotlinx.serialization.internal import kotlinx.serialization.* +import kotlinx.serialization.builtins.* import kotlin.reflect.* +import kotlin.time.* +import kotlin.uuid.* @Suppress("NOTHING_TO_INLINE") internal actual inline fun Array.getChecked(index: Int): T { @@ -61,3 +64,36 @@ internal actual fun createParametrizedCache(factory: (KClass, List ArrayList.toNativeArrayImpl(eClass: KClass): Array = toTypedArray() internal actual fun isReferenceArray(rootClass: KClass): Boolean = rootClass == Array::class + +@OptIn(ExperimentalUnsignedTypes::class, ExperimentalUuidApi::class, ExperimentalSerializationApi::class) +internal actual fun initBuiltins(): Map, KSerializer<*>> = mapOf( + String::class to String.serializer(), + Char::class to Char.serializer(), + CharArray::class to CharArraySerializer(), + Double::class to Double.serializer(), + DoubleArray::class to DoubleArraySerializer(), + Float::class to Float.serializer(), + FloatArray::class to FloatArraySerializer(), + Long::class to Long.serializer(), + LongArray::class to LongArraySerializer(), + ULong::class to ULong.serializer(), + ULongArray::class to ULongArraySerializer(), + Int::class to Int.serializer(), + IntArray::class to IntArraySerializer(), + UInt::class to UInt.serializer(), + UIntArray::class to UIntArraySerializer(), + Short::class to Short.serializer(), + ShortArray::class to ShortArraySerializer(), + UShort::class to UShort.serializer(), + UShortArray::class to UShortArraySerializer(), + Byte::class to Byte.serializer(), + ByteArray::class to ByteArraySerializer(), + UByte::class to UByte.serializer(), + UByteArray::class to UByteArraySerializer(), + Boolean::class to Boolean.serializer(), + BooleanArray::class to BooleanArraySerializer(), + Unit::class to Unit.serializer(), + Nothing::class to NothingSerializer(), + Duration::class to Duration.serializer(), + Uuid::class to Uuid.serializer() +)