1
0
mirror of https://github.com/mamoe/mirai.git synced 2025-03-28 16:50:09 +08:00

Support auto-constructing for builtin types

This commit is contained in:
Him188 2020-06-24 04:18:32 +08:00
parent 5adda00be0
commit 7048013c5f
2 changed files with 30 additions and 15 deletions
backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting

View File

@ -14,16 +14,12 @@ package net.mamoe.mirai.console.setting
import kotlinx.serialization.*
import kotlinx.serialization.builtins.MapSerializer
import kotlinx.serialization.builtins.serializer
import net.mamoe.mirai.console.setting.internal.isOdd
import net.mamoe.mirai.console.setting.internal.typeOf0
import net.mamoe.mirai.console.setting.internal.valueFromKTypeImpl
import net.mamoe.mirai.console.setting.internal.valueImpl
import net.mamoe.mirai.console.setting.internal.*
import net.mamoe.yamlkt.YamlNullableDynamicSerializer
import kotlin.internal.LowPriorityInOverloadResolution
import kotlin.reflect.KProperty
import kotlin.reflect.KType
import kotlin.reflect.full.findAnnotation
import kotlin.reflect.jvm.isAccessible
// TODO: 2020/6/21 move to JvmPlugin to inherit SettingStorage and CoroutineScope for saving
@ -170,9 +166,7 @@ fun Setting.value(default: String): SerializerAwareValue<String> = valueImpl(def
*/
@Suppress("UNCHECKED_CAST")
@LowPriorityInOverloadResolution
inline fun <reified T> Setting.value(default: T): SerializerAwareValue<T> =
value<T>().apply { value = default }
inline fun <reified T> Setting.value(default: T): SerializerAwareValue<T> = valueFromKType(typeOf0<T>(), default)
/**
* Creates a [Value] with reified type, and set default value by reflection to its no-arg public constructor.
@ -183,11 +177,7 @@ inline fun <reified T> Setting.value(default: T): SerializerAwareValue<T> =
* (typically annotated with [kotlinx.serialization.Serializable])
*/
@LowPriorityInOverloadResolution
inline fun <reified T> Setting.value(): SerializerAwareValue<T> =
value(
T::class.constructors.find { it.parameters.isEmpty() && it.isAccessible }?.call()
?: throw IllegalArgumentException("Cannot construct a default value for given type ${typeOf0<T>()}")
)
inline fun <reified T> Setting.value(): SerializerAwareValue<T> = value(T::class.createInstance() as T)
/**
* Creates a [Value] with specified [KType], and set default value.

View File

@ -21,6 +21,7 @@ import net.mamoe.yamlkt.YamlDynamicSerializer
import net.mamoe.yamlkt.YamlNullableDynamicSerializer
import kotlin.reflect.KClass
import kotlin.reflect.KType
import kotlin.reflect.full.createInstance as createInstanceKotlin
private val primitiveCollectionsImplemented by lazy {
false
@ -40,7 +41,7 @@ internal fun Setting.valueFromKTypeImpl(type: KType): SerializerAwareValue<*> {
return valueImplPrimitive(classifier) as SerializerAwareValue<*>
}
// 复合类型
// TODO: 2020/6/24 优化性能: 预先根据类型生成 V -> Value<V> 的 mapper
when (classifier) {
MutableMap::class,
@ -102,12 +103,36 @@ internal fun Setting.valueFromKTypeImpl(type: KType): SerializerAwareValue<*> {
}
}
@PublishedApi
internal fun KClass<*>.createInstance(): Any? {
return when (this) {
MutableMap::class,
Map::class,
LinkedHashMap::class,
HashMap::class
-> mutableMapOf<Any?, Any?>()
MutableList::class,
List::class,
ArrayList::class
-> mutableListOf<Any?>()
MutableSet::class,
Set::class,
LinkedHashSet::class,
HashSet::class
-> mutableSetOf<Any?>()
else -> createInstanceKotlin()
}
}
internal fun KClass<*>.isPrimitiveOrBuiltInSerializableValue(): Boolean {
when (this) {
Byte::class, Short::class, Int::class, Long::class,
Boolean::class,
Char::class, String::class,
Pair::class, Triple::class
Pair::class, Triple::class // TODO: 2020/6/24 支持 PairValue, TripleValue
-> return true
}