Skip to content

Commit ac54504

Browse files
Experimental support for inline classes (#1244)
* Support for `@Serializable inline class` with generated (requires 1.4.30 IR compiler) and custom serializers * Standard serializers for UInt, ULong, UByte and UShort * Unsigned types support for both streaming and tree Json * Exclude folder with inline classes tests when legacy JVM compiler is used * Add appendix with info about inline classes to documentation Co-authored-by: Vsevolod Tolstopyatov <qwwdfsad@gmail.com>
1 parent 07f730a commit ac54504

31 files changed

+1140
-55
lines changed

core/api/kotlinx-serialization-core.api

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,10 @@ public final class kotlinx/serialization/builtins/BuiltinSerializersKt {
145145
public static final fun ShortArraySerializer ()Lkotlinx/serialization/KSerializer;
146146
public static final fun TripleSerializer (Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer;
147147
public static final fun getNullable (Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer;
148+
public static final fun serializer (Lkotlin/UByte$Companion;)Lkotlinx/serialization/KSerializer;
149+
public static final fun serializer (Lkotlin/UInt$Companion;)Lkotlinx/serialization/KSerializer;
150+
public static final fun serializer (Lkotlin/ULong$Companion;)Lkotlinx/serialization/KSerializer;
151+
public static final fun serializer (Lkotlin/UShort$Companion;)Lkotlinx/serialization/KSerializer;
148152
public static final fun serializer (Lkotlin/Unit;)Lkotlinx/serialization/KSerializer;
149153
public static final fun serializer (Lkotlin/jvm/internal/BooleanCompanionObject;)Lkotlinx/serialization/KSerializer;
150154
public static final fun serializer (Lkotlin/jvm/internal/ByteCompanionObject;)Lkotlinx/serialization/KSerializer;
@@ -242,11 +246,13 @@ public abstract interface class kotlinx/serialization/descriptors/SerialDescript
242246
public abstract fun getKind ()Lkotlinx/serialization/descriptors/SerialKind;
243247
public abstract fun getSerialName ()Ljava/lang/String;
244248
public abstract fun isElementOptional (I)Z
249+
public abstract fun isInline ()Z
245250
public abstract fun isNullable ()Z
246251
}
247252

248253
public final class kotlinx/serialization/descriptors/SerialDescriptor$DefaultImpls {
249254
public static fun getAnnotations (Lkotlinx/serialization/descriptors/SerialDescriptor;)Ljava/util/List;
255+
public static fun isInline (Lkotlinx/serialization/descriptors/SerialDescriptor;)Z
250256
public static fun isNullable (Lkotlinx/serialization/descriptors/SerialDescriptor;)Z
251257
}
252258

@@ -315,6 +321,8 @@ public abstract class kotlinx/serialization/encoding/AbstractDecoder : kotlinx/s
315321
public fun decodeEnum (Lkotlinx/serialization/descriptors/SerialDescriptor;)I
316322
public fun decodeFloat ()F
317323
public final fun decodeFloatElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)F
324+
public fun decodeInline (Lkotlinx/serialization/descriptors/SerialDescriptor;)Lkotlinx/serialization/encoding/Decoder;
325+
public final fun decodeInlineElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)Lkotlinx/serialization/encoding/Decoder;
318326
public fun decodeInt ()I
319327
public final fun decodeIntElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)I
320328
public fun decodeLong ()J
@@ -352,6 +360,8 @@ public abstract class kotlinx/serialization/encoding/AbstractEncoder : kotlinx/s
352360
public fun encodeEnum (Lkotlinx/serialization/descriptors/SerialDescriptor;I)V
353361
public fun encodeFloat (F)V
354362
public final fun encodeFloatElement (Lkotlinx/serialization/descriptors/SerialDescriptor;IF)V
363+
public fun encodeInline (Lkotlinx/serialization/descriptors/SerialDescriptor;)Lkotlinx/serialization/encoding/Encoder;
364+
public final fun encodeInlineElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)Lkotlinx/serialization/encoding/Encoder;
355365
public fun encodeInt (I)V
356366
public final fun encodeIntElement (Lkotlinx/serialization/descriptors/SerialDescriptor;II)V
357367
public fun encodeLong (J)V
@@ -382,6 +392,7 @@ public abstract interface class kotlinx/serialization/encoding/CompositeDecoder
382392
public abstract fun decodeDoubleElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)D
383393
public abstract fun decodeElementIndex (Lkotlinx/serialization/descriptors/SerialDescriptor;)I
384394
public abstract fun decodeFloatElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)F
395+
public abstract fun decodeInlineElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)Lkotlinx/serialization/encoding/Decoder;
385396
public abstract fun decodeIntElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)I
386397
public abstract fun decodeLongElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)J
387398
public abstract fun decodeNullableSerializableElement (Lkotlinx/serialization/descriptors/SerialDescriptor;ILkotlinx/serialization/DeserializationStrategy;Ljava/lang/Object;)Ljava/lang/Object;
@@ -411,6 +422,7 @@ public abstract interface class kotlinx/serialization/encoding/CompositeEncoder
411422
public abstract fun encodeCharElement (Lkotlinx/serialization/descriptors/SerialDescriptor;IC)V
412423
public abstract fun encodeDoubleElement (Lkotlinx/serialization/descriptors/SerialDescriptor;ID)V
413424
public abstract fun encodeFloatElement (Lkotlinx/serialization/descriptors/SerialDescriptor;IF)V
425+
public abstract fun encodeInlineElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)Lkotlinx/serialization/encoding/Encoder;
414426
public abstract fun encodeIntElement (Lkotlinx/serialization/descriptors/SerialDescriptor;II)V
415427
public abstract fun encodeLongElement (Lkotlinx/serialization/descriptors/SerialDescriptor;IJ)V
416428
public abstract fun encodeNullableSerializableElement (Lkotlinx/serialization/descriptors/SerialDescriptor;ILkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V
@@ -434,6 +446,7 @@ public abstract interface class kotlinx/serialization/encoding/Decoder {
434446
public abstract fun decodeDouble ()D
435447
public abstract fun decodeEnum (Lkotlinx/serialization/descriptors/SerialDescriptor;)I
436448
public abstract fun decodeFloat ()F
449+
public abstract fun decodeInline (Lkotlinx/serialization/descriptors/SerialDescriptor;)Lkotlinx/serialization/encoding/Decoder;
437450
public abstract fun decodeInt ()I
438451
public abstract fun decodeLong ()J
439452
public abstract fun decodeNotNullMark ()Z
@@ -463,6 +476,7 @@ public abstract interface class kotlinx/serialization/encoding/Encoder {
463476
public abstract fun encodeDouble (D)V
464477
public abstract fun encodeEnum (Lkotlinx/serialization/descriptors/SerialDescriptor;I)V
465478
public abstract fun encodeFloat (F)V
479+
public abstract fun encodeInline (Lkotlinx/serialization/descriptors/SerialDescriptor;)Lkotlinx/serialization/encoding/Encoder;
466480
public abstract fun encodeInt (I)V
467481
public abstract fun encodeLong (J)V
468482
public abstract fun encodeNotNullMark ()V
@@ -691,6 +705,13 @@ public final class kotlinx/serialization/internal/HashSetSerializer : kotlinx/se
691705
public synthetic fun toResult (Ljava/lang/Object;)Ljava/lang/Object;
692706
}
693707

708+
public final class kotlinx/serialization/internal/InlineClassDescriptor : kotlinx/serialization/internal/PluginGeneratedSerialDescriptor {
709+
public fun <init> (Ljava/lang/String;Lkotlinx/serialization/internal/GeneratedSerializer;)V
710+
public fun equals (Ljava/lang/Object;)Z
711+
public fun hashCode ()I
712+
public fun isInline ()Z
713+
}
714+
694715
public final class kotlinx/serialization/internal/IntArrayBuilder : kotlinx/serialization/internal/PrimitiveArrayBuilder {
695716
public synthetic fun build$kotlinx_serialization_core ()Ljava/lang/Object;
696717
}
@@ -878,6 +899,7 @@ public class kotlinx/serialization/internal/PluginGeneratedSerialDescriptor : ko
878899
public fun getSerialNames ()Ljava/util/Set;
879900
public fun hashCode ()I
880901
public fun isElementOptional (I)Z
902+
public fun isInline ()Z
881903
public fun isNullable ()Z
882904
public final fun pushAnnotation (Ljava/lang/annotation/Annotation;)V
883905
public final fun pushClassAnnotation (Ljava/lang/annotation/Annotation;)V
@@ -975,6 +997,8 @@ public abstract class kotlinx/serialization/internal/TaggedDecoder : kotlinx/ser
975997
public final fun decodeEnum (Lkotlinx/serialization/descriptors/SerialDescriptor;)I
976998
public final fun decodeFloat ()F
977999
public final fun decodeFloatElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)F
1000+
public final fun decodeInline (Lkotlinx/serialization/descriptors/SerialDescriptor;)Lkotlinx/serialization/encoding/Decoder;
1001+
public final fun decodeInlineElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)Lkotlinx/serialization/encoding/Decoder;
9781002
public final fun decodeInt ()I
9791003
public final fun decodeIntElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)I
9801004
public final fun decodeLong ()J
@@ -997,6 +1021,7 @@ public abstract class kotlinx/serialization/internal/TaggedDecoder : kotlinx/ser
9971021
protected fun decodeTaggedDouble (Ljava/lang/Object;)D
9981022
protected fun decodeTaggedEnum (Ljava/lang/Object;Lkotlinx/serialization/descriptors/SerialDescriptor;)I
9991023
protected fun decodeTaggedFloat (Ljava/lang/Object;)F
1024+
protected fun decodeTaggedInline (Ljava/lang/Object;Lkotlinx/serialization/descriptors/SerialDescriptor;)Lkotlinx/serialization/encoding/Decoder;
10001025
protected fun decodeTaggedInt (Ljava/lang/Object;)I
10011026
protected fun decodeTaggedLong (Ljava/lang/Object;)J
10021027
protected fun decodeTaggedNotNullMark (Ljava/lang/Object;)Z
@@ -1028,6 +1053,8 @@ public abstract class kotlinx/serialization/internal/TaggedEncoder : kotlinx/ser
10281053
public final fun encodeEnum (Lkotlinx/serialization/descriptors/SerialDescriptor;I)V
10291054
public final fun encodeFloat (F)V
10301055
public final fun encodeFloatElement (Lkotlinx/serialization/descriptors/SerialDescriptor;IF)V
1056+
public final fun encodeInline (Lkotlinx/serialization/descriptors/SerialDescriptor;)Lkotlinx/serialization/encoding/Encoder;
1057+
public final fun encodeInlineElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)Lkotlinx/serialization/encoding/Encoder;
10311058
public final fun encodeInt (I)V
10321059
public final fun encodeIntElement (Lkotlinx/serialization/descriptors/SerialDescriptor;II)V
10331060
public final fun encodeLong (J)V
@@ -1048,6 +1075,7 @@ public abstract class kotlinx/serialization/internal/TaggedEncoder : kotlinx/ser
10481075
protected fun encodeTaggedDouble (Ljava/lang/Object;D)V
10491076
protected fun encodeTaggedEnum (Ljava/lang/Object;Lkotlinx/serialization/descriptors/SerialDescriptor;I)V
10501077
protected fun encodeTaggedFloat (Ljava/lang/Object;F)V
1078+
protected fun encodeTaggedInline (Ljava/lang/Object;Lkotlinx/serialization/descriptors/SerialDescriptor;)Lkotlinx/serialization/encoding/Encoder;
10511079
protected fun encodeTaggedInt (Ljava/lang/Object;I)V
10521080
protected fun encodeTaggedLong (Ljava/lang/Object;J)V
10531081
protected fun encodeTaggedNull (Ljava/lang/Object;)V
@@ -1074,6 +1102,42 @@ public final class kotlinx/serialization/internal/TripleSerializer : kotlinx/ser
10741102
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lkotlin/Triple;)V
10751103
}
10761104

1105+
public final class kotlinx/serialization/internal/UByteSerializer : kotlinx/serialization/KSerializer {
1106+
public static final field INSTANCE Lkotlinx/serialization/internal/UByteSerializer;
1107+
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
1108+
public fun deserialize-Wa3L5BU (Lkotlinx/serialization/encoding/Decoder;)B
1109+
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
1110+
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
1111+
public fun serialize-EK-6454 (Lkotlinx/serialization/encoding/Encoder;B)V
1112+
}
1113+
1114+
public final class kotlinx/serialization/internal/UIntSerializer : kotlinx/serialization/KSerializer {
1115+
public static final field INSTANCE Lkotlinx/serialization/internal/UIntSerializer;
1116+
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
1117+
public fun deserialize-OGnWXxg (Lkotlinx/serialization/encoding/Decoder;)I
1118+
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
1119+
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
1120+
public fun serialize-Qn1smSk (Lkotlinx/serialization/encoding/Encoder;I)V
1121+
}
1122+
1123+
public final class kotlinx/serialization/internal/ULongSerializer : kotlinx/serialization/KSerializer {
1124+
public static final field INSTANCE Lkotlinx/serialization/internal/ULongSerializer;
1125+
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
1126+
public fun deserialize-I7RO_PI (Lkotlinx/serialization/encoding/Decoder;)J
1127+
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
1128+
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
1129+
public fun serialize-2TYgG_w (Lkotlinx/serialization/encoding/Encoder;J)V
1130+
}
1131+
1132+
public final class kotlinx/serialization/internal/UShortSerializer : kotlinx/serialization/KSerializer {
1133+
public static final field INSTANCE Lkotlinx/serialization/internal/UShortSerializer;
1134+
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
1135+
public fun deserialize-BwKQO78 (Lkotlinx/serialization/encoding/Decoder;)S
1136+
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
1137+
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
1138+
public fun serialize-i8woANY (Lkotlinx/serialization/encoding/Encoder;S)V
1139+
}
1140+
10771141
public final class kotlinx/serialization/internal/UnitSerializer : kotlinx/serialization/KSerializer {
10781142
public static final field INSTANCE Lkotlinx/serialization/internal/UnitSerializer;
10791143
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;

core/commonMain/src/kotlinx/serialization/builtins/BuiltinSerializers.kt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,3 +190,30 @@ public fun <K, V> MapSerializer(
190190
valueSerializer: KSerializer<V>
191191
): KSerializer<Map<K, V>> = LinkedHashMapSerializer(keySerializer, valueSerializer)
192192

193+
/**
194+
* Returns serializer for [UInt].
195+
*/
196+
@ExperimentalSerializationApi
197+
@ExperimentalUnsignedTypes
198+
public fun UInt.Companion.serializer(): KSerializer<UInt> = UIntSerializer
199+
200+
/**
201+
* Returns serializer for [ULong].
202+
*/
203+
@ExperimentalSerializationApi
204+
@ExperimentalUnsignedTypes
205+
public fun ULong.Companion.serializer(): KSerializer<ULong> = ULongSerializer
206+
207+
/**
208+
* Returns serializer for [UByte].
209+
*/
210+
@ExperimentalSerializationApi
211+
@ExperimentalUnsignedTypes
212+
public fun UByte.Companion.serializer(): KSerializer<UByte> = UByteSerializer
213+
214+
/**
215+
* Returns serializer for [UShort].
216+
*/
217+
@ExperimentalSerializationApi
218+
@ExperimentalUnsignedTypes
219+
public fun UShort.Companion.serializer(): KSerializer<UShort> = UShortSerializer

core/commonMain/src/kotlinx/serialization/descriptors/SerialDescriptor.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,12 @@ public interface SerialDescriptor {
161161
@ExperimentalSerializationApi
162162
public val isNullable: Boolean get() = false
163163

164+
/**
165+
* Returns `true` if this descriptor describes a serializable inline class.
166+
*/
167+
@ExperimentalSerializationApi
168+
public val isInline: Boolean get() = false
169+
164170
/**
165171
* The number of elements this descriptor describes, besides from the class itself.
166172
* [elementsCount] describes the number of **semantic** elements, not the number

core/commonMain/src/kotlinx/serialization/encoding/AbstractDecoder.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ public abstract class AbstractDecoder : Decoder, CompositeDecoder {
3434
override fun decodeString(): String = decodeValue() as String
3535
override fun decodeEnum(enumDescriptor: SerialDescriptor): Int = decodeValue() as Int
3636

37+
override fun decodeInline(inlineDescriptor: SerialDescriptor): Decoder = this
38+
3739
// overwrite by default
3840
public open fun <T : Any?> decodeSerializableValue(
3941
deserializer: DeserializationStrategy<T>,
@@ -55,6 +57,11 @@ public abstract class AbstractDecoder : Decoder, CompositeDecoder {
5557
final override fun decodeCharElement(descriptor: SerialDescriptor, index: Int): Char = decodeChar()
5658
final override fun decodeStringElement(descriptor: SerialDescriptor, index: Int): String = decodeString()
5759

60+
final override fun decodeInlineElement(
61+
descriptor: SerialDescriptor,
62+
index: Int
63+
): Decoder = decodeInline(descriptor.getElementDescriptor(index))
64+
5865
final override fun <T> decodeSerializableElement(
5966
descriptor: SerialDescriptor,
6067
index: Int,

core/commonMain/src/kotlinx/serialization/encoding/AbstractEncoder.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package kotlinx.serialization.encoding
77
import kotlinx.serialization.*
88
import kotlinx.serialization.descriptors.*
99
import kotlinx.serialization.modules.*
10+
import kotlinx.serialization.internal.*
1011

1112
/**
1213
* A skeleton implementation of both [Encoder] and [CompositeEncoder] that can be used
@@ -50,6 +51,8 @@ public abstract class AbstractEncoder : Encoder, CompositeEncoder {
5051
override fun encodeString(value: String): Unit = encodeValue(value)
5152
override fun encodeEnum(enumDescriptor: SerialDescriptor, index: Int): Unit = encodeValue(index)
5253

54+
override fun encodeInline(inlineDescriptor: SerialDescriptor): Encoder = this
55+
5356
// Delegating implementation of CompositeEncoder
5457
final override fun encodeBooleanElement(descriptor: SerialDescriptor, index: Int, value: Boolean) { if (encodeElement(descriptor, index)) encodeBoolean(value) }
5558
final override fun encodeByteElement(descriptor: SerialDescriptor, index: Int, value: Byte) { if (encodeElement(descriptor, index)) encodeByte(value) }
@@ -61,6 +64,12 @@ public abstract class AbstractEncoder : Encoder, CompositeEncoder {
6164
final override fun encodeCharElement(descriptor: SerialDescriptor, index: Int, value: Char) { if (encodeElement(descriptor, index)) encodeChar(value) }
6265
final override fun encodeStringElement(descriptor: SerialDescriptor, index: Int, value: String) { if (encodeElement(descriptor, index)) encodeString(value) }
6366

67+
final override fun encodeInlineElement(
68+
descriptor: SerialDescriptor,
69+
index: Int
70+
): Encoder =
71+
if (encodeElement(descriptor, index)) encodeInline(descriptor.getElementDescriptor(index)) else NoOpEncoder
72+
6473
final override fun <T : Any?> encodeSerializableElement(
6574
descriptor: SerialDescriptor,
6675
index: Int,

0 commit comments

Comments
 (0)