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.builtins.MapSerializer
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.typeOf0
import net.mamoe.mirai.console.setting.internal.valueFromKTypeImpl
import net.mamoe.mirai.console.setting.internal.valueImpl
import net.mamoe.mirai.utils.MiraiExperimentalAPI
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.typeOf
import kotlin.reflect.jvm.isAccessible
// 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.
* 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])
*/
@LowPriorityInOverloadResolution
@MiraiExperimentalAPI
@OptIn(ExperimentalStdlibApi::class) // stable in 1.4
inline fun <reified T> Setting.valueReified(default: T): SerializerAwareValue<T> =
valueFromKTypeImpl(typeOf<T>()).cast()
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>()}")
)
@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.

View File

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

View File

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