Rename valueReified to value;

Introduce public valueFromKType;
Fix CompositeListValueImpl
This commit is contained in:
Him188 2020-06-24 04:08:53 +08:00
parent 1425378e19
commit d120bfe576
3 changed files with 38 additions and 16 deletions

View File

@ -14,17 +14,16 @@ package net.mamoe.mirai.console.setting
import kotlinx.serialization.* import kotlinx.serialization.*
import kotlinx.serialization.builtins.MapSerializer import kotlinx.serialization.builtins.MapSerializer
import kotlinx.serialization.builtins.serializer import kotlinx.serialization.builtins.serializer
import net.mamoe.mirai.console.setting.internal.cast
import net.mamoe.mirai.console.setting.internal.isOdd 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.valueFromKTypeImpl
import net.mamoe.mirai.console.setting.internal.valueImpl import net.mamoe.mirai.console.setting.internal.valueImpl
import net.mamoe.mirai.utils.MiraiExperimentalAPI
import net.mamoe.yamlkt.YamlNullableDynamicSerializer import net.mamoe.yamlkt.YamlNullableDynamicSerializer
import kotlin.internal.LowPriorityInOverloadResolution import kotlin.internal.LowPriorityInOverloadResolution
import kotlin.reflect.KProperty import kotlin.reflect.KProperty
import kotlin.reflect.KType import kotlin.reflect.KType
import kotlin.reflect.full.findAnnotation import kotlin.reflect.full.findAnnotation
import kotlin.reflect.typeOf import kotlin.reflect.jvm.isAccessible
// TODO: 2020/6/21 move to JvmPlugin to inherit SettingStorage and CoroutineScope for saving // TODO: 2020/6/21 move to JvmPlugin to inherit SettingStorage and CoroutineScope for saving
@ -162,7 +161,21 @@ fun Setting.value(default: String): SerializerAwareValue<String> = valueImpl(def
/** /**
* Creates a [Value] with reified type. * Creates a [Value] with reified type, and set default value.
*
* @param T reified param type T.
* Supports only primitives, Kotlin built-in collections,
* and classes that are serializable with Kotlinx.serialization
* (typically annotated with [kotlinx.serialization.Serializable])
*/
@Suppress("UNCHECKED_CAST")
@LowPriorityInOverloadResolution
inline fun <reified T> Setting.value(default: T): SerializerAwareValue<T> =
value<T>().apply { value = default }
/**
* Creates a [Value] with reified type, and set default value by reflection to its no-arg public constructor.
* *
* @param T reified param type T. * @param T reified param type T.
* Supports only primitives, Kotlin built-in collections, * Supports only primitives, Kotlin built-in collections,
@ -170,12 +183,17 @@ fun Setting.value(default: String): SerializerAwareValue<String> = valueImpl(def
* (typically annotated with [kotlinx.serialization.Serializable]) * (typically annotated with [kotlinx.serialization.Serializable])
*/ */
@LowPriorityInOverloadResolution @LowPriorityInOverloadResolution
@MiraiExperimentalAPI inline fun <reified T> Setting.value(): SerializerAwareValue<T> =
@OptIn(ExperimentalStdlibApi::class) // stable in 1.4 value(
inline fun <reified T> Setting.valueReified(default: T): SerializerAwareValue<T> = T::class.constructors.find { it.parameters.isEmpty() && it.isAccessible }?.call()
valueFromKTypeImpl(typeOf<T>()).cast() ?: throw IllegalArgumentException("Cannot construct a default value for given type ${typeOf0<T>()}")
)
@MiraiExperimentalAPI /**
fun <T> Setting.valueFromKType(type: KType): SerializerAwareValue<T> = valueFromKTypeImpl(type).cast() * Creates a [Value] with specified [KType], and set default value.
*/
@Suppress("UNCHECKED_CAST")
fun <T> Setting.valueFromKType(type: KType, default: T): SerializerAwareValue<T> =
(valueFromKTypeImpl(type) as SerializerAwareValue<Any?>).apply { this.value = default } as SerializerAwareValue<T>
// TODO: 2020/6/24 Introduce class TypeToken for compound types for Java. // TODO: 2020/6/24 Introduce class TypeToken for compound types for Java.

View File

@ -26,6 +26,10 @@ private val primitiveCollectionsImplemented by lazy {
false false
} }
@PublishedApi
@OptIn(ExperimentalStdlibApi::class)
internal inline fun <reified T> typeOf0(): KType = kotlin.reflect.typeOf<T>()
@PublishedApi @PublishedApi
@Suppress("UnsafeCall", "SMARTCAST_IMPOSSIBLE", "UNCHECKED_CAST") @Suppress("UnsafeCall", "SMARTCAST_IMPOSSIBLE", "UNCHECKED_CAST")
internal fun Setting.valueFromKTypeImpl(type: KType): SerializerAwareValue<*> { internal fun Setting.valueFromKTypeImpl(type: KType): SerializerAwareValue<*> {
@ -54,8 +58,8 @@ internal fun Setting.valueFromKTypeImpl(type: KType): SerializerAwareValue<*> {
TODO() TODO()
} else { } else {
return createCompositeMapValueImpl<Any?, Any?>( return createCompositeMapValueImpl<Any?, Any?>(
kToValue = { k -> valueFromKType<Any?>(type.arguments[0].type!!).also { it.value = k } }, kToValue = { k -> valueFromKType(type.arguments[0].type!!, k) },
vToValue = { v -> valueFromKType<Any?>(type.arguments[1].type!!).also { it.value = v } } vToValue = { v -> valueFromKType(type.arguments[1].type!!, v) }
).serializableValueWith(serializerMirai(type) as KSerializer<Map<Any?, Any?>>) // erased ).serializableValueWith(serializerMirai(type) as KSerializer<Map<Any?, Any?>>) // erased
} }
} }
@ -72,7 +76,7 @@ internal fun Setting.valueFromKTypeImpl(type: KType): SerializerAwareValue<*> {
// ... // ...
TODO() TODO()
} else { } else {
return createCompositeListValueImpl<Any?> { valueFromKType(type.arguments[0].type!!) } return createCompositeListValueImpl<Any?> { v -> valueFromKType(type.arguments[0].type!!, v) }
.serializableValueWith(serializerMirai(type) as KSerializer<List<Any?>>) .serializableValueWith(serializerMirai(type) as KSerializer<List<Any?>>)
} }
} }
@ -87,7 +91,7 @@ internal fun Setting.valueFromKTypeImpl(type: KType): SerializerAwareValue<*> {
// ... // ...
TODO() TODO()
} else { } else {
return createCompositeSetValueImpl<Any?> { valueFromKType(type.arguments[0].type!!) } return createCompositeSetValueImpl<Any?> { v -> valueFromKType(type.arguments[0].type!!, v) }
.serializableValueWith(serializerMirai(type) as KSerializer<Set<Any?>>) .serializableValueWith(serializerMirai(type) as KSerializer<Set<Any?>>)
} }
} }

View File

@ -20,8 +20,8 @@ internal class SettingTest {
class MySetting : Setting() { class MySetting : Setting() {
var int by value(1) var int by value(1)
val map by valueReified(mapOf("" to "")) val map by value(mapOf("" to ""))
val map2 by valueReified(mutableMapOf("" to mutableMapOf("" to ""))) val map2 by value(mutableMapOf("" to mutableMapOf("" to "")))
} }
@OptIn(UnstableDefault::class) @OptIn(UnstableDefault::class)