mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-10 18:40:15 +08:00
Introduce JPluginData for Java callers
This commit is contained in:
parent
4ffa67ddf6
commit
6fe8f6f57c
@ -156,6 +156,26 @@ internal fun PluginData.${ktType.lowerCaseName}ValueImpl(): SerializerAwareValue
|
||||
|
||||
}
|
||||
|
||||
object JPluginData_value_primitivesCodegen : RegionCodegen("JPluginData.kt"), DefaultInvoke {
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) = super.startIndependently()
|
||||
override val defaultInvokeArgs: List<KtType> = KtPrimitives + KtString
|
||||
|
||||
override fun StringBuilder.apply(ktType: KtType) {
|
||||
@Suppress("unused")
|
||||
appendKCode(
|
||||
"""
|
||||
/**
|
||||
* 创建一个 [${ktType.standardName}] 类型的 [Value], 并设置初始值为 [default]
|
||||
*/
|
||||
public fun value(default: ${ktType.standardName}): SerializerAwareValue<${ktType.standardName}> = delegate.valueImpl(default)
|
||||
"""
|
||||
)
|
||||
appendLine()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 运行本 object 中所有嵌套 object Codegen
|
||||
*/
|
||||
|
@ -14,10 +14,8 @@ package net.mamoe.mirai.console.data
|
||||
import kotlinx.serialization.KSerializer
|
||||
import net.mamoe.mirai.console.data.PluginData.ValueNode
|
||||
import net.mamoe.mirai.console.internal.data.PluginDataImpl
|
||||
import net.mamoe.mirai.console.internal.data.serialName
|
||||
import net.mamoe.mirai.console.util.ConsoleExperimentalAPI
|
||||
import kotlin.annotation.AnnotationTarget.*
|
||||
import kotlin.reflect.KProperty
|
||||
import net.mamoe.mirai.console.util.ConsoleInternalAPI
|
||||
|
||||
/**
|
||||
* [PluginData] 的默认实现. 支持使用 `by value()` 等委托方法创建 [Value] 并跟踪其改动.
|
||||
@ -28,24 +26,23 @@ public abstract class AbstractPluginData : PluginData, PluginDataImpl() {
|
||||
/**
|
||||
* 添加了追踪的 [ValueNode] 列表, 即通过 `by value` 初始化的属性列表.
|
||||
*
|
||||
* 他们的修改会被跟踪, 并触发 [onValueChanged].
|
||||
* 它们的修改会被跟踪, 并触发 [onValueChanged].
|
||||
*
|
||||
* @see provideDelegate
|
||||
*/
|
||||
@ConsoleExperimentalAPI
|
||||
public override val valueNodes: MutableList<ValueNode<*>> = mutableListOf()
|
||||
|
||||
/**
|
||||
* 使用 `by` 时自动调用此方法, 添加对 [Value] 的值修改的跟踪.
|
||||
*
|
||||
* 将会创建一个 [ValueNode] 并添加到 [valueNodes]
|
||||
* 供手动实现时值跟踪使用 (如 Java 用户). 一般 Kotlin 用户需使用 [provideDelegate]
|
||||
*/
|
||||
public final override operator fun <T> SerializerAwareValue<T>.provideDelegate(
|
||||
thisRef: Any?,
|
||||
property: KProperty<*>
|
||||
): SerializerAwareValue<T> = apply { valueNodes.add(ValueNode(property.serialName, this, this.serializer)) }
|
||||
public override fun <T : SerializerAwareValue<*>> T.track(valueName: String): T =
|
||||
apply { valueNodes.add(ValueNode(valueName, this, this.serializer)) }
|
||||
|
||||
/**
|
||||
* 值更新序列化器. 仅供内部使用.
|
||||
* 所有 [valueNodes] 更新和保存序列化器. 仅供内部使用
|
||||
*
|
||||
* @suppress 注意, 这是实验性 API.
|
||||
*/
|
||||
@ConsoleExperimentalAPI
|
||||
public final override val updaterSerializer: KSerializer<Unit>
|
||||
@ -54,30 +51,6 @@ public abstract class AbstractPluginData : PluginData, PluginDataImpl() {
|
||||
/**
|
||||
* 当所属于这个 [PluginData] 的 [Value] 的 [值][Value.value] 被修改时被调用.
|
||||
*/
|
||||
@ConsoleInternalAPI
|
||||
public abstract override fun onValueChanged(value: Value<*>)
|
||||
}
|
||||
|
||||
/**
|
||||
* [PluginConfig] 的默认实现.
|
||||
*
|
||||
* 支持所有 [PluginData] 支持的功能, 支持通过 UI
|
||||
*
|
||||
* @see PluginConfig
|
||||
*/
|
||||
@ExperimentalPluginConfig
|
||||
public abstract class AbstractPluginConfig : AbstractPluginData(), PluginConfig
|
||||
|
||||
|
||||
/**
|
||||
* 标记实验性的 [PluginConfig] API.
|
||||
*
|
||||
* @see ConsoleExperimentalAPI
|
||||
*/
|
||||
@ConsoleExperimentalAPI
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(CLASS, TYPEALIAS, FUNCTION, PROPERTY, FIELD, CONSTRUCTOR)
|
||||
@MustBeDocumented
|
||||
public annotation class ExperimentalPluginConfig(
|
||||
val message: String = ""
|
||||
)
|
||||
}
|
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright 2020 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
@file:Suppress("unused")
|
||||
|
||||
package net.mamoe.mirai.console.data
|
||||
|
||||
import net.mamoe.mirai.console.internal.data.cast
|
||||
import net.mamoe.mirai.console.internal.data.setValueBySerializer
|
||||
import net.mamoe.mirai.console.internal.data.valueImpl
|
||||
import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KType
|
||||
import kotlin.reflect.KTypeProjection
|
||||
import kotlin.reflect.full.createType
|
||||
|
||||
/**
|
||||
* 供 Java 用户使用的 [PluginData]. 参考 [PluginData] 以获取更多信息.
|
||||
*
|
||||
* 在 [JvmPlugin] 的典型实现方式:
|
||||
* ```
|
||||
* // PluginMain.java
|
||||
* public final class PluginMain extends JavaPlugin {
|
||||
* public static PluginMain INSTANCE = null;
|
||||
* public PluginMain() {
|
||||
* INSTANCE = this;
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // MyPluginData.java
|
||||
* public class AccountPluginData extends JPluginData {
|
||||
* public static AccountPluginData INSTANCE;
|
||||
*
|
||||
* public AccountPluginData() {
|
||||
* super(PluginMain.INSTANCE.loadPluginData(AccountPluginData.class));
|
||||
* INSTANCE = this;
|
||||
* }
|
||||
*
|
||||
* public final Value<String> string = value("test"); // 默认值 "test"
|
||||
*
|
||||
* public final Value<List<String>> list = typedValue(createKType(List.class, createKType(String.class))); // 无默认值, 自动创建空 List
|
||||
*
|
||||
* public final Value<Map<Long, Object>> custom = typedValue(
|
||||
* createKType(Map.class, createKType(Long.class), createKType(Object.class)),
|
||||
* new HashMap<Long, Object>() {{ // 带默认值
|
||||
* put(123L, "ok");
|
||||
* }}
|
||||
* );
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* 使用时, 需要使用 `.get()`, 如:
|
||||
* ```
|
||||
* Value<List<String>> theList = MyPluginData.INSTANCE.list; // 获取 Value 实例. Value 代表一个追踪自动保存的值.
|
||||
*
|
||||
* List<String> actualList = theList.get();
|
||||
*
|
||||
* theList.set();
|
||||
* ```
|
||||
*
|
||||
* @see PluginData
|
||||
*/
|
||||
public open class JPluginData(
|
||||
private val delegate: PluginData
|
||||
) : PluginData by delegate {
|
||||
//// region JPluginData_value_primitives CODEGEN ////
|
||||
|
||||
/**
|
||||
* 创建一个 [Byte] 类型的 [Value], 并设置初始值为 [default]
|
||||
*/
|
||||
public fun value(default: Byte): SerializerAwareValue<Byte> = delegate.valueImpl(default)
|
||||
|
||||
/**
|
||||
* 创建一个 [Short] 类型的 [Value], 并设置初始值为 [default]
|
||||
*/
|
||||
public fun value(default: Short): SerializerAwareValue<Short> = delegate.valueImpl(default)
|
||||
|
||||
/**
|
||||
* 创建一个 [Int] 类型的 [Value], 并设置初始值为 [default]
|
||||
*/
|
||||
public fun value(default: Int): SerializerAwareValue<Int> = delegate.valueImpl(default)
|
||||
|
||||
/**
|
||||
* 创建一个 [Long] 类型的 [Value], 并设置初始值为 [default]
|
||||
*/
|
||||
public fun value(default: Long): SerializerAwareValue<Long> = delegate.valueImpl(default)
|
||||
|
||||
/**
|
||||
* 创建一个 [Float] 类型的 [Value], 并设置初始值为 [default]
|
||||
*/
|
||||
public fun value(default: Float): SerializerAwareValue<Float> = delegate.valueImpl(default)
|
||||
|
||||
/**
|
||||
* 创建一个 [Double] 类型的 [Value], 并设置初始值为 [default]
|
||||
*/
|
||||
public fun value(default: Double): SerializerAwareValue<Double> = delegate.valueImpl(default)
|
||||
|
||||
/**
|
||||
* 创建一个 [Char] 类型的 [Value], 并设置初始值为 [default]
|
||||
*/
|
||||
public fun value(default: Char): SerializerAwareValue<Char> = delegate.valueImpl(default)
|
||||
|
||||
/**
|
||||
* 创建一个 [Boolean] 类型的 [Value], 并设置初始值为 [default]
|
||||
*/
|
||||
public fun value(default: Boolean): SerializerAwareValue<Boolean> = delegate.valueImpl(default)
|
||||
|
||||
/**
|
||||
* 创建一个 [String] 类型的 [Value], 并设置初始值为 [default]
|
||||
*/
|
||||
public fun value(default: String): SerializerAwareValue<String> = delegate.valueImpl(default)
|
||||
|
||||
//// endregion JPluginData_value_primitives CODEGEN ////
|
||||
|
||||
/**
|
||||
* 构造一个支持泛型的 [Value].
|
||||
*
|
||||
* 对于 [Map], [Set], [List] 等标准库类型, 这个函数会尝试构造 [LinkedHashMap], [LinkedHashSet], [ArrayList] 等相关类型.
|
||||
* 而对于自定义数据类型, 本函数只会反射获取 [objectInstance][KClass.objectInstance] 或使用*无参构造器*构造实例.
|
||||
*
|
||||
* @param type Kotlin 类型. 可通过 [createKType] 获得
|
||||
*
|
||||
* @param T 类型 T. 仅支持:
|
||||
* - 基础数据类型, [String]
|
||||
* - 标准库集合类型 ([List], [Map], [Set])
|
||||
* - 标准库数据类型 ([Map.Entry], [Pair], [Triple])
|
||||
* - 使用 [kotlinx.serialization](https://github.com/Kotlin/kotlinx.serialization) 的 [Serializable] 标记的类
|
||||
*/
|
||||
@JvmOverloads
|
||||
public fun <T : Any> typedValue(type: KType, default: T? = null): SerializerAwareValue<T> {
|
||||
val value = delegate.valueImpl<T>(type, type.classifier!!.cast())
|
||||
if (default != null) value.setValueBySerializer(default)
|
||||
return value
|
||||
}
|
||||
|
||||
public companion object {
|
||||
/**
|
||||
* 根据 [Class] 及泛型参数获得一个类型
|
||||
*
|
||||
* 如要获得一个 `Map<String, Long>` 的类型,
|
||||
* ```java
|
||||
* KType type = JPluginDataHelper.createKType(Map.java, createKType(String.java), createKType(Long.java))
|
||||
* ```
|
||||
*
|
||||
* @param genericArguments 带有顺序的泛型参数
|
||||
*/
|
||||
@JvmStatic
|
||||
public fun <T : Any> createKType(clazz: Class<T>, nullable: Boolean, vararg genericArguments: KType): KType {
|
||||
return clazz.kotlin.createType(genericArguments.map { KTypeProjection(null, it) }, nullable)
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 [Class] 及泛型参数获得一个不可为 `null` 的类型
|
||||
*
|
||||
* @see createKType
|
||||
*/
|
||||
@JvmStatic
|
||||
public fun <T : Any> createKType(clazz: Class<T>, vararg genericArguments: KType): KType {
|
||||
return createKType(clazz, false, *genericArguments)
|
||||
}
|
||||
}
|
||||
}
|
@ -9,6 +9,9 @@
|
||||
|
||||
package net.mamoe.mirai.console.data
|
||||
|
||||
import net.mamoe.mirai.console.util.ConsoleExperimentalAPI
|
||||
import kotlin.annotation.AnnotationTarget.*
|
||||
|
||||
/**
|
||||
* 一个插件的配置数据, 用于和用户交互.
|
||||
*
|
||||
@ -18,4 +21,18 @@ package net.mamoe.mirai.console.data
|
||||
* 插件内部的数据应用 [PluginData] 存储, 而不能使用 [PluginConfig].
|
||||
*/
|
||||
@ExperimentalPluginConfig
|
||||
public interface PluginConfig : PluginData
|
||||
public interface PluginConfig : PluginData
|
||||
|
||||
/**
|
||||
* 标记实验性的 [PluginConfig] API.
|
||||
*
|
||||
* @see ConsoleExperimentalAPI
|
||||
*/
|
||||
@ConsoleExperimentalAPI
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(CLASS, TYPEALIAS, FUNCTION, PROPERTY, FIELD, CONSTRUCTOR)
|
||||
@MustBeDocumented
|
||||
public annotation class ExperimentalPluginConfig(
|
||||
val message: String = ""
|
||||
)
|
@ -7,19 +7,22 @@
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER", "EXPOSED_SUPER_CLASS", "NOTHING_TO_INLINE")
|
||||
@file:Suppress(
|
||||
"INVISIBLE_REFERENCE",
|
||||
"INVISIBLE_MEMBER",
|
||||
"EXPOSED_SUPER_CLASS",
|
||||
"NOTHING_TO_INLINE", "unused"
|
||||
)
|
||||
@file:JvmName("PluginDataKt")
|
||||
|
||||
package net.mamoe.mirai.console.data
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import net.mamoe.mirai.console.internal.data.createInstanceSmart
|
||||
import net.mamoe.mirai.console.internal.data.typeOf0
|
||||
import net.mamoe.mirai.console.internal.data.valueFromKTypeImpl
|
||||
import net.mamoe.mirai.console.internal.data.valueImpl
|
||||
import net.mamoe.mirai.console.internal.data.*
|
||||
import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
|
||||
import net.mamoe.mirai.console.plugin.jvm.loadPluginData
|
||||
import net.mamoe.mirai.console.util.ConsoleExperimentalAPI
|
||||
import net.mamoe.mirai.console.util.ConsoleInternalAPI
|
||||
import kotlin.internal.LowPriorityInOverloadResolution
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KProperty
|
||||
@ -30,17 +33,52 @@ import kotlin.reflect.KType
|
||||
*
|
||||
* [PluginData] 不涉及有关数据的存储, 而是只维护数据结构: [属性节点列表][valueNodes].
|
||||
*
|
||||
* 有关存储方案, 请查看 [PluginDataStorage]
|
||||
* 有关存储方案, 请查看 [PluginDataStorage].
|
||||
*
|
||||
* **注意**: [PluginData] 总应该是单例的.
|
||||
*
|
||||
* ### [JvmPlugin] 的实现方案
|
||||
*
|
||||
* 要修改保存时的名称, 请参考 [ValueName]
|
||||
*
|
||||
* ### 使用 Kotlin
|
||||
*
|
||||
* 在 [JvmPlugin] 的典型实现方式:
|
||||
* ```
|
||||
* object PluginMain : KotlinPlugin()
|
||||
*
|
||||
* object AccountPluginData : PluginData by PluginMain.loadPluginData() {
|
||||
* val map: Map<String, String> by value("a" to "b")
|
||||
* val list: MutableList<String> by value(mutableListOf("a", "b")) // mutableListOf("a", "b") 是初始值, 可以省略
|
||||
* val custom: Map<Long, CustomData> by value() // 使用 kotlinx-serialization 序列化的类型. (目前还不支持)
|
||||
* var custom2: CustomData by value() // 允许 var
|
||||
* }
|
||||
*
|
||||
* @Serializable
|
||||
* data class CustomData(
|
||||
* // ...
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* 使用时, 可以方便地直接调用, 如:
|
||||
* ```
|
||||
* val theList = AccountPluginData.list
|
||||
* ```
|
||||
*
|
||||
* 但也注意, 不要存储 `AccountPluginData.list`. 它可能受不到值跟踪.
|
||||
* 错误的示例:
|
||||
* ```
|
||||
*
|
||||
* class {
|
||||
*
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* ### 使用 Java
|
||||
*
|
||||
* 参考 [JPluginData]
|
||||
*
|
||||
* **注意**: 由于实现特殊, 请不要在初始化 Value 时就使用 `.get()`. 这可能会导致自动保存追踪失效. 必须在使用时才调用 `.get()` 获取真实数据对象.
|
||||
*
|
||||
* @see JvmPlugin.loadPluginData 通过 [JvmPlugin] 获取指定 [PluginData] 实例.
|
||||
* @see PluginDataStorage [PluginData] 存储仓库
|
||||
*/
|
||||
@ -51,7 +89,9 @@ public interface PluginData {
|
||||
* 他们的修改会被跟踪, 并触发 [onValueChanged].
|
||||
*
|
||||
* @see provideDelegate
|
||||
* @see track
|
||||
*/
|
||||
@ConsoleExperimentalAPI
|
||||
public val valueNodes: MutableList<ValueNode<*>>
|
||||
|
||||
/**
|
||||
@ -61,14 +101,14 @@ public interface PluginData {
|
||||
/**
|
||||
* 节点名称.
|
||||
*
|
||||
* 如果属性带有 [SerialName], 则使用 [kotlinx.serialization.SerialName.value],
|
||||
* 如果属性带有 [ValueName], 则使用 [ValueName.value],
|
||||
* 否则使用 [属性名称][KProperty.name]
|
||||
*/
|
||||
val serialName: String,
|
||||
val valueName: String,
|
||||
/**
|
||||
* 属性值代理
|
||||
*/
|
||||
val value: Value<T>,
|
||||
val value: Value<out T>,
|
||||
/**
|
||||
* 属性值更新器
|
||||
*
|
||||
@ -81,13 +121,28 @@ public interface PluginData {
|
||||
/**
|
||||
* 使用 `by value()` 时自动调用此方法, 添加对 [Value] 的值修改的跟踪, 并创建 [ValueNode] 加入 [valueNodes]
|
||||
*/
|
||||
public operator fun <T> SerializerAwareValue<T>.provideDelegate(
|
||||
public operator fun <T : SerializerAwareValue<*>> T.provideDelegate(
|
||||
thisRef: Any?,
|
||||
property: KProperty<*>
|
||||
): SerializerAwareValue<T>
|
||||
): T = track(property.valueName)
|
||||
|
||||
/**
|
||||
* 值更新序列化器. 仅供内部使用
|
||||
* 供手动实现时值跟踪使用 (如 Java 用户). 一般 Kotlin 用户需使用 [provideDelegate]
|
||||
*/
|
||||
public fun <T : SerializerAwareValue<*>> T.track(
|
||||
/**
|
||||
* 值名称.
|
||||
*
|
||||
* 如果属性带有 [ValueName], 则使用 [ValueName.value],
|
||||
* 否则使用 [属性名称][KProperty.name]
|
||||
*
|
||||
* @see [ValueNode.value]
|
||||
*/
|
||||
valueName: String
|
||||
): T
|
||||
|
||||
/**
|
||||
* 所有 [valueNodes] 更新和保存序列化器. 仅供内部使用
|
||||
*
|
||||
* @suppress 注意, 这是实验性 API.
|
||||
*/
|
||||
@ -97,14 +152,70 @@ public interface PluginData {
|
||||
/**
|
||||
* 当所属于这个 [PluginData] 的 [Value] 的 [值][Value.value] 被修改时被调用.
|
||||
*/
|
||||
@ConsoleInternalAPI
|
||||
public fun onValueChanged(value: Value<*>)
|
||||
|
||||
/**
|
||||
* 当这个 [PluginData] 被放入一个 [PluginDataStorage] 时调用
|
||||
*/
|
||||
@ConsoleInternalAPI
|
||||
public fun setStorage(storage: PluginDataStorage)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取这个 [KProperty] 委托的 [Value]
|
||||
*
|
||||
* 如, 对于
|
||||
* ```
|
||||
* object MyData : PluginData {
|
||||
* val list: List<String> by value()
|
||||
* }
|
||||
*
|
||||
* val value: Value<List<String>> = MyData.findBackingFieldValue(MyData::list)
|
||||
* ```
|
||||
*/
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
public fun <T> PluginData.findBackingFieldValue(property: KProperty<T>): Value<out T>? =
|
||||
findBackingFieldValue(property.valueName)
|
||||
|
||||
/**
|
||||
* 获取这个 [KProperty] 委托的 [Value]
|
||||
*
|
||||
* 如, 对于
|
||||
* ```
|
||||
* object MyData : PluginData {
|
||||
* @ValueName("theList")
|
||||
* val list: List<String> by value()
|
||||
* val int: Int by value()
|
||||
* }
|
||||
*
|
||||
* val value: Value<List<String>> = MyData.findBackingFieldValue("theList") // 需使用 @ValueName 标注的名称
|
||||
* val intValue: Value<Int> = MyData.findBackingFieldValue("int")
|
||||
* ```
|
||||
*/
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
public fun <T> PluginData.findBackingFieldValue(propertyValueName: String): Value<out T>? {
|
||||
return this.valueNodes.find { it.valueName == propertyValueName }?.value as Value<T>
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取这个 [KProperty] 委托的 [Value]
|
||||
*
|
||||
* 如, 对于
|
||||
* ```
|
||||
* object MyData : PluginData {
|
||||
* val list: List<String> by value()
|
||||
* }
|
||||
*
|
||||
* val value: PluginData.ValueNode<List<String>> = MyData.findBackingFieldValueNode(MyData::list)
|
||||
* ```
|
||||
*/
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
public fun <T> PluginData.findBackingFieldValueNode(property: KProperty<T>): PluginData.ValueNode<out T>? {
|
||||
return this.valueNodes.find { it == property } as PluginData.ValueNode<out T>?
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于支持属性委托
|
||||
*/
|
||||
@ -199,14 +310,14 @@ internal fun <T> PluginData.valueImpl(type: KType, classifier: KClass<*>): Seria
|
||||
/**
|
||||
* 通过一个特定的 [KType] 创建 [Value], 并设置初始值.
|
||||
*
|
||||
* 对于 [List], [Map], [Set] 等标准库类型, 这个函数会尝试构造 [LinkedHashMap] 等相关类型.
|
||||
* 而对于自定义数据类型, 本函数只会反射获取 [objectInstance][KClass.objectInstance] 或使用无参构造器构造实例.
|
||||
* 对于 [Map], [Set], [List] 等标准库类型, 这个函数会尝试构造 [LinkedHashMap], [LinkedHashSet], [ArrayList] 等相关类型.
|
||||
* 而对于自定义数据类型, 本函数只会反射获取 [objectInstance][KClass.objectInstance] 或使用*无参构造器*构造实例.
|
||||
*
|
||||
* @param T 具体化参数类型 T. 仅支持:
|
||||
* - 基础数据类型
|
||||
* - 基础数据类型, [String]
|
||||
* - 标准库集合类型 ([List], [Map], [Set])
|
||||
* - 标准库数据类型 ([Map.Entry], [Pair], [Triple])
|
||||
* - 和使用 [kotlinx.serialization](https://github.com/Kotlin/kotlinx.serialization) 的 [Serializable] 标记的
|
||||
* - 使用 [kotlinx.serialization](https://github.com/Kotlin/kotlinx.serialization) 的 [Serializable] 标记的类
|
||||
*/
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@ConsoleExperimentalAPI
|
||||
|
@ -5,9 +5,9 @@ package net.mamoe.mirai.console.data
|
||||
*
|
||||
* 例:
|
||||
* ```
|
||||
* @SerialName("accounts")
|
||||
* @ValueName("accounts")
|
||||
* object AccountPluginData : PluginData by ... {
|
||||
* @SerialName("info")
|
||||
* @ValueName("info")
|
||||
* val map: Map<String, String> by value("a" to "b")
|
||||
* }
|
||||
* ```
|
||||
@ -19,4 +19,6 @@ package net.mamoe.mirai.console.data
|
||||
* a: b
|
||||
* ```
|
||||
*/
|
||||
public typealias SerialName = kotlinx.serialization.SerialName
|
||||
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
public annotation class ValueName(val value: String)
|
||||
|
@ -7,7 +7,7 @@
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER", "unused", "NOTHING_TO_INLINE")
|
||||
@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER", "unused", "NOTHING_TO_INLINE", "INAPPLICABLE_JVM_NAME")
|
||||
|
||||
package net.mamoe.mirai.console.data
|
||||
|
||||
@ -31,6 +31,8 @@ import net.mamoe.mirai.console.util.ConsoleExperimentalAPI
|
||||
* @see CompositeValue 复合数据类型实现
|
||||
*/
|
||||
public interface Value<T> {
|
||||
@get:JvmName("get")
|
||||
@set:JvmName("set")
|
||||
public var value: T
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user