Merge remote-tracking branch 'origin/reborn' into reborn

# Conflicts:
#	backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/internal/PluginsLoader.kt
This commit is contained in:
Karlatemp 2020-06-20 20:52:09 +08:00
commit 9c1b937aaf
No known key found for this signature in database
GPG Key ID: 21FBDDF664FF06F8
5 changed files with 89 additions and 23 deletions

View File

@ -0,0 +1,11 @@
/*
* 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
*/
package net.mamoe.mirai.console.codegen.setting

View File

@ -0,0 +1,54 @@
/*
* 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
*/
package net.mamoe.mirai.console.codegen
import java.io.File
fun codegen(targetFile: String, regionName: String, block: StringBuilder.() -> Unit) {
//// region PrimitiveValue CODEGEN START ////
//// region PrimitiveValue CODEGEN END ////
targetFile.findFileSmart().also {
println("Codegen target: ${it.absolutePath}")
}.apply {
writeText(
readText()
.replace(Regex("""//// region $regionName CODEGEN START ////([\s\S]*?)//// endregion $regionName CODEGEN END ////""")) {
val code = StringBuilder().apply(block).toString()
"""
|//// region $regionName CODEGEN START ////
|
|$code
|
|//// endregion $regionName CODEGEN END ////
""".trimMargin()
}
)
}
}
fun String.findFileSmart(): File = kotlin.run {
if (contains("/")) { // absolute
File(this)
} else {
val list = File(".").walk().filter { it.name == this }.toList()
if (list.isNotEmpty()) return list.single()
File(".").walk().filter { it.name.contains(this) }.single()
}
}.also {
require(it.exists()) { "file doesn't exist" }
}
fun main() {
codegen("Value.kt", "PrimitiveValue") {
}
}

View File

@ -16,7 +16,7 @@ import java.net.URLClassLoader
internal class PluginsLoader(private val parentClassLoader: ClassLoader) { internal class PluginsLoader(private val parentClassLoader: ClassLoader) {
private val loggerName = "PluginsLoader" private val loggerName = "PluginsLoader"
private val pluginLoaders = linkedMapOf<String, PluginClassLoader>() private val pluginLoaders = linkedMapOf<String, PluginClassLoader>()
private val classesCache = mutableMapOf<String,Class<*>>() private val classesCache = mutableMapOf<String, Class<*>>()
private val logger = MiraiConsole.newLogger(loggerName) private val logger = MiraiConsole.newLogger(loggerName)
/** /**
@ -93,9 +93,9 @@ internal class PluginsLoader(private val parentClassLoader: ClassLoader) {
* A Adapted URL Class Loader that supports Android and JVM for single URL(File) Class Load * A Adapted URL Class Loader that supports Android and JVM for single URL(File) Class Load
*/ */
internal open class AdaptiveURLClassLoader(file: File, parent: ClassLoader):ClassLoader(){ internal open class AdaptiveURLClassLoader(file: File, parent: ClassLoader) : ClassLoader() {
private val internalClassLoader:ClassLoader by lazy { private val internalClassLoader: ClassLoader by lazy {
kotlin.runCatching { kotlin.runCatching {
val loaderClass = Class.forName("dalvik.system.PathClassLoader") val loaderClass = Class.forName("dalvik.system.PathClassLoader")
loaderClass.getConstructor(String::class.java, ClassLoader::class.java) loaderClass.getConstructor(String::class.java, ClassLoader::class.java)
@ -110,19 +110,19 @@ internal open class AdaptiveURLClassLoader(file: File, parent: ClassLoader):Clas
} }
private val internalClassCache = mutableMapOf<String,Class<*>>() private val internalClassCache = mutableMapOf<String, Class<*>>()
internal val classesCache:Map<String,Class<*>> internal val classesCache: Map<String, Class<*>>
get() = internalClassCache get() = internalClassCache
internal fun addClassCache(string: String, clazz: Class<*>){ internal fun addClassCache(string: String, clazz: Class<*>) {
synchronized(internalClassCache){ synchronized(internalClassCache) {
internalClassCache[string] = clazz internalClassCache[string] = clazz
} }
} }
fun close(){ fun close() {
if (internalClassLoader is URLClassLoader) { if (internalClassLoader is URLClassLoader) {
(internalClassLoader as URLClassLoader).close() (internalClassLoader as URLClassLoader).close()
} }
@ -135,24 +135,25 @@ internal class PluginClassLoader(
file: File, file: File,
private val pluginsLoader: PluginsLoader, private val pluginsLoader: PluginsLoader,
parent: ClassLoader parent: ClassLoader
) :AdaptiveURLClassLoader(file,parent){ ) : AdaptiveURLClassLoader(file, parent) {
override fun findClass(name: String): Class<*> { override fun findClass(name: String): Class<*> {
return findClass(name,true) return findClass(name, true)
} }
fun findClass(name: String, global: Boolean = true): Class<*>{ fun findClass(name: String, global: Boolean = true): Class<*> {
return classesCache[name]?: kotlin.run { return classesCache[name] ?: kotlin.run {
var clazz: Class<*>? = null var clazz: Class<*>? = null
if (global) { if (global) {
clazz = pluginsLoader.findClassByName(name) clazz = pluginsLoader.findClassByName(name)
} }
if(clazz == null) { if (clazz == null) {
clazz = loadClass(name)//这里应该是find, 如果不行就要改 clazz = loadClass(name)//这里应该是find, 如果不行就要改
} }
pluginsLoader.addClassCache(name, clazz) pluginsLoader.addClassCache(name, clazz)
this.addClassCache(name, clazz) this.addClassCache(name, clazz)
clazz @Suppress("UNNECESSARY_NOT_NULL_ASSERTION")
}!! clazz!! // compiler bug
}
} }
} }

View File

@ -43,7 +43,7 @@ typealias ValueSerializer<T> = KSerializer<Value<T>>
* - [Char], [String] * - [Char], [String]
* *
* Note: The values are actually *boxed* because of the generic type T. * Note: The values are actually *boxed* because of the generic type T.
* *Primitive* indicates only it is one of the 8 types mentioned above. * *Primitive* indicates only it is one of the 9 types mentioned above.
*/ */
interface PrimitiveValue<T> : Value<T> interface PrimitiveValue<T> : Value<T>

View File

@ -15,33 +15,33 @@ import net.mamoe.mirai.console.setting.Setting
import net.mamoe.mirai.console.setting.Value import net.mamoe.mirai.console.setting.Value
import kotlin.reflect.KClass import kotlin.reflect.KClass
import kotlin.reflect.KType import kotlin.reflect.KType
import kotlin.reflect.full.isSubclassOf
@PublishedApi @PublishedApi
@Suppress("UnsafeCall", "SMARTCAST_IMPOSSIBLE") @Suppress("UnsafeCall", "SMARTCAST_IMPOSSIBLE")
internal fun Setting.valueFromKTypeImpl(type: KType): Value<*> { internal fun Setting.valueFromKTypeImpl(type: KType): Value<*> {
require(type.classifier is KClass<*>) val classifier = type.classifier
require(classifier is KClass<*>)
if (type.classifier.isPrimitiveOrBuiltInSerializableValue()) { if (classifier.isPrimitiveOrBuiltInSerializableValue()) {
TODO("是基础类型, 可以直接创建 ValueImpl. ") TODO("是基础类型, 可以直接创建 ValueImpl. ")
} }
// 复合类型 // 复合类型
when { when {
type.classifier.isSubclassOf(Map::class) -> { classifier == Map::class -> {
TODO() TODO()
} }
type.classifier.isSubclassOf(List::class) -> { classifier == List::class -> {
TODO() TODO()
} }
type.classifier.isSubclassOf(Set::class) -> { classifier == Set::class -> {
TODO() TODO()
} }
else -> error("Custom composite value is not supported yet (${type.classifier.qualifiedName})") else -> error("Custom composite value is not supported yet (${classifier.qualifiedName})")
} }
} }