From 3c4a0c5f824b16a421cbb7e2e2979c023191dc9b Mon Sep 17 00:00:00 2001 From: "Sergey.Shanshin" Date: Tue, 13 Dec 2022 14:32:25 +0100 Subject: [PATCH] Removed strict rule `-dontwarn java.lang.ClassValue` The `-dontwarn java.lang.ClassValue` rule embedded in serialization may have a side effect for the target application if it uses `java.lang.ClassValue` too. Instead of this rule, it is enough to disable warnings for ClassValue inheritors in the serialization itself. Resolves #2119 --- .../kotlinx/serialization/internal/Caching.kt | 48 +++++++++---------- rules/common.pro | 7 ++- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/core/jvmMain/src/kotlinx/serialization/internal/Caching.kt b/core/jvmMain/src/kotlinx/serialization/internal/Caching.kt index 8116f9b2d2..a95d77967f 100644 --- a/core/jvmMain/src/kotlinx/serialization/internal/Caching.kt +++ b/core/jvmMain/src/kotlinx/serialization/internal/Caching.kt @@ -40,41 +40,41 @@ internal actual fun createParametrizedCache(factory: (KClass, List(private val compute: (KClass<*>) -> KSerializer?) : SerializerCache { - private val classValue = initClassValue() - - private fun initClassValue() = object : ClassValue>() { - /* - * Since during the computing of the value for the `ClassValue` entry, we do not know whether a nullable - * serializer is needed, so we may need to differentiate nullable/non-null caches by a level higher - */ - override fun computeValue(type: Class<*>): CacheEntry { - return CacheEntry(compute(type.kotlin)) - } - } +private class ClassValueCache(compute: (KClass<*>) -> KSerializer?) : SerializerCache { + private val classValue = ClassValueWrapper(compute) override fun get(key: KClass): KSerializer? = classValue[key.java].serializer } @SuppressAnimalSniffer -private class ClassValueParametrizedCache(private val compute: (KClass, List) -> KSerializer?) : ParametrizedSerializerCache { - private val classValue = initClassValue() - - private fun initClassValue() = object : ClassValue>() { - /* - * Since during the computing of the value for the `ClassValue` entry, we do not know whether a nullable - * serializer is needed, so we may need to differentiate nullable/non-null caches by a level higher - */ - override fun computeValue(type: Class<*>): ParametrizedCacheEntry { - return ParametrizedCacheEntry() - } +private class ClassValueWrapper(private val compute: (KClass<*>) -> KSerializer?): ClassValue>() { + /* + * Since during the computing of the value for the `ClassValue` entry, we do not know whether a nullable + * serializer is needed, so we may need to differentiate nullable/non-null caches by a level higher + */ + override fun computeValue(type: Class<*>): CacheEntry { + return CacheEntry(compute(type.kotlin)) } +} + +private class ClassValueParametrizedCache(private val compute: (KClass, List) -> KSerializer?) : ParametrizedSerializerCache { + private val classValue = ParametrizedClassValueWrapper() override fun get(key: KClass, types: List): Result?> = classValue[key.java].computeIfAbsent(types) { compute(key, types) } } +@SuppressAnimalSniffer +private class ParametrizedClassValueWrapper : ClassValue>() { + /* + * Since during the computing of the value for the `ClassValue` entry, we do not know whether a nullable + * serializer is needed, so we may need to differentiate nullable/non-null caches by a level higher + */ + override fun computeValue(type: Class<*>): ParametrizedCacheEntry { + return ParametrizedCacheEntry() + } +} + /** * We no longer support Java 6, so the only place we use this cache is Android, where there * are no classloader leaks issue, thus we can safely use strong references and do not bother diff --git a/rules/common.pro b/rules/common.pro index 149093de1d..c703473594 100644 --- a/rules/common.pro +++ b/rules/common.pro @@ -29,5 +29,8 @@ # See also https://github.com/Kotlin/kotlinx.serialization/issues/1900 -dontnote kotlinx.serialization.** -# Serialization core uses `Class.forName("java.lang.ClassValue")` for caching in JVM-only, so it is an expected situation that this class is not in Android --dontwarn java.lang.ClassValue +# Serialization core uses `java.lang.ClassValue` for caching inside these specified classes. +# If there is no `java.lang.ClassValue` (for example, in Android), then R8/ProGuard will print a warning. +# However, since in this case they will not be used, we can disable these warnings +-dontwarn kotlinx.serialization.internal.ClassValueWrapper +-dontwarn kotlinx.serialization.internal.ParametrizedClassValueWrapper