diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/Setting.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/Setting.kt index 9f45c874f..862c5514f 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/Setting.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/Setting.kt @@ -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. diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/internal/Setting.value composite impl.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/internal/Setting.value composite impl.kt index 3f6927227..12b26af65 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/internal/Setting.value composite impl.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/setting/internal/Setting.value composite impl.kt @@ -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 }