From e0aa2b4456149df3c6009870bb6c90830665393a Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Thu, 12 Nov 2020 00:44:19 +0600 Subject: [PATCH] experimentally add SDIIncluded --- build.gradle | 5 ++++ gradle.properties | 1 + .../kotlin/dev/inmo/sdi/HelperTools.kt | 7 ++++++ .../kotlin/dev/inmo/sdi/SDIIncluded.kt | 25 +++++++++++++++++++ .../dev/inmo/sdi/utils/JsonAdaptations.kt | 15 +++++++++-- .../kotlin/dev/inmo/sdi/ListTest.kt | 1 + .../dev/inmo/sdi/SimpleCustomObjectTest.kt | 1 + .../kotlin/dev/inmo/sdi/SimpleTest.kt | 1 + .../kotlin/dev/inmo/sdi/JVMHelperTools.kt | 3 +++ .../dev/inmo/sdi/SDIIncludedRealization.kt | 18 +++++++++++++ 10 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 src/commonMain/kotlin/dev/inmo/sdi/SDIIncluded.kt create mode 100644 src/jvmMain/kotlin/dev/inmo/sdi/SDIIncludedRealization.kt diff --git a/build.gradle b/build.gradle index 48d1c16..ba67907 100644 --- a/build.gradle +++ b/build.gradle @@ -46,6 +46,11 @@ kotlin { implementation kotlin('test-annotations-common') } } + jvmMain { + dependencies { + api "org.atteo.classindex:classindex:$classindex_version" + } + } jvmTest { dependencies { implementation kotlin('test-junit') diff --git a/gradle.properties b/gradle.properties index 38473de..79ca913 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,7 @@ kotlin.code.style=official kotlin_version=1.4.10 kotlin_serialisation_runtime_version=1.0.1 +classindex_version=3.4 gradle_bintray_plugin_version=1.8.5 github_release_plugin_version=2.2.12 diff --git a/src/commonMain/kotlin/dev/inmo/sdi/HelperTools.kt b/src/commonMain/kotlin/dev/inmo/sdi/HelperTools.kt index 43a227f..77b3d37 100644 --- a/src/commonMain/kotlin/dev/inmo/sdi/HelperTools.kt +++ b/src/commonMain/kotlin/dev/inmo/sdi/HelperTools.kt @@ -1,12 +1,18 @@ package dev.inmo.sdi +import kotlinx.serialization.InternalSerializationApi import kotlinx.serialization.json.Json +import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.modules.SerializersModuleBuilder import kotlin.reflect.KClass +@InternalSerializationApi internal val nonStrictJson = Json { isLenient = true ignoreUnknownKeys = true + serializersModule = SerializersModule { + includeClassesForSDI() + } } fun Json.loadModule( @@ -22,6 +28,7 @@ fun Json.loadModule( json ) +@InternalSerializationApi fun loadModule( json: String, vararg additionalClassesToInclude: KClass<*>, diff --git a/src/commonMain/kotlin/dev/inmo/sdi/SDIIncluded.kt b/src/commonMain/kotlin/dev/inmo/sdi/SDIIncluded.kt new file mode 100644 index 0000000..ad2e89d --- /dev/null +++ b/src/commonMain/kotlin/dev/inmo/sdi/SDIIncluded.kt @@ -0,0 +1,25 @@ +package dev.inmo.sdi + +import kotlinx.serialization.InternalSerializationApi +import kotlinx.serialization.modules.SerializersModuleBuilder +import kotlinx.serialization.serializer +import kotlin.reflect.KClass + +@Retention(AnnotationRetention.RUNTIME) +@Target(AnnotationTarget.CLASS) +expect annotation class SDIIncluded(val customNames: Array = []) + +internal expect fun getClassesForIncludingInSDI(): List, List>> + +@Suppress("NOTHING_TO_INLINE") +@InternalSerializationApi +private inline fun KClass.includeInBuilder( + builder: SerializersModuleBuilder +) = builder.contextual(this, serializer()) + +@InternalSerializationApi +fun SerializersModuleBuilder.includeClassesForSDI() { + getClassesForIncludingInSDI().forEach { (kclass, _) -> + kclass.includeInBuilder(this) + } +} diff --git a/src/commonMain/kotlin/dev/inmo/sdi/utils/JsonAdaptations.kt b/src/commonMain/kotlin/dev/inmo/sdi/utils/JsonAdaptations.kt index a76b783..de9580b 100644 --- a/src/commonMain/kotlin/dev/inmo/sdi/utils/JsonAdaptations.kt +++ b/src/commonMain/kotlin/dev/inmo/sdi/utils/JsonAdaptations.kt @@ -1,5 +1,6 @@ package dev.inmo.sdi.utils +import dev.inmo.sdi.getClassesForIncludingInSDI import kotlinx.serialization.InternalSerializationApi import kotlinx.serialization.json.* import kotlinx.serialization.modules.* @@ -7,6 +8,12 @@ import kotlin.reflect.KClass private typealias PackageOrOtherDependencyNamePair = Pair +private val namesToTheirClasses = getClassesForIncludingInSDI().flatMap { + (it.second + it.first.qualifiedName!!).map { name -> + name to it.first.qualifiedName!! + } +}.toMap() + private fun JsonElement.resolvePackageName(currentKey: String, otherDependenciesKeys: Set): PackageOrOtherDependencyNamePair { return when (this) { is JsonPrimitive -> contentOrNull ?.let { @@ -16,8 +23,12 @@ private fun JsonElement.resolvePackageName(currentKey: String, otherDependencies it to null } } ?: throw IllegalArgumentException("Value on dependency name \"$currentKey\" is invalid: provided $this, but expected package name or other dependency name string") - is JsonObject -> return currentKey to null - is JsonArray -> return get(0).jsonPrimitive.contentOrNull ?.let { it to null } ?: throw IllegalArgumentException("Value on first argument of dependency value must be its package as a string, but was provided ${get(0)}") + is JsonObject -> if (currentKey in otherDependenciesKeys) { + null to currentKey + } else { + (namesToTheirClasses[currentKey] ?: currentKey) to null + } + is JsonArray -> return get(0).jsonPrimitive.contentOrNull ?.let { (namesToTheirClasses[it] ?: it) to null } ?: throw IllegalArgumentException("Value on first argument of dependency value must be its package as a string, but was provided ${get(0)}") } } diff --git a/src/commonTest/kotlin/dev/inmo/sdi/ListTest.kt b/src/commonTest/kotlin/dev/inmo/sdi/ListTest.kt index 784a43e..e22ca4c 100644 --- a/src/commonTest/kotlin/dev/inmo/sdi/ListTest.kt +++ b/src/commonTest/kotlin/dev/inmo/sdi/ListTest.kt @@ -19,6 +19,7 @@ class List_Child(override val names: List) : List_ChildAPI class ListTest { val servicesNum = 10 + @InternalSerializationApi @Test fun test_that_simple_config_correctly_work() { val names = (0 until servicesNum).map { diff --git a/src/commonTest/kotlin/dev/inmo/sdi/SimpleCustomObjectTest.kt b/src/commonTest/kotlin/dev/inmo/sdi/SimpleCustomObjectTest.kt index 172d24c..9f5f1c0 100644 --- a/src/commonTest/kotlin/dev/inmo/sdi/SimpleCustomObjectTest.kt +++ b/src/commonTest/kotlin/dev/inmo/sdi/SimpleCustomObjectTest.kt @@ -48,6 +48,7 @@ class SimpleCustomObject_BusinessService(override val names: List) : Sim class SimpleCustomObject_BusinessService1(override val names: List) : SimpleCustomObject_ServiceAPI class SimpleCustomObjectTest { + @InternalSerializationApi @Test fun test_that_simple_config_correctly_work() { val names = arrayOf("nameOne", "nameTwo") diff --git a/src/commonTest/kotlin/dev/inmo/sdi/SimpleTest.kt b/src/commonTest/kotlin/dev/inmo/sdi/SimpleTest.kt index abacfe2..4d66dcd 100644 --- a/src/commonTest/kotlin/dev/inmo/sdi/SimpleTest.kt +++ b/src/commonTest/kotlin/dev/inmo/sdi/SimpleTest.kt @@ -21,6 +21,7 @@ class Simple_Controller(@Contextual val service: Simple_ServiceAPI) : Simple_Con class Simple_BusinessService(override val names: List) : Simple_ServiceAPI class SimpleTest { + @InternalSerializationApi @Test fun test_that_simple_config_correctly_work() { val names = arrayOf("nameOne", "nameTwo") diff --git a/src/jvmMain/kotlin/dev/inmo/sdi/JVMHelperTools.kt b/src/jvmMain/kotlin/dev/inmo/sdi/JVMHelperTools.kt index 8220793..4adc715 100644 --- a/src/jvmMain/kotlin/dev/inmo/sdi/JVMHelperTools.kt +++ b/src/jvmMain/kotlin/dev/inmo/sdi/JVMHelperTools.kt @@ -1,5 +1,6 @@ package dev.inmo.sdi +import kotlinx.serialization.InternalSerializationApi import kotlin.reflect.KClass import kotlinx.serialization.json.Json import kotlinx.serialization.modules.SerializersModuleBuilder @@ -14,6 +15,7 @@ fun Json.loadModule( ) = loadModule(stream.reader().readText(), *additionalClassesToInclude, moduleBuilder = moduleBuilder) +@InternalSerializationApi fun loadModule( stream: InputStream, vararg additionalClassesToInclude: KClass<*>, @@ -28,6 +30,7 @@ fun Json.loadModule( ) = loadModule(file.inputStream(), *additionalClassesToInclude, moduleBuilder = moduleBuilder) +@InternalSerializationApi fun loadModule( file: File, vararg additionalClassesToInclude: KClass<*>, diff --git a/src/jvmMain/kotlin/dev/inmo/sdi/SDIIncludedRealization.kt b/src/jvmMain/kotlin/dev/inmo/sdi/SDIIncludedRealization.kt new file mode 100644 index 0000000..c7409fd --- /dev/null +++ b/src/jvmMain/kotlin/dev/inmo/sdi/SDIIncludedRealization.kt @@ -0,0 +1,18 @@ +package dev.inmo.sdi + +import org.atteo.classindex.ClassIndex +import org.atteo.classindex.IndexAnnotated +import kotlin.reflect.KClass + +@Retention(AnnotationRetention.RUNTIME) +@Target(AnnotationTarget.CLASS) +@IndexAnnotated +actual annotation class SDIIncluded actual constructor(actual val customNames: Array) + +internal actual fun getClassesForIncludingInSDI(): List, List>> = ClassIndex.getAnnotated( + SDIIncluded::class.java +).map { + it.kotlin.let { + it to it.annotations.flatMap { (it as? SDIIncluded) ?.customNames ?.toList() ?: emptyList() } + } +}