Fix JAutoSavePluginData.typedValue, fix #311

This commit is contained in:
Him188 2021-04-10 15:45:52 +08:00
parent c00a08b4f9
commit eb240f3a75
3 changed files with 82 additions and 8 deletions

View File

@ -1,10 +1,10 @@
/* /*
* Copyright 2019-2020 Mamoe Technologies and contributors. * Copyright 2019-2021 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found through the following link. * 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 * https://github.com/mamoe/mirai/blob/master/LICENSE
*/ */
@file:Suppress("unused", "EXPOSED_SUPER_CLASS") @file:Suppress("unused", "EXPOSED_SUPER_CLASS")
@ -16,9 +16,12 @@ import net.mamoe.mirai.console.internal.data.cast
import net.mamoe.mirai.console.internal.data.setValueBySerializer import net.mamoe.mirai.console.internal.data.setValueBySerializer
import net.mamoe.mirai.console.internal.data.valueImpl import net.mamoe.mirai.console.internal.data.valueImpl
import net.mamoe.mirai.console.plugin.jvm.JvmPlugin import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentMap
import kotlin.reflect.KClass import kotlin.reflect.KClass
import kotlin.reflect.KType import kotlin.reflect.KType
import kotlin.reflect.KTypeProjection import kotlin.reflect.KTypeProjection
import kotlin.reflect.KVariance
import kotlin.reflect.full.createType import kotlin.reflect.full.createType
/** /**
@ -120,16 +123,16 @@ public abstract class JAutoSavePluginData public constructor(saveName: String) :
/** /**
* 构造一个支持泛型的 [Value]. * 构造一个支持泛型的 [Value].
* *
* 对于 [Map], [Set], [List] 等标准库类型, 这个函数会尝试构造 [LinkedHashMap], [LinkedHashSet], [ArrayList] 等相关类型. * 对于 [Map], [Set], [List], [ConcurrentMap] 等标准库类型, 这个函数会尝试构造 [LinkedHashMap], [LinkedHashSet], [ArrayList], [ConcurrentHashMap] 等相关类型.
* 而对于自定义数据类型, 本函数只会反射获取 [objectInstance][KClass.objectInstance] 或使用*无参构造器*构造实例. * 而对于自定义数据类型, 本函数只会反射获取 [objectInstance][KClass.objectInstance] 或使用*无参构造器*构造实例.
* *
* @param type Kotlin 类型. 可通过 [createKType] 获得 * @param type Kotlin 类型. 可通过 [createKType] 获得
* *
* @param T 类型 T. 仅支持: * @param T 类型 T. 仅支持:
* - 基础数据类型, [String] * - 基础数据类型, [String]
* - 标准库集合类型 ([List], [Map], [Set]) * - 标准库集合类型 ([List], [Map], [Set], [ConcurrentMap])
* - 标准库数据类型 ([Map.Entry], [Pair], [Triple]) * - 标准库数据类型 ([Map.Entry], [Pair], [Triple])
* - 使用 [kotlinx.serialization](https://github.com/Kotlin/kotlinx.serialization) 的 [Serializable] 标记的 * - 使用 [kotlinx.serialization](https://github.com/Kotlin/kotlinx.serialization) 的 [Serializable] 标记的 **Kotlin**
*/ */
@JvmOverloads @JvmOverloads
public fun <T : Any> typedValue(type: KType, default: T? = null): SerializerAwareValue<T> { public fun <T : Any> typedValue(type: KType, default: T? = null): SerializerAwareValue<T> {
@ -151,7 +154,7 @@ public abstract class JAutoSavePluginData public constructor(saveName: String) :
*/ */
@JvmStatic @JvmStatic
public fun <T : Any> createKType(clazz: Class<T>, nullable: Boolean, vararg genericArguments: KType): KType { public fun <T : Any> createKType(clazz: Class<T>, nullable: Boolean, vararg genericArguments: KType): KType {
return clazz.kotlin.createType(genericArguments.map { KTypeProjection(null, it) }, nullable) return clazz.kotlin.createType(genericArguments.map { KTypeProjection(KVariance.INVARIANT, it) }, nullable)
} }
/** /**

View File

@ -0,0 +1,30 @@
/*
* Copyright 2019-2021 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
*/
package net.mamoe.mirai.console
import kotlinx.coroutines.cancel
import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription
import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
abstract class AbstractConsoleTest {
val mockPlugin = object : KotlinPlugin(JvmPluginDescription("org.test.test", "1.0.0")) {}
@BeforeEach
fun beforeTest() {
initTestEnvironment()
}
@AfterEach
fun afterTest() {
MiraiConsole.cancel()
}
}

View File

@ -0,0 +1,41 @@
/*
* Copyright 2019-2021 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
*/
package data
import net.mamoe.mirai.console.AbstractConsoleTest
import net.mamoe.mirai.console.data.Value
import net.mamoe.mirai.console.data.java.JAutoSavePluginData
import net.mamoe.mirai.console.plugin.jvm.reloadPluginData
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals
@Suppress("unused")
class JavaPluginDescriptionTests : AbstractConsoleTest() {
@Test
fun testSimpleValue() {
class MyJavaData : JAutoSavePluginData("data") {
val list: Value<String> = value("str")
}
val d = MyJavaData()
mockPlugin.reloadPluginData(d)
assertEquals("str", d.list.value)
}
@Test
fun testValueSet() {
class MyJavaData : JAutoSavePluginData("data") {
val list: Value<Set<String>> = typedValue(createKType(MutableSet::class.java, createKType(String::class.java)))
}
mockPlugin.reloadPluginData(MyJavaData())
}
}