diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/AbstractPluginData.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/AbstractPluginData.kt index 080170e9f..72ca966b2 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/AbstractPluginData.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/AbstractPluginData.kt @@ -24,6 +24,11 @@ import kotlin.reflect.KProperty * @see PluginData */ public abstract class AbstractPluginData : PluginData, PluginDataImpl() { + /** + * 这个 [PluginData] 保存时使用的名称. + */ + public abstract override val saveName: String + /** * 添加了追踪的 [ValueNode] 列表, 即通过 `by value` 初始化的属性列表. * @@ -32,7 +37,7 @@ public abstract class AbstractPluginData : PluginData, PluginDataImpl() { * @see provideDelegate */ @ConsoleExperimentalApi - public override val valueNodes: MutableList> = mutableListOf() + public val valueNodes: MutableList> = mutableListOf() /** * 供手动实现时值跟踪使用 (如 Java 用户). 一般 Kotlin 用户需使用 [provideDelegate] @@ -61,7 +66,7 @@ public abstract class AbstractPluginData : PluginData, PluginDataImpl() { ): T = track(this, property.valueName, property.getAnnotationListForValueSerialization()) /** - * 所有 [valueNodes] 更新和保存序列化器. 仅供内部使用 + * 所有 [valueNodes] 更新和保存序列化器. */ @ConsoleExperimentalApi public final override val updaterSerializer: KSerializer diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/AutoSavePluginConfig.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/AutoSavePluginConfig.kt index f6aa40dfa..df4a4c280 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/AutoSavePluginConfig.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/AutoSavePluginConfig.kt @@ -23,4 +23,10 @@ import kotlinx.coroutines.Job * @see PluginConfig * @see AutoSavePluginData */ -public open class AutoSavePluginConfig : AutoSavePluginData(), PluginConfig \ No newline at end of file +public open class AutoSavePluginConfig : AutoSavePluginData, PluginConfig { + @Deprecated("请手动指定保存名称. 此构造器将在 1.0.0 删除", level = DeprecationLevel.ERROR, replaceWith = ReplaceWith("AutoSavePluginConfig(\"改成保存的名称\")")) + @Suppress("DEPRECATION_ERROR") + public constructor() : super() + + public constructor(saveName: String) : super(saveName) +} diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/AutoSavePluginData.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/AutoSavePluginData.kt index 937a32de4..06410a113 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/AutoSavePluginData.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/AutoSavePluginData.kt @@ -18,6 +18,7 @@ import net.mamoe.mirai.console.internal.command.qualifiedNameOrTip import net.mamoe.mirai.console.internal.plugin.updateWhen import net.mamoe.mirai.console.util.ConsoleExperimentalApi import net.mamoe.mirai.utils.* +import kotlin.reflect.full.findAnnotation /** * 链接自动保存的 [PluginData]. @@ -35,8 +36,22 @@ public open class AutoSavePluginData private constructor( private val autoSaveIntervalMillis_: LongRange get() = owner_.autoSaveIntervalMillis private lateinit var storage_: PluginDataStorage - public constructor() : this(null) + public final override val saveName: String + get() = _saveName + private lateinit var _saveName: String + + public constructor(saveName: String) : this(null) { + _saveName = saveName + } + + @Deprecated("请手动指定保存名称. 此构造器将在 1.0.0 删除", level = DeprecationLevel.ERROR, replaceWith = ReplaceWith("AutoSavePluginConfig")) + public constructor() : this(null) { + val clazz = this::class + _saveName = clazz.findAnnotation()?.value + ?: clazz.qualifiedName + ?: throw IllegalArgumentException("Cannot find a serial name for ${this::class}") + } @ConsoleExperimentalApi override fun onInit(owner: PluginDataHolder, storage: PluginDataStorage) { diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginData.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginData.kt index 705c90996..119b9f2e3 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginData.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginData.kt @@ -32,12 +32,11 @@ import net.mamoe.mirai.console.util.ConsoleExperimentalApi import kotlin.internal.LowPriorityInOverloadResolution import kotlin.reflect.KClass import kotlin.reflect.KType -import kotlin.reflect.full.findAnnotation /** - * 一个插件内部的, 对用户隐藏的数据对象. 可包含对多个 [Value] 的值变更的跟踪. + * 一个插件内部的, 对用户隐藏的数据对象. 可包含对多个 [Value] 的值变更的跟踪. 典型的实现为 [AbstractPluginData]. * - * [PluginData] 不涉及有关数据的存储, 而是只维护数据结构: [属性节点列表][valueNodes]. + * [AbstractPluginData] 不涉及有关数据的存储, 而是只维护数据结构: [属性节点列表][AbstractPluginData.valueNodes]. * * 有关存储方案, 请查看 [PluginDataStorage]. * @@ -74,7 +73,7 @@ import kotlin.reflect.full.findAnnotation * val theList: MutableList = AccountPluginData.list * ``` * - * 但也注意, 不要存储 `AccountPluginData.list`. 它可能受不到值跟踪. 若必要存储, 请使用 [PluginData.findBackingFieldValue] + * 但也注意, 不要存储 `AccountPluginData.list`. 它可能受不到值跟踪. 若必要存储, 请使用 [AbstractPluginData.findBackingFieldValue] * * ### 使用 Java * @@ -110,22 +109,17 @@ import kotlin.reflect.full.findAnnotation */ public interface PluginData { /** - * 这个 [PluginData] 保存时使用的名称. 默认通过 [ValueName] 获取, 否则使用 [类全名][KClass.qualifiedName] (即 [Class.getCanonicalName]) + * 这个 [PluginData] 保存时使用的名称. */ @ConsoleExperimentalApi public val saveName: String - get() { - val clazz = this::class - return clazz.findAnnotation()?.value - ?: clazz.qualifiedName - ?: throw IllegalArgumentException("Cannot find a serial name for ${this::class}") - } @ConsoleExperimentalApi public val updaterSerializer: KSerializer /** * 当所属于这个 [PluginData] 的 [Value] 的 [值][Value.value] 被修改时被调用. + * 调用者为 [Value] 的实现. */ @ConsoleExperimentalApi public fun onValueChanged(value: Value<*>) @@ -202,7 +196,7 @@ public fun PluginData.value(default: String): SerializerAwareValue = val @LowPriorityInOverloadResolution public inline fun PluginData.value( default: T, - crossinline apply: T.() -> Unit = {} + crossinline apply: T.() -> Unit = {}, ): SerializerAwareValue = valueFromKType(typeOf0(), default).also { it.value.apply() } diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/java/JAutoSavePluginConfig.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/java/JAutoSavePluginConfig.kt index 16a7764eb..5d9788dd1 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/java/JAutoSavePluginConfig.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/java/JAutoSavePluginConfig.kt @@ -37,4 +37,10 @@ import net.mamoe.mirai.console.data.PluginData * @see JAutoSavePluginData * @see PluginConfig */ -public abstract class JAutoSavePluginConfig : AutoSavePluginConfig(), PluginConfig +public abstract class JAutoSavePluginConfig : AutoSavePluginConfig, PluginConfig { + @Deprecated("请手动指定保存名称. 此构造器将在 1.0.0 删除", level = DeprecationLevel.ERROR, replaceWith = ReplaceWith("AutoSavePluginConfig(\"改成保存的名称\")")) + @Suppress("DEPRECATION_ERROR") + public constructor() : super() + + public constructor(saveName: String) : super(saveName) +} diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/java/JAutoSavePluginData.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/java/JAutoSavePluginData.kt index 835522027..ec2986fbc 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/java/JAutoSavePluginData.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/java/JAutoSavePluginData.kt @@ -66,7 +66,13 @@ import kotlin.reflect.full.createType * * @see PluginData */ -public abstract class JAutoSavePluginData : AutoSavePluginData(), PluginConfig { +public abstract class JAutoSavePluginData : AutoSavePluginData, PluginConfig { + @Deprecated("请手动指定保存名称. 此构造器将在 1.0.0 删除", level = DeprecationLevel.ERROR, replaceWith = ReplaceWith("AutoSavePluginConfig(\"改成保存的名称\")")) + @Suppress("DEPRECATION_ERROR") + public constructor() : super() + + public constructor(saveName: String) : super(saveName) + //// region JPluginData_value_primitives CODEGEN //// /** diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/data/PluginDataImpl.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/data/PluginDataImpl.kt index d388d87fc..e52d4d79a 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/data/PluginDataImpl.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/data/PluginDataImpl.kt @@ -18,9 +18,9 @@ import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.CompositeDecoder import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder +import net.mamoe.mirai.console.data.AbstractPluginData import net.mamoe.mirai.console.data.AbstractPluginData.ValueNode import net.mamoe.mirai.console.data.PluginData -import net.mamoe.mirai.console.data.Value import net.mamoe.mirai.console.data.ValueDescription import net.mamoe.mirai.console.data.ValueName import net.mamoe.yamlkt.Comment @@ -34,12 +34,25 @@ import kotlin.reflect.KAnnotatedElement * - Auto-saving */ internal abstract class PluginDataImpl { - internal fun findNodeInstance(name: String): ValueNode<*>? = valueNodes.firstOrNull { it.valueName == name } + init { + @Suppress("LeakingThis") + check(this is AbstractPluginData) + } - internal abstract val valueNodes: MutableList> + private fun findNodeInstance(name: String): ValueNode<*>? { + check(this is AbstractPluginData) + return valueNodes.firstOrNull { it.valueName == name } + } internal open val updaterSerializer: KSerializer = object : KSerializer { - override val descriptor: SerialDescriptor get() = dataUpdaterSerializerDescriptor + override val descriptor: SerialDescriptor by lazy { + check(this@PluginDataImpl is AbstractPluginData) + kotlinx.serialization.descriptors.buildClassSerialDescriptor((this@PluginDataImpl as PluginData).saveName) { + for (valueNode in valueNodes) valueNode.run { + element(valueName, updaterSerializer.descriptor, annotations = annotations, isOptional = true) + } + } + } @Suppress("UNCHECKED_CAST") override fun deserialize(decoder: Decoder) { @@ -84,6 +97,8 @@ internal abstract class PluginDataImpl { @Suppress("UNCHECKED_CAST") override fun serialize(encoder: Encoder, value: Unit) { + check(this@PluginDataImpl is AbstractPluginData) + val descriptor = descriptor with(encoder.beginStructure(descriptor)) { repeat(descriptor.elementsCount) { index -> @@ -100,18 +115,6 @@ internal abstract class PluginDataImpl { } } - - /** - * flatten - */ - abstract fun onValueChanged(value: Value<*>) - private val dataUpdaterSerializerDescriptor by lazy { - kotlinx.serialization.descriptors.buildClassSerialDescriptor((this as PluginData).saveName) { - for (valueNode in valueNodes) valueNode.run { - element(valueName, updaterSerializer.descriptor, annotations = annotations, isOptional = true) - } - } - } } internal fun KAnnotatedElement.getAnnotationListForValueSerialization(): List { diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/data/builtins/AutoLoginConfig.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/data/builtins/AutoLoginConfig.kt index 3fee86f5b..5cf269874 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/data/builtins/AutoLoginConfig.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/data/builtins/AutoLoginConfig.kt @@ -6,10 +6,7 @@ import net.mamoe.mirai.console.data.value import net.mamoe.mirai.console.internal.util.md5 import net.mamoe.mirai.console.internal.util.toUHexString -internal object AutoLoginConfig : AutoSavePluginConfig() { - override val saveName: String - get() = "AutoLogin" - +internal object AutoLoginConfig : AutoSavePluginConfig("AutoLogin") { @ValueDescription( """ 账号和明文密码列表 diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/extension/BuiltInSingletonExtensionSelector.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/extension/BuiltInSingletonExtensionSelector.kt index 5b50e64ca..60bb09cd8 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/extension/BuiltInSingletonExtensionSelector.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/extension/BuiltInSingletonExtensionSelector.kt @@ -16,9 +16,7 @@ internal object BuiltInSingletonExtensionSelector : SingletonExtensionSelector { internal val config: SaveData = SaveData() - internal class SaveData : AutoSavePluginConfig() { - override val saveName: String get() = "ExtensionSelector" - + internal class SaveData : AutoSavePluginConfig("ExtensionSelector") { val value: MutableMap by value() } diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/permission/BuiltInPermissionServices.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/permission/BuiltInPermissionServices.kt index 2d2271312..d787e3358 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/permission/BuiltInPermissionServices.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/permission/BuiltInPermissionServices.kt @@ -117,12 +117,12 @@ internal object BuiltInPermissionService : AbstractConcurrentPermissionService

> - by value>>(ConcurrentHashMap()) - .withDefault { CopyOnWriteArraySet() } + by value>>(ConcurrentHashMap()) + .withDefault { CopyOnWriteArraySet() } public companion object { @JvmStatic diff --git a/backend/mirai-console/src/test/kotlin/net/mamoe/mirai/console/data/SettingTest.kt b/backend/mirai-console/src/test/kotlin/net/mamoe/mirai/console/data/SettingTest.kt index 22c052765..e50cb7e11 100644 --- a/backend/mirai-console/src/test/kotlin/net/mamoe/mirai/console/data/SettingTest.kt +++ b/backend/mirai-console/src/test/kotlin/net/mamoe/mirai/console/data/SettingTest.kt @@ -17,7 +17,7 @@ import kotlin.test.assertSame @OptIn(ConsoleInternalApi::class) internal class PluginDataTest { - class MyPluginData : AutoSavePluginData() { + class MyPluginData : AutoSavePluginData("test") { var int by value(1) val map: MutableMap by value() val map2: MutableMap> by value()