Merge pull request #1 from InsanusMokrassar/0.1.2

0.1.2
This commit is contained in:
InsanusMokrassar 2020-02-15 12:18:26 +06:00 committed by GitHub
commit 5076e16954
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 90 additions and 69 deletions

View File

@ -1,5 +1,11 @@
# SDI changelogs
## 0.1.2
* All reflection support methods are internal
* Added `loadModule` functions for more useful working with modules loading
* `Module` now is not serializable and can be created only via `loadModule` functions (at least, for some time)
## 0.1.1
* Added opportunity to create objects inside of config:

View File

@ -36,7 +36,7 @@ kotlin {
commonMain {
dependencies {
implementation kotlin('stdlib')
api "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
api kotlin('reflect')
api "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$kotlin_serialisation_runtime_version"
}
}

View File

@ -0,0 +1,10 @@
package com.insanusmokrassar.sdi
import kotlinx.serialization.ImplicitReflectionSerializer
import kotlinx.serialization.json.Json
@ImplicitReflectionSerializer
fun Json.loadModule(json: String): Module = parse(ModuleDeserializerStrategy, json)
@ImplicitReflectionSerializer
fun loadModule(json: String): Module = Json.nonstrict.loadModule(json)

View File

@ -0,0 +1,5 @@
package com.insanusmokrassar.sdi
import kotlinx.serialization.ContextualSerialization
class Module internal constructor(base: Map<String, @ContextualSerialization Any>) : Map<String, Any> by base

View File

@ -1,19 +1,13 @@
package com.insanusmokrassar.sdi
import com.insanusmokrassar.sdi.utils.*
import com.insanusmokrassar.sdi.utils.createModuleBasedOnConfigRoot
import kotlinx.serialization.*
import kotlinx.serialization.internal.*
import kotlinx.serialization.internal.HashMapSerializer
import kotlinx.serialization.internal.StringSerializer
import kotlinx.serialization.json.*
import kotlinx.serialization.modules.*
import kotlin.reflect.KClass
@ImplicitReflectionSerializer
@Serializable(ModuleSerializer::class)
class Module(base: Map<String, @ContextualSerialization Any>) : Map<String, Any> by base
@ImplicitReflectionSerializer
@Serializer(Module::class)
internal object ModuleSerializer : KSerializer<Module> {
internal object ModuleDeserializerStrategy : DeserializationStrategy<Module> {
private val internalSerializer = HashMapSerializer(StringSerializer, ContextSerializer(Any::class))
override val descriptor: SerialDescriptor
get() = internalSerializer.descriptor
@ -28,7 +22,5 @@ internal object ModuleSerializer : KSerializer<Module> {
return Module(map)
}
override fun serialize(encoder: Encoder, obj: Module) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun patch(decoder: Decoder, old: Module): Module = throw UpdateNotSupportedException("Module")
}

View File

@ -2,7 +2,8 @@ package com.insanusmokrassar.sdi.utils
import kotlinx.serialization.*
import kotlinx.serialization.json.*
import kotlinx.serialization.modules.*
import kotlinx.serialization.modules.SerializerAlreadyRegisteredException
import kotlinx.serialization.modules.SerializersModuleBuilder
import kotlin.reflect.KClass
@ImplicitReflectionSerializer
@ -13,7 +14,7 @@ internal class DependencyResolver<T : Any>(
private val dependencyGetter: (String) -> Any
) : KSerializer<T> {
private val originalSerializer: KSerializer<T> = try {
resolveSerializerByKClass(kClass)
kClass.serializer()
} catch (e: Exception) {
PolymorphicSerializer(kClass)
}

View File

@ -1,8 +1,9 @@
package com.insanusmokrassar.sdi.utils
import kotlinx.serialization.*
import kotlinx.serialization.ImplicitReflectionSerializer
import kotlinx.serialization.json.*
import kotlinx.serialization.modules.*
import kotlinx.serialization.modules.SerializerAlreadyRegisteredException
import kotlinx.serialization.modules.SerializersModule
private typealias PackageOrOtherDependencyNamePair = Pair<String?, String?>
@ -63,25 +64,26 @@ internal fun createModuleBasedOnConfigRoot(jsonObject: JsonObject): Json {
key to packageName
}.toMap()
return Json(
configuration = JsonConfiguration(useArrayPolymorphism = true),
context = SerializersModule {
keysToPackages.values.forEach {
val kclass = resolveKClassByPackageName(it)
val context = SerializersModule {
keysToPackages.values.forEach {
val kclass = resolveKClassByPackageName(it)
try {
DependencyResolver(
this,
kclass,
{ jsonStringFormat }
) {
caches.getValue(it).invoke()
}
} catch (e: SerializerAlreadyRegisteredException) {
// here we are thinking that already registered
try {
DependencyResolver(
this,
kclass,
{ jsonStringFormat }
) {
caches.getValue(it).invoke()
}
} catch (e: SerializerAlreadyRegisteredException) {
// here we are thinking that already registered
}
}
}
return Json(
configuration = JsonConfiguration(useArrayPolymorphism = true),
context = context
).also {
jsonStringFormat = it
}

View File

@ -1,24 +1,22 @@
package com.insanusmokrassar.sdi.utils
import kotlinx.serialization.ImplicitReflectionSerializer
import kotlinx.serialization.KSerializer
import kotlinx.serialization.*
import kotlin.reflect.KClass
import kotlin.reflect.KType
internal expect fun resolveKClassByPackageName(packageName: String): KClass<*>
@ImplicitReflectionSerializer
expect fun resolveSerializerByPackageName(packageName: String): KSerializer<*>
internal fun <T : Any> resolveSerializerByKClass(kClass: KClass<T>): KSerializer<T> = kClass.serializer()
@ImplicitReflectionSerializer
expect fun <T : Any> resolveSerializerByKClass(kClass: KClass<T>): KSerializer<T>
internal fun resolveSerializerByPackageName(packageName: String): KSerializer<*> = resolveSerializerByKClass(
resolveKClassByPackageName(packageName)
)
expect fun resolveKClassByPackageName(packageName: String): KClass<*>
expect val KClass<*>.currentSupertypes: List<KType>
val KClass<*>.allSubclasses: Set<KClass<*>>
internal val KClass<*>.allSubclasses: Set<KClass<*>>
get() {
val subclasses = mutableSetOf<KClass<*>>()
val leftToVisit = currentSupertypes.mapNotNull { it.classifier as? KClass<*> }.toMutableList()
val leftToVisit = supertypes.mapNotNull { it.classifier as? KClass<*> }.toMutableList()
while (leftToVisit.isNotEmpty()) {
val top = leftToVisit.removeAt(0)
if (subclasses.add(top)) {

View File

@ -2,7 +2,8 @@ package com.insanusmokrassar.sdi
import kotlinx.serialization.*
import kotlinx.serialization.json.Json
import kotlin.test.*
import kotlin.test.Test
import kotlin.test.assertEquals
interface List_ParentalAPI {
val services: List<List_ChildAPI>
@ -44,7 +45,7 @@ class ListTest {
]
}
""".trimIndent()
val module = Json.plain.parse(Module.serializer(), input)
val module = loadModule(input)
(module[controllerName] as List_ParentalAPI)
val controller = (module[controllerName] as List_Parent)
controller.services.forEachIndexed { i, service ->

View File

@ -2,7 +2,8 @@ package com.insanusmokrassar.sdi
import kotlinx.serialization.*
import kotlinx.serialization.json.Json
import kotlin.test.*
import kotlin.test.Test
import kotlin.test.assertEquals
interface SimpleCustomObject_ControllerAPI {
fun showUp()
@ -78,7 +79,7 @@ class SimpleCustomObjectTest {
]
}
""".trimIndent()
val module = Json.plain.parse(Module.serializer(), input)
val module = loadModule(input)
(module[controllerName] as SimpleCustomObject_ControllerAPI)
val controller = (module["controller"] as SimpleCustomObject_Controller)

View File

@ -2,7 +2,8 @@ package com.insanusmokrassar.sdi
import kotlinx.serialization.*
import kotlinx.serialization.json.Json
import kotlin.test.*
import kotlin.test.Test
import kotlin.test.assertEquals
interface Simple_ControllerAPI {
fun showUp()
@ -42,7 +43,7 @@ class SimpleTest {
]
}
""".trimIndent()
val module = Json.plain.parse(Module.serializer(), input)
val module = loadModule(input)
(module[controllerName] as Simple_ControllerAPI)
val controller = (module["controller"] as Simple_Controller)
assertEquals(names.toList(), controller.service.names)

View File

@ -0,0 +1,18 @@
package com.insanusmokrassar.sdi
import kotlinx.io.InputStream
import kotlinx.serialization.ImplicitReflectionSerializer
import kotlinx.serialization.json.Json
import java.io.File
@ImplicitReflectionSerializer
fun Json.loadModule(stream: InputStream) = loadModule(stream.reader().readText())
@ImplicitReflectionSerializer
fun loadModule(stream: InputStream) = Json.nonstrict.loadModule(stream.reader().readText())
@ImplicitReflectionSerializer
fun Json.loadModule(file: File) = loadModule(file.inputStream())
@ImplicitReflectionSerializer
fun loadModule(file: File) = Json.nonstrict.loadModule(file.inputStream())

View File

@ -1,7 +0,0 @@
package com.insanusmokrassar.sdi.utils
import kotlin.reflect.KClass
import kotlin.reflect.KType
actual val KClass<*>.currentSupertypes: List<KType>
get() = this.supertypes

View File

@ -0,0 +1,5 @@
package com.insanusmokrassar.sdi.utils
import kotlin.reflect.KClass
actual fun resolveKClassByPackageName(packageName: String): KClass<*> = Class.forName(packageName).kotlin

View File

@ -1,12 +0,0 @@
package com.insanusmokrassar.sdi.utils
import kotlinx.serialization.*
import kotlin.reflect.KClass
@ImplicitReflectionSerializer
actual fun resolveSerializerByPackageName(packageName: String): KSerializer<*> = Class.forName(packageName).kotlin.serializer()
@ImplicitReflectionSerializer
actual fun <T : Any> resolveSerializerByKClass(kClass: KClass<T>): KSerializer<T> = kClass.serializer()
actual fun resolveKClassByPackageName(packageName: String): KClass<*> = Class.forName(packageName).kotlin