Add diagnostic to check whether provided custom serializer matches

type of the property.

Check for serializer type mismatch only when custom serializer is present

Otherwise, there are too many false positives on e.g. PolymorphicSerializer

#KT-36329 Fixed

Fixes https://github.com/Kotlin/kotlinx.serialization/issues/830
This commit is contained in:
Leonid Startsev
2020-09-08 19:45:19 +03:00
parent bc432ecb85
commit fe5dbf75fa
8 changed files with 140 additions and 4 deletions
@@ -18,4 +18,7 @@ object EnumSerializer: KSerializer<ExplicitlyMarkedEnumCustom> {
override val descriptor = TODO()
override fun serialize(encoder: Encoder, value: ExplicitlyMarkedEnumCustom) = TODO()
override fun deserialize(decoder: Decoder): ExplicitlyMarkedEnumCustom = TODO()
}
}
@Serializable
data class EnumUsage(val s: SimpleEnum, val m: MarkedNameEnum, val e: ExplicitlyMarkedEnum)
@@ -11,6 +11,42 @@ public object EnumSerializer : kotlinx.serialization.KSerializer<ExplicitlyMarke
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@kotlinx.serialization.Serializable public final data class EnumUsage {
public constructor EnumUsage(/*0*/ s: SimpleEnum, /*1*/ m: MarkedNameEnum, /*2*/ e: ExplicitlyMarkedEnum)
@kotlin.Deprecated(level = DeprecationLevel.HIDDEN, message = "This synthesized declaration should not be used directly", replaceWith = kotlin.ReplaceWith(expression = "", imports = {})) public /*synthesized*/ constructor EnumUsage(/*0*/ seen1: kotlin.Int, /*1*/ s: SimpleEnum?, /*2*/ m: MarkedNameEnum?, /*3*/ e: ExplicitlyMarkedEnum?, /*4*/ serializationConstructorMarker: kotlinx.serialization.internal.SerializationConstructorMarker?)
public final val e: ExplicitlyMarkedEnum
public final val m: MarkedNameEnum
public final val s: SimpleEnum
public final operator /*synthesized*/ fun component1(): SimpleEnum
public final operator /*synthesized*/ fun component2(): MarkedNameEnum
public final operator /*synthesized*/ fun component3(): ExplicitlyMarkedEnum
public final /*synthesized*/ fun copy(/*0*/ s: SimpleEnum = ..., /*1*/ m: MarkedNameEnum = ..., /*2*/ e: ExplicitlyMarkedEnum = ...): EnumUsage
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
@kotlin.Deprecated(level = DeprecationLevel.HIDDEN, message = "This synthesized declaration should not be used directly", replaceWith = kotlin.ReplaceWith(expression = "", imports = {})) public object `$serializer` : kotlinx.serialization.internal.GeneratedSerializer<EnumUsage> {
private constructor `$serializer`()
public open override /*1*/ /*synthesized*/ val descriptor: kotlinx.serialization.descriptors.SerialDescriptor
public open override /*1*/ /*synthesized*/ fun childSerializers(): kotlin.Array<kotlinx.serialization.KSerializer<*>>
public open override /*1*/ /*synthesized*/ fun deserialize(/*0*/ decoder: kotlinx.serialization.encoding.Decoder): EnumUsage
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@kotlin.Deprecated(level = DeprecationLevel.ERROR, message = "Patch function is deprecated for removal since this functionality is no longer supported by serializer.Some formats may provide implementation-specific patching in their Decoders.") public open override /*1*/ /*fake_override*/ fun patch(/*0*/ decoder: kotlinx.serialization.encoding.Decoder, /*1*/ old: EnumUsage): EnumUsage
public open override /*1*/ /*synthesized*/ fun serialize(/*0*/ encoder: kotlinx.serialization.encoding.Encoder, /*1*/ value: EnumUsage): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public open override /*1*/ /*fake_override*/ fun typeParametersSerializers(): kotlin.Array<kotlinx.serialization.KSerializer<*>>
}
public companion object Companion {
private constructor Companion()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final /*synthesized*/ fun serializer(): kotlinx.serialization.KSerializer<EnumUsage>
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
@kotlinx.serialization.Serializable public final enum class ExplicitlyMarkedEnum : kotlin.Enum<ExplicitlyMarkedEnum> {
@kotlinx.serialization.SerialName(value = "a") enum entry A
@@ -0,0 +1,18 @@
// WITH_RUNTIME
// SKIP_TXT
import kotlinx.serialization.*
class Bar
@Serializer(forClass = Bar::class)
object BarSerializer: KSerializer<Bar>
class Baz
@Serializer(forClass = Baz::class)
object BazSerializer: KSerializer<Baz>
@Serializable
class Foo1(@Polymorphic val i: Baz)
@Serializable
class Foo2(val li: MutableList<@Serializable(with = BazSerializer::class) Baz>)
@@ -0,0 +1,35 @@
// WITH_RUNTIME
// SKIP_TXT
import kotlinx.serialization.*
class Bar
@Serializer(forClass = Bar::class)
object BarSerializer: KSerializer<Bar>
class Baz
@Serializer(forClass = Baz::class)
object BazSerializer: KSerializer<Baz>
@Serializer(forClass = Baz::class)
object NullableBazSerializer: KSerializer<Baz?>
@Serializable
class Foo(@Serializable(with = BazSerializer::class) val i: <!SERIALIZER_TYPE_INCOMPATIBLE!>Bar<!>)
@Serializable
class Foo2(val li: List<@Serializable(with = BazSerializer::class) <!SERIALIZER_TYPE_INCOMPATIBLE!>Bar<!>>)
@Serializable
class Foo3(@Serializable(with = BazSerializer::class) val i: Baz)
@Serializable
class Foo4(val li: List<@Serializable(with = BazSerializer::class) Baz>)
@Serializable
class Foo5(@Serializable(with = BazSerializer::class) val i: <!SERIALIZER_TYPE_INCOMPATIBLE!>Bar?<!>)
@Serializable
class Foo6(@Serializable(with = NullableBazSerializer::class) val i: <!SERIALIZER_NULLABILITY_INCOMPATIBLE, SERIALIZER_TYPE_INCOMPATIBLE!>Bar<!>)
@Serializable
class Foo7(@Serializable(with = NullableBazSerializer::class) val i: <!SERIALIZER_TYPE_INCOMPATIBLE!>Bar?<!>)