diff options
4 files changed, 85 insertions, 41 deletions
diff --git a/core/api/kotlinx-serialization-core.api b/core/api/kotlinx-serialization-core.api index 9159db42..4aab661b 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 <init> (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 <init> (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 <init> (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 <init> (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 <init> (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 <init> (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 <init> (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 fbd16c58..fcf4cfa7 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<Element, Collection, Builder> : } @PublishedApi -internal sealed class ListLikeSerializer<Element, Collection, Builder>( +internal sealed class CollectionLikeSerializer<Element, Collection, Builder>( private val elementSerializer: KSerializer<Element> ) : AbstractCollectionSerializer<Element, Collection, Builder>() { @@ -70,13 +70,13 @@ internal sealed class ListLikeSerializer<Element, Collection, Builder>( } } - 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<Array> internal constructor() { internal abstract class PrimitiveArraySerializer<Element, Array, Builder : PrimitiveArrayBuilder<Array>> internal constructor( primitiveSerializer: KSerializer<Element> -) : ListLikeSerializer<Element, Array, Builder>(primitiveSerializer) { +) : CollectionLikeSerializer<Element, Array, Builder>(primitiveSerializer) { final override val descriptor: SerialDescriptor = PrimitiveArrayDescriptor(primitiveSerializer.descriptor) final override fun Builder.builderSize(): Int = position @@ -160,7 +160,7 @@ internal abstract class PrimitiveArraySerializer<Element, Array, Builder protected abstract fun empty(): Array - protected abstract override fun readElement( + abstract override fun readElement( decoder: CompositeDecoder, index: Int, builder: Builder, @@ -184,7 +184,7 @@ internal abstract class PrimitiveArraySerializer<Element, Array, Builder internal class ReferenceArraySerializer<ElementKlass : Any, Element : ElementKlass?>( private val kClass: KClass<ElementKlass>, eSerializer: KSerializer<Element> -) : ListLikeSerializer<Element, Array<Element>, ArrayList<Element>>(eSerializer) { +) : CollectionLikeSerializer<Element, Array<Element>, ArrayList<Element>>(eSerializer) { override val descriptor: SerialDescriptor = ArrayClassDesc(eSerializer.descriptor) override fun Array<Element>.collectionSize(): Int = size @@ -202,12 +202,17 @@ internal class ReferenceArraySerializer<ElementKlass : Any, Element : ElementKla } } +@PublishedApi +internal abstract class CollectionSerializer<E, C: Collection<E>, B>(element: KSerializer<E>) : CollectionLikeSerializer<E, C, B>(element) { + override fun C.collectionSize(): Int = size + override fun C.collectionIterator(): Iterator<E> = iterator() +} + @InternalSerializationApi @PublishedApi -internal class ArrayListSerializer<E>(element: KSerializer<E>) : ListLikeSerializer<E, List<E>, ArrayList<E>>(element) { +internal class ArrayListSerializer<E>(element: KSerializer<E>) : CollectionSerializer<E, List<E>, ArrayList<E>>(element) { override val descriptor: SerialDescriptor = ArrayListClassDesc(element.descriptor) - override fun List<E>.collectionSize(): Int = size - override fun List<E>.collectionIterator(): Iterator<E> = iterator() + override fun builder(): ArrayList<E> = arrayListOf() override fun ArrayList<E>.builderSize(): Int = size override fun ArrayList<E>.toResult(): List<E> = this @@ -219,11 +224,9 @@ internal class ArrayListSerializer<E>(element: KSerializer<E>) : ListLikeSeriali @PublishedApi internal class LinkedHashSetSerializer<E>( eSerializer: KSerializer<E> -) : ListLikeSerializer<E, Set<E>, LinkedHashSet<E>>(eSerializer) { - +) : CollectionSerializer<E, Set<E>, LinkedHashSet<E>>(eSerializer) { override val descriptor: SerialDescriptor = LinkedHashSetClassDesc(eSerializer.descriptor) - override fun Set<E>.collectionSize(): Int = size - override fun Set<E>.collectionIterator(): Iterator<E> = iterator() + override fun builder(): LinkedHashSet<E> = linkedSetOf() override fun LinkedHashSet<E>.builderSize(): Int = size override fun LinkedHashSet<E>.toResult(): Set<E> = this @@ -235,11 +238,9 @@ internal class LinkedHashSetSerializer<E>( @PublishedApi internal class HashSetSerializer<E>( eSerializer: KSerializer<E> -) : ListLikeSerializer<E, Set<E>, HashSet<E>>(eSerializer) { - +) : CollectionSerializer<E, Set<E>, HashSet<E>>(eSerializer) { override val descriptor: SerialDescriptor = HashSetClassDesc(eSerializer.descriptor) - override fun Set<E>.collectionSize(): Int = size - override fun Set<E>.collectionIterator(): Iterator<E> = iterator() + override fun builder(): HashSet<E> = HashSet() override fun HashSet<E>.builderSize(): Int = size override fun HashSet<E>.toResult(): Set<E> = this diff --git a/core/commonTest/src/kotlinx/serialization/SealedGenericClassesTest.kt b/core/commonTest/src/kotlinx/serialization/SealedGenericClassesTest.kt index 150ab7a7..7840cd23 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 00000000..ca8116a0 --- /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<String> + ) + + @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<CollectionWrapper>(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<CollectionWrapper>(string) + assertEquals(set.toList(), wrapper.collection) + } +} |