summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeonid Startsev <sandwwraith@users.noreply.github.com>2022-09-15 17:19:19 +0300
committerGitHub <noreply@github.com>2022-09-15 17:19:19 +0300
commitf8d605d59f69209e3f3978f2c7682bc9128fd612 (patch)
treeac3939a1824a707f994b4b0c5a6055ebe5392739
parent79de734f60d4efd86d9c3174ba5f212f276ee125 (diff)
downloadkotlinx.serialization-f8d605d59f69209e3f3978f2c7682bc9128fd612.tar.gz
Add functions that can be used by compiler plugin for intrinsics (#2031)
-rw-r--r--build.gradle6
-rw-r--r--core/api/kotlinx-serialization-core.api3
-rw-r--r--core/commonMain/src/kotlinx/serialization/Serializers.kt32
-rw-r--r--core/commonTest/src/kotlinx/serialization/CachedSerializersTest.kt20
-rw-r--r--core/commonTest/src/kotlinx/serialization/SerializersLookupEnumTest.kt16
-rw-r--r--core/commonTest/src/kotlinx/serialization/SerializersLookupObjectTest.kt17
-rw-r--r--formats/json-tests/jvmTest/src/kotlinx/serialization/features/SerializerByTypeTest.kt16
7 files changed, 75 insertions, 35 deletions
diff --git a/build.gradle b/build.gradle
index f363e1d2..fb28ee64 100644
--- a/build.gradle
+++ b/build.gradle
@@ -14,13 +14,15 @@ buildscript {
}
ext.experimentalsEnabled = ["-progressive", "-opt-in=kotlin.Experimental",
"-opt-in=kotlin.ExperimentalMultiplatform",
- "-opt-in=kotlinx.serialization.InternalSerializationApi"
+ "-opt-in=kotlinx.serialization.InternalSerializationApi",
+ "-P", "plugin:org.jetbrains.kotlinx.serialization:disableIntrinsic=false"
]
ext.experimentalsInTestEnabled = ["-progressive", "-opt-in=kotlin.Experimental",
"-opt-in=kotlin.ExperimentalMultiplatform",
"-opt-in=kotlinx.serialization.ExperimentalSerializationApi",
- "-opt-in=kotlinx.serialization.InternalSerializationApi"
+ "-opt-in=kotlinx.serialization.InternalSerializationApi",
+ "-P", "plugin:org.jetbrains.kotlinx.serialization:disableIntrinsic=false"
]
ext.koverEnabled = property('kover.enabled') ?: true
diff --git a/core/api/kotlinx-serialization-core.api b/core/api/kotlinx-serialization-core.api
index bc7bbced..5cddb226 100644
--- a/core/api/kotlinx-serialization-core.api
+++ b/core/api/kotlinx-serialization-core.api
@@ -119,6 +119,9 @@ public abstract interface annotation class kotlinx/serialization/Serializer : ja
}
public final class kotlinx/serialization/SerializersKt {
+ public static final fun noCompiledSerializer (Ljava/lang/String;)Lkotlinx/serialization/KSerializer;
+ public static final fun noCompiledSerializer (Lkotlinx/serialization/modules/SerializersModule;Lkotlin/reflect/KClass;)Lkotlinx/serialization/KSerializer;
+ public static final fun noCompiledSerializer (Lkotlinx/serialization/modules/SerializersModule;Lkotlin/reflect/KClass;[Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer;
public static final fun serializer (Ljava/lang/reflect/Type;)Lkotlinx/serialization/KSerializer;
public static final fun serializer (Lkotlin/reflect/KClass;)Lkotlinx/serialization/KSerializer;
public static final fun serializer (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;
diff --git a/core/commonMain/src/kotlinx/serialization/Serializers.kt b/core/commonMain/src/kotlinx/serialization/Serializers.kt
index 8063e1a8..e89fb33a 100644
--- a/core/commonMain/src/kotlinx/serialization/Serializers.kt
+++ b/core/commonMain/src/kotlinx/serialization/Serializers.kt
@@ -216,3 +216,35 @@ private fun <T : Any> KSerializer<T>.nullable(shouldBeNullable: Boolean): KSeria
if (shouldBeNullable) return nullable
return this as KSerializer<T?>
}
+
+
+/**
+ * Overloads of [noCompiledSerializer] should never be called directly.
+ * Instead, compiler inserts calls to them when intrinsifying [serializer] function.
+ *
+ * If no serializer has been found in compile time, call to [noCompiledSerializer] inserted instead.
+ */
+@Suppress("unused")
+@PublishedApi
+internal fun noCompiledSerializer(forClass: String): KSerializer<*> {
+ throw SerializationException(
+ "Cannot find serializer for class $forClass.\n" +
+ "Make sure that this class marked with @Serializable annotation," +
+ "or provide serializer explicitly, or use proper SerializersModule"
+ )
+}
+
+// Used when compiler intrinsic is inserted
+@OptIn(ExperimentalSerializationApi::class)
+@Suppress("unused")
+@PublishedApi
+internal fun noCompiledSerializer(module: SerializersModule, kClass: KClass<*>): KSerializer<*> {
+ return module.getContextual(kClass) ?: kClass.serializerNotRegistered()
+}
+
+@OptIn(ExperimentalSerializationApi::class)
+@Suppress("unused")
+@PublishedApi
+internal fun noCompiledSerializer(module: SerializersModule, kClass: KClass<*>, argSerializers: Array<KSerializer<*>>): KSerializer<*> {
+ return module.getContextual(kClass, argSerializers.asList()) ?: kClass.serializerNotRegistered()
+}
diff --git a/core/commonTest/src/kotlinx/serialization/CachedSerializersTest.kt b/core/commonTest/src/kotlinx/serialization/CachedSerializersTest.kt
index d04390af..77fa593e 100644
--- a/core/commonTest/src/kotlinx/serialization/CachedSerializersTest.kt
+++ b/core/commonTest/src/kotlinx/serialization/CachedSerializersTest.kt
@@ -4,8 +4,10 @@
package kotlinx.serialization
+import kotlinx.serialization.modules.*
import kotlinx.serialization.test.noJsLegacy
import kotlin.test.*
+import kotlin.time.*
class CachedSerializersTest {
@Serializable
@@ -34,4 +36,22 @@ class CachedSerializersTest {
fun testAbstractSerializersAreSame() = noJsLegacy {
assertSame(Abstract.serializer(), Abstract.serializer())
}
+
+
+ @OptIn(ExperimentalTime::class)
+ @Test
+ @Ignore // TODO: Unignore after 1.8.0 update
+ fun testSerializersAreIntrinsified() {
+ val m = SerializersModule { }
+ val direct = measureTime {
+ Object.serializer()
+ }
+ val directMs = direct.inWholeMicroseconds
+ val indirect = measureTime {
+ m.serializer<Object>()
+ }
+ val indirectMs = indirect.inWholeMicroseconds
+ if (indirectMs > directMs + (directMs / 4)) error("Direct ($directMs) and indirect ($indirectMs) times are too far apart")
+ }
}
+
diff --git a/core/commonTest/src/kotlinx/serialization/SerializersLookupEnumTest.kt b/core/commonTest/src/kotlinx/serialization/SerializersLookupEnumTest.kt
index 4fb61b04..95c6c62b 100644
--- a/core/commonTest/src/kotlinx/serialization/SerializersLookupEnumTest.kt
+++ b/core/commonTest/src/kotlinx/serialization/SerializersLookupEnumTest.kt
@@ -44,9 +44,6 @@ class SerializersLookupEnumTest {
}
}
- @Polymorphic
- enum class EnumPolymorphic
-
@Serializable
enum class PlainEnum
@@ -72,17 +69,4 @@ class SerializersLookupEnumTest {
assertFails { serializer<EnumExternalClass>() }
}
}
-
- @Test
- fun testEnumPolymorphic() {
- if (isJvm()) {
- assertEquals(
- PolymorphicSerializer(EnumPolymorphic::class).descriptor,
- serializer<EnumPolymorphic>().descriptor
- )
- } else {
- // FIXME serializer<PolymorphicEnum> is broken for K/JS and K/Native. Remove `assertFails` after fix
- assertFails { serializer<EnumPolymorphic>() }
- }
- }
}
diff --git a/core/commonTest/src/kotlinx/serialization/SerializersLookupObjectTest.kt b/core/commonTest/src/kotlinx/serialization/SerializersLookupObjectTest.kt
index 49efb912..d4f906d6 100644
--- a/core/commonTest/src/kotlinx/serialization/SerializersLookupObjectTest.kt
+++ b/core/commonTest/src/kotlinx/serialization/SerializersLookupObjectTest.kt
@@ -43,9 +43,6 @@ class SerializersLookupObjectTest {
}
}
- @Polymorphic
- object ObjectPolymorphic
-
@Serializable
object PlainObject
@@ -73,18 +70,4 @@ class SerializersLookupObjectTest {
assertIs<ObjectExternalClassSerializer>(serializer<ObjectExternalClass>())
}
}
-
- @Test
- fun testEnumPolymorphic() {
- if (isJvm()) {
- assertEquals(
- PolymorphicSerializer(ObjectPolymorphic::class).descriptor,
- serializer<ObjectPolymorphic>().descriptor
- )
- } else {
- // FIXME serializer<PolymorphicObject> is broken for K/JS and K/Native. Remove `assertFails` after fix
- assertFails { serializer<ObjectPolymorphic>() }
- }
-
- }
}
diff --git a/formats/json-tests/jvmTest/src/kotlinx/serialization/features/SerializerByTypeTest.kt b/formats/json-tests/jvmTest/src/kotlinx/serialization/features/SerializerByTypeTest.kt
index 5227ca43..450b3f42 100644
--- a/formats/json-tests/jvmTest/src/kotlinx/serialization/features/SerializerByTypeTest.kt
+++ b/formats/json-tests/jvmTest/src/kotlinx/serialization/features/SerializerByTypeTest.kt
@@ -15,6 +15,7 @@ import org.junit.Test
import java.lang.reflect.*
import kotlin.reflect.*
import kotlin.test.*
+import kotlin.time.*
class SerializerByTypeTest {
@@ -283,4 +284,19 @@ class SerializerByTypeTest {
serializer(typeTokenOf<Array<NonSerializable>>())
}
}
+
+ @OptIn(ExperimentalTime::class)
+ @Test
+ @Ignore // TODO: Unignore after 1.8.0 update
+ fun testSerializersAreIntrinsified() {
+ val direct = measureTime {
+ Json.encodeToString(IntData.serializer(), IntData(10))
+ }
+ val directMs = direct.inWholeMicroseconds
+ val indirect = measureTime {
+ Json.encodeToString(IntData(10))
+ }
+ val indirectMs = indirect.inWholeMicroseconds
+ if (indirectMs > directMs + (directMs / 4)) error("Direct ($directMs) and indirect ($indirectMs) times are too far apart")
+ }
}