diff --git a/core/api/kotlinx-serialization-core.api b/core/api/kotlinx-serialization-core.api index 9159db420..4aab661b6 100644 --- a/core/api/kotlinx-serialization-core.api +++ b/core/api/kotlinx-serialization-core.api @@ -542,13 +542,11 @@ public abstract class kotlinx/serialization/internal/AbstractPolymorphicSerializ public final fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V } -public final class kotlinx/serialization/internal/ArrayListSerializer : kotlinx/serialization/internal/ListLikeSerializer { +public final class kotlinx/serialization/internal/ArrayListSerializer : kotlinx/serialization/internal/CollectionSerializer { public fun (Lkotlinx/serialization/KSerializer;)V public synthetic fun builder ()Ljava/lang/Object; public synthetic fun builderSize (Ljava/lang/Object;)I public synthetic fun checkCapacity (Ljava/lang/Object;I)V - public synthetic fun collectionIterator (Ljava/lang/Object;)Ljava/util/Iterator; - public synthetic fun collectionSize (Ljava/lang/Object;)I public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; public synthetic fun insert (Ljava/lang/Object;ILjava/lang/Object;)V public synthetic fun toBuilder (Ljava/lang/Object;)Ljava/lang/Object; @@ -624,6 +622,23 @@ public final class kotlinx/serialization/internal/CharSerializer : kotlinx/seria public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V } +public abstract class kotlinx/serialization/internal/CollectionLikeSerializer : kotlinx/serialization/internal/AbstractCollectionSerializer { + public synthetic fun (Lkotlinx/serialization/KSerializer;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public abstract fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + protected abstract fun insert (Ljava/lang/Object;ILjava/lang/Object;)V + protected final fun readAll (Lkotlinx/serialization/encoding/CompositeDecoder;Ljava/lang/Object;II)V + protected fun readElement (Lkotlinx/serialization/encoding/CompositeDecoder;ILjava/lang/Object;Z)V + public fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V +} + +public abstract class kotlinx/serialization/internal/CollectionSerializer : kotlinx/serialization/internal/CollectionLikeSerializer { + public fun (Lkotlinx/serialization/KSerializer;)V + public synthetic fun collectionIterator (Ljava/lang/Object;)Ljava/util/Iterator; + protected fun collectionIterator (Ljava/util/Collection;)Ljava/util/Iterator; + public synthetic fun collectionSize (Ljava/lang/Object;)I + protected fun collectionSize (Ljava/util/Collection;)I +} + public final class kotlinx/serialization/internal/DoubleArrayBuilder : kotlinx/serialization/internal/PrimitiveArrayBuilder { public synthetic fun build$kotlinx_serialization_core ()Ljava/lang/Object; } @@ -717,13 +732,11 @@ public final class kotlinx/serialization/internal/HashMapSerializer : kotlinx/se public synthetic fun toResult (Ljava/lang/Object;)Ljava/lang/Object; } -public final class kotlinx/serialization/internal/HashSetSerializer : kotlinx/serialization/internal/ListLikeSerializer { +public final class kotlinx/serialization/internal/HashSetSerializer : kotlinx/serialization/internal/CollectionSerializer { public fun (Lkotlinx/serialization/KSerializer;)V public synthetic fun builder ()Ljava/lang/Object; public synthetic fun builderSize (Ljava/lang/Object;)I public synthetic fun checkCapacity (Ljava/lang/Object;I)V - public synthetic fun collectionIterator (Ljava/lang/Object;)Ljava/util/Iterator; - public synthetic fun collectionSize (Ljava/lang/Object;)I public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; public synthetic fun insert (Ljava/lang/Object;ILjava/lang/Object;)V public synthetic fun toBuilder (Ljava/lang/Object;)Ljava/lang/Object; @@ -788,28 +801,17 @@ public final class kotlinx/serialization/internal/LinkedHashMapSerializer : kotl public synthetic fun toResult (Ljava/lang/Object;)Ljava/lang/Object; } -public final class kotlinx/serialization/internal/LinkedHashSetSerializer : kotlinx/serialization/internal/ListLikeSerializer { +public final class kotlinx/serialization/internal/LinkedHashSetSerializer : kotlinx/serialization/internal/CollectionSerializer { public fun (Lkotlinx/serialization/KSerializer;)V public synthetic fun builder ()Ljava/lang/Object; public synthetic fun builderSize (Ljava/lang/Object;)I public synthetic fun checkCapacity (Ljava/lang/Object;I)V - public synthetic fun collectionIterator (Ljava/lang/Object;)Ljava/util/Iterator; - public synthetic fun collectionSize (Ljava/lang/Object;)I public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; public synthetic fun insert (Ljava/lang/Object;ILjava/lang/Object;)V public synthetic fun toBuilder (Ljava/lang/Object;)Ljava/lang/Object; public synthetic fun toResult (Ljava/lang/Object;)Ljava/lang/Object; } -public abstract class kotlinx/serialization/internal/ListLikeSerializer : kotlinx/serialization/internal/AbstractCollectionSerializer { - public synthetic fun (Lkotlinx/serialization/KSerializer;Lkotlin/jvm/internal/DefaultConstructorMarker;)V - public abstract fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - protected abstract fun insert (Ljava/lang/Object;ILjava/lang/Object;)V - protected final fun readAll (Lkotlinx/serialization/encoding/CompositeDecoder;Ljava/lang/Object;II)V - protected fun readElement (Lkotlinx/serialization/encoding/CompositeDecoder;ILjava/lang/Object;Z)V - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V -} - public final class kotlinx/serialization/internal/LongArrayBuilder : kotlinx/serialization/internal/PrimitiveArrayBuilder { public synthetic fun build$kotlinx_serialization_core ()Ljava/lang/Object; } @@ -935,7 +937,7 @@ public class kotlinx/serialization/internal/PluginGeneratedSerialDescriptor : ko public abstract class kotlinx/serialization/internal/PrimitiveArrayBuilder { } -public abstract class kotlinx/serialization/internal/PrimitiveArraySerializer : kotlinx/serialization/internal/ListLikeSerializer { +public abstract class kotlinx/serialization/internal/PrimitiveArraySerializer : kotlinx/serialization/internal/CollectionLikeSerializer { public synthetic fun builder ()Ljava/lang/Object; protected final fun builder ()Lkotlinx/serialization/internal/PrimitiveArrayBuilder; public synthetic fun builderSize (Ljava/lang/Object;)I @@ -955,7 +957,7 @@ public abstract class kotlinx/serialization/internal/PrimitiveArraySerializer : protected abstract fun writeContent (Lkotlinx/serialization/encoding/CompositeEncoder;Ljava/lang/Object;I)V } -public final class kotlinx/serialization/internal/ReferenceArraySerializer : kotlinx/serialization/internal/ListLikeSerializer { +public final class kotlinx/serialization/internal/ReferenceArraySerializer : kotlinx/serialization/internal/CollectionLikeSerializer { public fun (Lkotlin/reflect/KClass;Lkotlinx/serialization/KSerializer;)V public synthetic fun builder ()Ljava/lang/Object; public synthetic fun builderSize (Ljava/lang/Object;)I diff --git a/core/commonMain/src/kotlinx/serialization/internal/CollectionSerializers.kt b/core/commonMain/src/kotlinx/serialization/internal/CollectionSerializers.kt index fbd16c58a..fcf4cfa74 100644 --- a/core/commonMain/src/kotlinx/serialization/internal/CollectionSerializers.kt +++ b/core/commonMain/src/kotlinx/serialization/internal/CollectionSerializers.kt @@ -54,7 +54,7 @@ public sealed class AbstractCollectionSerializer : } @PublishedApi -internal sealed class ListLikeSerializer( +internal sealed class CollectionLikeSerializer( private val elementSerializer: KSerializer ) : AbstractCollectionSerializer() { @@ -70,13 +70,13 @@ internal sealed class ListLikeSerializer( } } - protected final override fun readAll(decoder: CompositeDecoder, builder: Builder, startIndex: Int, size: Int) { + final override fun readAll(decoder: CompositeDecoder, builder: Builder, startIndex: Int, size: Int) { require(size >= 0) { "Size must be known in advance when using READ_ALL" } for (index in 0 until size) readElement(decoder, startIndex + index, builder, checkIndex = false) } - protected override fun readElement(decoder: CompositeDecoder, index: Int, builder: Builder, checkIndex: Boolean) { + override fun readElement(decoder: CompositeDecoder, index: Int, builder: Builder, checkIndex: Boolean) { builder.insert(index, decoder.decodeSerializableElement(descriptor, index, elementSerializer)) } } @@ -143,7 +143,7 @@ internal abstract class PrimitiveArrayBuilder internal constructor() { internal abstract class PrimitiveArraySerializer> internal constructor( primitiveSerializer: KSerializer -) : ListLikeSerializer(primitiveSerializer) { +) : CollectionLikeSerializer(primitiveSerializer) { final override val descriptor: SerialDescriptor = PrimitiveArrayDescriptor(primitiveSerializer.descriptor) final override fun Builder.builderSize(): Int = position @@ -160,7 +160,7 @@ internal abstract class PrimitiveArraySerializer( private val kClass: KClass, eSerializer: KSerializer -) : ListLikeSerializer, ArrayList>(eSerializer) { +) : CollectionLikeSerializer, ArrayList>(eSerializer) { override val descriptor: SerialDescriptor = ArrayClassDesc(eSerializer.descriptor) override fun Array.collectionSize(): Int = size @@ -202,12 +202,17 @@ internal class ReferenceArraySerializer, B>(element: KSerializer) : CollectionLikeSerializer(element) { + override fun C.collectionSize(): Int = size + override fun C.collectionIterator(): Iterator = iterator() +} + @InternalSerializationApi @PublishedApi -internal class ArrayListSerializer(element: KSerializer) : ListLikeSerializer, ArrayList>(element) { +internal class ArrayListSerializer(element: KSerializer) : CollectionSerializer, ArrayList>(element) { override val descriptor: SerialDescriptor = ArrayListClassDesc(element.descriptor) - override fun List.collectionSize(): Int = size - override fun List.collectionIterator(): Iterator = iterator() + override fun builder(): ArrayList = arrayListOf() override fun ArrayList.builderSize(): Int = size override fun ArrayList.toResult(): List = this @@ -219,11 +224,9 @@ internal class ArrayListSerializer(element: KSerializer) : ListLikeSeriali @PublishedApi internal class LinkedHashSetSerializer( eSerializer: KSerializer -) : ListLikeSerializer, LinkedHashSet>(eSerializer) { - +) : CollectionSerializer, LinkedHashSet>(eSerializer) { override val descriptor: SerialDescriptor = LinkedHashSetClassDesc(eSerializer.descriptor) - override fun Set.collectionSize(): Int = size - override fun Set.collectionIterator(): Iterator = iterator() + override fun builder(): LinkedHashSet = linkedSetOf() override fun LinkedHashSet.builderSize(): Int = size override fun LinkedHashSet.toResult(): Set = this @@ -235,11 +238,9 @@ internal class LinkedHashSetSerializer( @PublishedApi internal class HashSetSerializer( eSerializer: KSerializer -) : ListLikeSerializer, HashSet>(eSerializer) { - +) : CollectionSerializer, HashSet>(eSerializer) { override val descriptor: SerialDescriptor = HashSetClassDesc(eSerializer.descriptor) - override fun Set.collectionSize(): Int = size - override fun Set.collectionIterator(): Iterator = iterator() + override fun builder(): HashSet = HashSet() override fun HashSet.builderSize(): Int = size override fun HashSet.toResult(): Set = this diff --git a/core/commonTest/src/kotlinx/serialization/SealedGenericClassesTest.kt b/core/commonTest/src/kotlinx/serialization/SealedGenericClassesTest.kt index 150ab7a7f..7840cd236 100644 --- a/core/commonTest/src/kotlinx/serialization/SealedGenericClassesTest.kt +++ b/core/commonTest/src/kotlinx/serialization/SealedGenericClassesTest.kt @@ -31,13 +31,13 @@ class SealedGenericClassesTest { // Test that compilation and retrieval is successful @Test fun testQuery() { - val serial1 = Query.SimpleQuery.serializer(String.serializer()) - val serial2 = Query.serializer(UnitSerializer) + Query.SimpleQuery.serializer(String.serializer()) + Query.serializer(UnitSerializer) } @Test fun testFetcher() { - val serial1 = Fetcher.SomethingFetcher.serializer() - val serial2 = Fetcher.serializer(Something.serializer()) + Fetcher.SomethingFetcher.serializer() + Fetcher.serializer(Something.serializer()) } } diff --git a/formats/json/commonTest/src/kotlinx/serialization/features/CollectionSerializerTest.kt b/formats/json/commonTest/src/kotlinx/serialization/features/CollectionSerializerTest.kt new file mode 100644 index 000000000..ca8116a0b --- /dev/null +++ b/formats/json/commonTest/src/kotlinx/serialization/features/CollectionSerializerTest.kt @@ -0,0 +1,41 @@ +/* + * Copyright 2017-2022 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +package kotlinx.serialization.features + +import kotlinx.serialization.* +import kotlinx.serialization.builtins.* +import kotlinx.serialization.json.Json +import kotlinx.serialization.test.* +import kotlin.test.* + +class CollectionSerializerTest { + + @Serializable + data class CollectionWrapper( + val collection: Collection + ) + + @Test + fun testListJson() { + val list = listOf("foo", "bar", "foo", "bar") + + val string = Json.encodeToString(CollectionWrapper(list)) + assertEquals("""{"collection":["foo","bar","foo","bar"]}""", string) + + val wrapper = Json.decodeFromString(string) + assertEquals(list, wrapper.collection) + } + + @Test + fun testSetJson() { + val set = setOf("foo", "bar", "foo", "bar") + + val string = Json.encodeToString(CollectionWrapper(set)) + assertEquals("""{"collection":["foo","bar"]}""", string) + + val wrapper = Json.decodeFromString(string) + assertEquals(set.toList(), wrapper.collection) + } +}