From 7dd4a9669bcc9ba246075fdd3acb36fcaa5d5174 Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Thu, 12 Nov 2020 12:38:49 +0800 Subject: [PATCH 1/8] Fix console stopping, fix #221 - Make StopCommand async - Close terminal reader only --- .../src/command/BuiltInCommands.kt | 46 ++++++++++--------- backend/mirai-console/src/util/SemVersion.kt | 4 +- .../src/ConsoleThread.kt | 10 ++-- 3 files changed, 29 insertions(+), 31 deletions(-) diff --git a/backend/mirai-console/src/command/BuiltInCommands.kt b/backend/mirai-console/src/command/BuiltInCommands.kt index c24fe9948..a5d978b53 100644 --- a/backend/mirai-console/src/command/BuiltInCommands.kt +++ b/backend/mirai-console/src/command/BuiltInCommands.kt @@ -102,29 +102,31 @@ public object BuiltInCommands { @Handler public suspend fun CommandSender.handle() { - kotlin.runCatching { - closingLock.withLock { - sendMessage("Stopping mirai-console") - kotlin.runCatching { - runIgnoreException { MiraiConsole.job.cancelAndJoin() } - }.fold( - onSuccess = { - runIgnoreException { sendMessage("mirai-console stopped successfully.") } - }, - onFailure = { - if (it is CancellationException) return@fold - @OptIn(ConsoleInternalApi::class) - MiraiConsole.mainLogger.error("Exception in stop", it) - runIgnoreException { - sendMessage( - it.localizedMessage ?: it.message ?: it.toString() - ) + GlobalScope.launch { + kotlin.runCatching { + closingLock.withLock { + if (!MiraiConsole.isActive) return@withLock + sendMessage("Stopping mirai-console") + kotlin.runCatching { + MiraiConsole.job.cancelAndJoin() + }.fold( + onSuccess = { + runIgnoreException { sendMessage("mirai-console stopped successfully.") } + }, + onFailure = { + @OptIn(ConsoleInternalApi::class) + MiraiConsole.mainLogger.error("Exception in stop", it) + runIgnoreException { + sendMessage( + it.localizedMessage ?: it.message ?: it.toString() + ) + } } - } - ) - } - }.exceptionOrNull()?.let(MiraiConsole.mainLogger::error) - exitProcess(0) + ) + } + }.exceptionOrNull()?.let(MiraiConsole.mainLogger::error) + exitProcess(0) + } } } diff --git a/backend/mirai-console/src/util/SemVersion.kt b/backend/mirai-console/src/util/SemVersion.kt index f350c0f58..4aee3861d 100644 --- a/backend/mirai-console/src/util/SemVersion.kt +++ b/backend/mirai-console/src/util/SemVersion.kt @@ -94,9 +94,7 @@ internal constructor( private val impl = SemVersionInternal.parseRangeRequirement(rule) /** 在 [version] 满足此要求时返回 true */ - public fun test(version: SemVersion): Boolean { - return impl.test(version) - } + public fun test(version: SemVersion): Boolean = impl.test(version) public object RequirementAsStringSerializer : KSerializer by String.serializer().map( serializer = { it.rule }, diff --git a/frontend/mirai-console-terminal/src/ConsoleThread.kt b/frontend/mirai-console-terminal/src/ConsoleThread.kt index 97294ca1c..2e2e78fba 100644 --- a/frontend/mirai-console-terminal/src/ConsoleThread.kt +++ b/frontend/mirai-console-terminal/src/ConsoleThread.kt @@ -9,10 +9,7 @@ package net.mamoe.mirai.console.terminal -import kotlinx.coroutines.CancellationException -import kotlinx.coroutines.CoroutineName -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch +import kotlinx.coroutines.* import net.mamoe.mirai.console.MiraiConsole import net.mamoe.mirai.console.command.* import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors @@ -30,12 +27,13 @@ internal fun startupConsoleThread() { if (terminal is NoConsole) return MiraiConsole.launch(CoroutineName("Input Cancelling Daemon")) { - while (true) { + while (isActive) { delay(2000) } }.invokeOnCompletion { runCatching { - terminal.close() + // 应该仅关闭用户输入 + terminal.reader().shutdown() ConsoleInputImpl.thread.shutdownNow() runCatching { ConsoleInputImpl.executingCoroutine?.cancel(EndOfFileException()) From 3b27a26b0ab57dc1f8bda1ca8c58e6dc58ac9cfc Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Thu, 12 Nov 2020 22:25:44 +0800 Subject: [PATCH 2/8] Fix SemVersion.Requirement --- backend/mirai-console/src/util/SemVersion.kt | 13 +++++-------- backend/mirai-console/test/util/TestSemVersion.kt | 10 ++++++++++ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/backend/mirai-console/src/util/SemVersion.kt b/backend/mirai-console/src/util/SemVersion.kt index e86131864..59657ef86 100644 --- a/backend/mirai-console/src/util/SemVersion.kt +++ b/backend/mirai-console/src/util/SemVersion.kt @@ -94,16 +94,13 @@ internal constructor( */ val rule: String, ) { - init { - kotlin.runCatching { - parseRangeRequirement(rule) - }.onFailure { - throw java.lang.IllegalArgumentException("Syntax error: $rule", it) - } - } @Transient - private val impl = SemVersionInternal.parseRangeRequirement(rule) + internal val impl = kotlin.runCatching { + SemVersionInternal.parseRangeRequirement(rule) + }.getOrElse { + throw java.lang.IllegalArgumentException("Syntax error: $rule", it) + } /** 在 [version] 满足此要求时返回 true */ public fun test(version: SemVersion): Boolean = impl.test(version) diff --git a/backend/mirai-console/test/util/TestSemVersion.kt b/backend/mirai-console/test/util/TestSemVersion.kt index 3021de67b..781392f1a 100644 --- a/backend/mirai-console/test/util/TestSemVersion.kt +++ b/backend/mirai-console/test/util/TestSemVersion.kt @@ -43,6 +43,16 @@ internal class TestSemVersion { assert("1.0.0-rc.1".sem() < "1.0.0".sem()) } + @Test + internal fun testRequirementCopy() { + fun SemVersion.Requirement.check(a: SemVersion.Requirement.() -> SemVersion.Requirement) { + assert(a().impl !== this.impl) + } + SemVersion.parseRangeRequirement("1.0").check { copy() } + SemVersion.parseRangeRequirement("1.0").check { copy("2.0") } + SemVersion.parseRangeRequirement("1.0").check { copy("1.0") } + } + @Test internal fun testRequirement() { fun SemVersion.Requirement.assert(version: String): SemVersion.Requirement { From ff9c493e4b796906d36e03712f4ae7005cd6fa0d Mon Sep 17 00:00:00 2001 From: Him188 Date: Fri, 13 Nov 2020 14:32:16 +0800 Subject: [PATCH 3/8] Support kotlinx-serialization builtin serializers --- .../internal/MiraiConsoleBuildConstants.kt | 4 +- .../org/example/myplugin/MyPluginMain.kt | 7 ++ .../diagnostics/PluginDataValuesChecker.kt | 74 ++++++++++++++++--- 3 files changed, 73 insertions(+), 12 deletions(-) diff --git a/backend/mirai-console/src/internal/MiraiConsoleBuildConstants.kt b/backend/mirai-console/src/internal/MiraiConsoleBuildConstants.kt index 418852398..141cb973b 100644 --- a/backend/mirai-console/src/internal/MiraiConsoleBuildConstants.kt +++ b/backend/mirai-console/src/internal/MiraiConsoleBuildConstants.kt @@ -14,8 +14,8 @@ import java.time.Instant internal object MiraiConsoleBuildConstants { // auto-filled on build (task :mirai-console:fillBuildConstants) @JvmStatic - val buildDate: Instant = Instant.ofEpochSecond(1604041264) - const val versionConst: String = "1.0-RC-1" + val buildDate: Instant = Instant.ofEpochSecond(1605147625) + const val versionConst: String = "1.0-RC2-dev-4" @JvmStatic val version: SemVersion = SemVersion(versionConst) diff --git a/tools/intellij-plugin/run/projects/test-project/src/main/kotlin/org/example/myplugin/MyPluginMain.kt b/tools/intellij-plugin/run/projects/test-project/src/main/kotlin/org/example/myplugin/MyPluginMain.kt index ca1f36d57..34a50f190 100644 --- a/tools/intellij-plugin/run/projects/test-project/src/main/kotlin/org/example/myplugin/MyPluginMain.kt +++ b/tools/intellij-plugin/run/projects/test-project/src/main/kotlin/org/example/myplugin/MyPluginMain.kt @@ -2,6 +2,7 @@ package org.example.myplugin import kotlinx.serialization.Serializable import net.mamoe.mirai.console.data.AutoSavePluginConfig +import net.mamoe.mirai.console.data.AutoSavePluginData import net.mamoe.mirai.console.data.value import net.mamoe.mirai.console.permission.PermissionId import net.mamoe.mirai.console.permission.PermissionService @@ -29,3 +30,9 @@ object MyPluginMain : KotlinPlugin( } } + + +object MyData : AutoSavePluginData("") { + val value by value("") + val value2 by value>() +} \ No newline at end of file diff --git a/tools/intellij-plugin/src/diagnostics/PluginDataValuesChecker.kt b/tools/intellij-plugin/src/diagnostics/PluginDataValuesChecker.kt index 7eb1c0f6b..e05db2e83 100644 --- a/tools/intellij-plugin/src/diagnostics/PluginDataValuesChecker.kt +++ b/tools/intellij-plugin/src/diagnostics/PluginDataValuesChecker.kt @@ -18,10 +18,12 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.idea.inspections.collections.isCalling import org.jetbrains.kotlin.idea.refactoring.fqName.fqName +import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext import org.jetbrains.kotlin.types.SimpleType +import org.jetbrains.kotlinx.serialization.compiler.resolve.* class PluginDataValuesChecker : DeclarationChecker { @@ -39,26 +41,78 @@ class PluginDataValuesChecker : DeclarationChecker { && t is SimpleType }.forEach { (e, callExpr) -> val (_, type) = e - val classDescriptor = type.constructor.declarationDescriptor?.castOrNull() + val classDescriptor = type.constructor.declarationDescriptor?.castOrNull() ?: return@forEach + + if (canBeSerializedInternally(classDescriptor)) return@forEach val inspectionTarget = kotlin.run { val fqName = type.fqName ?: return@run null callExpr.typeArguments.find { it.typeReference?.isReferencing(fqName) == true } } ?: return@forEach - if (classDescriptor == null - || !classDescriptor.hasNoArgConstructor() - ) return@forEach context.report(MiraiConsoleErrors.NOT_CONSTRUCTABLE_TYPE.on( - inspectionTarget, - callExpr, - type.fqName?.asString().toString()) - ) + if (!classDescriptor.hasNoArgConstructor()) + return@forEach context.report(MiraiConsoleErrors.NOT_CONSTRUCTABLE_TYPE.on( + inspectionTarget, + callExpr, + type.fqName?.asString().toString()) + ) - if (!classDescriptor.hasAnnotation(SERIALIZABLE_FQ_NAME)) // TODO: 2020/9/18 external serializers + if (!classDescriptor.hasAnnotation(SERIALIZABLE_FQ_NAME)) return@forEach context.report(MiraiConsoleErrors.UNSERIALIZABLE_TYPE.on( inspectionTarget, classDescriptor )) } } -} \ No newline at end of file +} + +private fun canBeSerializedInternally(descriptor: ClassDescriptor): Boolean { + @Suppress("UNUSED_VARIABLE") val name = when (descriptor.defaultType.getJetTypeFqName(false)) { + "kotlin.Unit" -> "UnitSerializer" + "Z", "kotlin.Boolean" -> "BooleanSerializer" + "B", "kotlin.Byte" -> "ByteSerializer" + "S", "kotlin.Short" -> "ShortSerializer" + "I", "kotlin.Int" -> "IntSerializer" + "J", "kotlin.Long" -> "LongSerializer" + "F", "kotlin.Float" -> "FloatSerializer" + "D", "kotlin.Double" -> "DoubleSerializer" + "C", "kotlin.Char" -> "CharSerializer" + "kotlin.String" -> "StringSerializer" + "kotlin.Pair" -> "PairSerializer" + "kotlin.Triple" -> "TripleSerializer" + "kotlin.collections.Collection", "kotlin.collections.List", + "kotlin.collections.ArrayList", "kotlin.collections.MutableList", + -> "ArrayListSerializer" + "kotlin.collections.Set", "kotlin.collections.LinkedHashSet", "kotlin.collections.MutableSet" -> "LinkedHashSetSerializer" + "kotlin.collections.HashSet" -> "HashSetSerializer" + "kotlin.collections.Map", "kotlin.collections.LinkedHashMap", "kotlin.collections.MutableMap" -> "LinkedHashMapSerializer" + "kotlin.collections.HashMap" -> "HashMapSerializer" + "kotlin.collections.Map.Entry" -> "MapEntrySerializer" + "kotlin.ByteArray" -> "ByteArraySerializer" + "kotlin.ShortArray" -> "ShortArraySerializer" + "kotlin.IntArray" -> "IntArraySerializer" + "kotlin.LongArray" -> "LongArraySerializer" + "kotlin.CharArray" -> "CharArraySerializer" + "kotlin.FloatArray" -> "FloatArraySerializer" + "kotlin.DoubleArray" -> "DoubleArraySerializer" + "kotlin.BooleanArray" -> "BooleanArraySerializer" + "java.lang.Boolean" -> "BooleanSerializer" + "java.lang.Byte" -> "ByteSerializer" + "java.lang.Short" -> "ShortSerializer" + "java.lang.Integer" -> "IntSerializer" + "java.lang.Long" -> "LongSerializer" + "java.lang.Float" -> "FloatSerializer" + "java.lang.Double" -> "DoubleSerializer" + "java.lang.Character" -> "CharSerializer" + "java.lang.String" -> "StringSerializer" + "java.util.Collection", "java.util.List", "java.util.ArrayList" -> "ArrayListSerializer" + "java.util.Set", "java.util.LinkedHashSet" -> "LinkedHashSetSerializer" + "java.util.HashSet" -> "HashSetSerializer" + "java.util.Map", "java.util.LinkedHashMap" -> "LinkedHashMapSerializer" + "java.util.HashMap" -> "HashMapSerializer" + "java.util.Map.Entry" -> "MapEntrySerializer" + else -> return false + } + return true +} + From d1f431e98e59a9e98c004ecc5d90243c881a5a59 Mon Sep 17 00:00:00 2001 From: Him188 Date: Fri, 13 Nov 2020 15:35:38 +0800 Subject: [PATCH 4/8] Fix resources packaging in buildPlugin --- tools/gradle-plugin/src/MiraiConsoleGradlePlugin.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/gradle-plugin/src/MiraiConsoleGradlePlugin.kt b/tools/gradle-plugin/src/MiraiConsoleGradlePlugin.kt index 427eba7b9..06ea0c733 100644 --- a/tools/gradle-plugin/src/MiraiConsoleGradlePlugin.kt +++ b/tools/gradle-plugin/src/MiraiConsoleGradlePlugin.kt @@ -96,6 +96,9 @@ class MiraiConsoleGradlePlugin : Plugin { compilations.forEach { dependsOn(it.compileKotlinTask) from(it.output) + for (allKotlinSourceSet in it.allKotlinSourceSets) { + from(allKotlinSourceSet.resources) + } } from(project.configurations.getByName("runtimeClasspath").copyRecursive { dependency -> From cf08c2b7673b75f04aa7205c357c95273d001b65 Mon Sep 17 00:00:00 2001 From: Him188 Date: Fri, 13 Nov 2020 18:24:18 +0800 Subject: [PATCH 5/8] Fix loadFromResource --- backend/mirai-console/src/internal/util/CommonUtils.kt | 5 ++++- backend/mirai-console/src/plugin/jvm/JvmPluginDescription.kt | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/backend/mirai-console/src/internal/util/CommonUtils.kt b/backend/mirai-console/src/internal/util/CommonUtils.kt index 037bd0bb7..b1c2c2848 100644 --- a/backend/mirai-console/src/internal/util/CommonUtils.kt +++ b/backend/mirai-console/src/internal/util/CommonUtils.kt @@ -11,6 +11,8 @@ package net.mamoe.mirai.console.internal.util +import net.mamoe.mirai.console.internal.plugin.BuiltInJvmPluginLoaderImpl + internal inline fun runIgnoreException(block: () -> R): R? { try { return block() @@ -41,6 +43,7 @@ internal fun getCallerClassloader(): ClassLoader? { net.mamoe.mirai.console.TestMiraiConosleKt.main(TestMiraiConosle.kt) */ val traces = Thread.currentThread().stackTrace - Class.forName(traces[3].className).classLoader + val classname = traces[3].className + BuiltInJvmPluginLoaderImpl.classLoaders.firstOrNull { it.findClass(classname, true) != null } }.getOrNull() } \ No newline at end of file diff --git a/backend/mirai-console/src/plugin/jvm/JvmPluginDescription.kt b/backend/mirai-console/src/plugin/jvm/JvmPluginDescription.kt index 6a4452879..28d9a96a8 100644 --- a/backend/mirai-console/src/plugin/jvm/JvmPluginDescription.kt +++ b/backend/mirai-console/src/plugin/jvm/JvmPluginDescription.kt @@ -67,7 +67,7 @@ public interface JvmPluginDescription : PluginDescription { * @param filename [ClassLoader.getResourceAsStream] 的参数 `name` * @param pluginClassloader 默认通过 [Thread.getStackTrace] 获取调用方 [Class] 然后获取其 [Class.getClassLoader]. */ - @JvmOverloads + // @JvmOverloads // compiler error @JvmStatic public fun loadFromResource( filename: String = "plugin.yml", From 18a0a95609760ae1086f0247603e67640e42574e Mon Sep 17 00:00:00 2001 From: Him188 Date: Fri, 13 Nov 2020 18:24:33 +0800 Subject: [PATCH 6/8] Fix PluginMainServiceNotConfiguredInspection --- .../PluginMainServiceNotConfiguredInspection.kt | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/tools/intellij-plugin/src/diagnostics/PluginMainServiceNotConfiguredInspection.kt b/tools/intellij-plugin/src/diagnostics/PluginMainServiceNotConfiguredInspection.kt index 5f4568fd8..4d9fd7e9d 100644 --- a/tools/intellij-plugin/src/diagnostics/PluginMainServiceNotConfiguredInspection.kt +++ b/tools/intellij-plugin/src/diagnostics/PluginMainServiceNotConfiguredInspection.kt @@ -11,6 +11,7 @@ package net.mamoe.mirai.console.intellij.diagnostics import com.intellij.codeInspection.ProblemHighlightType import com.intellij.codeInspection.ProblemsHolder +import com.intellij.openapi.progress.impl.CancellationCheck.Companion.runWithCancellationCheck import com.intellij.psi.PsiElementVisitor import net.mamoe.mirai.console.compiler.common.resolve.AUTO_SERVICE import net.mamoe.mirai.console.intellij.diagnostics.fix.ConfigurePluginMainServiceFix @@ -64,14 +65,16 @@ class PluginMainServiceNotConfiguredInspection : AbstractKotlinInspection() { ktClass: KtClassOrObject, fqName: String, ): Boolean { - val sourceRoots = ktClass.module?.rootManager?.sourceRoots ?: return false - val services = sourceRoots.asSequence().flatMap { file -> - SERVICE_FILE_NAMES.asSequence().mapNotNull { serviceFileName -> - file.findFileByRelativePath("META-INF/services/$serviceFileName") + return runWithCancellationCheck { + val sourceRoots = ktClass.module?.rootManager?.sourceRoots ?: return@runWithCancellationCheck false + val services = sourceRoots.asSequence().flatMap { file -> + SERVICE_FILE_NAMES.asSequence().mapNotNull { serviceFileName -> + file.findFileByRelativePath("META-INF/services/$serviceFileName") + } + } + return@runWithCancellationCheck services.any { serviceFile -> + serviceFile.readAction { f -> f.inputStream.bufferedReader().use { it.readLine() }.trim() == fqName } } - } - return services.any { serviceFile -> - serviceFile.readAction { f -> f.inputStream.bufferedReader().use { it.readLine() }.trim() == fqName } } } } \ No newline at end of file From 9a25ac78fa5611c5cfde96300d451e11053421c0 Mon Sep 17 00:00:00 2001 From: Him188 Date: Fri, 13 Nov 2020 18:24:40 +0800 Subject: [PATCH 7/8] 1.0-RC2-dev-6 --- buildSrc/src/main/kotlin/Versions.kt | 2 +- tools/gradle-plugin/src/VersionConstants.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index 424cd4c80..2c0ffc0c7 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -11,7 +11,7 @@ object Versions { const val core = "1.3.3" - const val console = "1.0-RC2-dev-4" + const val console = "1.0-RC2-dev-6" const val consoleGraphical = "0.0.7" const val consoleTerminal = console diff --git a/tools/gradle-plugin/src/VersionConstants.kt b/tools/gradle-plugin/src/VersionConstants.kt index aa639fdcc..5b584aadf 100644 --- a/tools/gradle-plugin/src/VersionConstants.kt +++ b/tools/gradle-plugin/src/VersionConstants.kt @@ -10,6 +10,6 @@ package net.mamoe.mirai.console.gradle internal object VersionConstants { - const val CONSOLE_VERSION = "1.0-RC2-dev-4" // value is written here automatically during build + const val CONSOLE_VERSION = "1.0-RC2-dev-6" // value is written here automatically during build const val CORE_VERSION = "1.3.3" // value is written here automatically during build } \ No newline at end of file From c17762eaf5e9f855e3f3e1ebc9d4292776f7e9c2 Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Fri, 13 Nov 2020 21:06:49 +0800 Subject: [PATCH 8/8] CallerFinder --- backend/mirai-console/build.gradle.kts | 1 + .../src/internal/util/CommonUtils.kt | 19 +++++-------------- .../src/plugin/jvm/JvmPluginDescription.kt | 8 +++++--- build.gradle.kts | 1 + buildSrc/src/main/kotlin/Versions.kt | 3 +++ 5 files changed, 15 insertions(+), 17 deletions(-) diff --git a/backend/mirai-console/build.gradle.kts b/backend/mirai-console/build.gradle.kts index 24fd5e80a..a2e1294e5 100644 --- a/backend/mirai-console/build.gradle.kts +++ b/backend/mirai-console/build.gradle.kts @@ -32,6 +32,7 @@ dependencies { smartImplementation(yamlkt) smartImplementation(`jetbrains-annotations`) + smartImplementation(`caller-finder`) smartApi(`kotlinx-coroutines-jdk8`) testApi(`mirai-core-qqandroid`) diff --git a/backend/mirai-console/src/internal/util/CommonUtils.kt b/backend/mirai-console/src/internal/util/CommonUtils.kt index b1c2c2848..aca7b0d7d 100644 --- a/backend/mirai-console/src/internal/util/CommonUtils.kt +++ b/backend/mirai-console/src/internal/util/CommonUtils.kt @@ -11,6 +11,7 @@ package net.mamoe.mirai.console.internal.util +import io.github.karlatemp.caller.StackFrame import net.mamoe.mirai.console.internal.plugin.BuiltInJvmPluginLoaderImpl internal inline fun runIgnoreException(block: () -> R): R? { @@ -31,19 +32,9 @@ internal inline fun runIgnoreException(block: () -> Unit } } -internal fun getCallerClassloader(): ClassLoader? { +internal fun StackFrame.findLoader(): ClassLoader? { + classInstance?.let { return it.classLoader } return runCatching { - /* - java.base/java.lang.Thread.getStackTrace(Thread.java:1598) - net.mamoe.mirai.console.internal.util.CommonUtils.getCallerClassloader(CommonUtils.kt:37) - net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription$Companion.loadFromResource$default(JvmPluginDescription.kt:67) - net.mamoe.mirai.console.KotlinP.(TestMiraiConosle.kt:34) - net.mamoe.mirai.console.KotlinP.(TestMiraiConosle.kt:34) - net.mamoe.mirai.console.TestMiraiConosleKt.main(TestMiraiConosle.kt:37) - net.mamoe.mirai.console.TestMiraiConosleKt.main(TestMiraiConosle.kt) - */ - val traces = Thread.currentThread().stackTrace - val classname = traces[3].className - BuiltInJvmPluginLoaderImpl.classLoaders.firstOrNull { it.findClass(classname, true) != null } + BuiltInJvmPluginLoaderImpl.classLoaders.firstOrNull { it.findClass(className, true) != null } }.getOrNull() -} \ No newline at end of file +} diff --git a/backend/mirai-console/src/plugin/jvm/JvmPluginDescription.kt b/backend/mirai-console/src/plugin/jvm/JvmPluginDescription.kt index 28d9a96a8..d20a8852e 100644 --- a/backend/mirai-console/src/plugin/jvm/JvmPluginDescription.kt +++ b/backend/mirai-console/src/plugin/jvm/JvmPluginDescription.kt @@ -11,10 +11,12 @@ package net.mamoe.mirai.console.plugin.jvm +import io.github.karlatemp.caller.CallerFinder +import io.github.karlatemp.caller.StackFrame import kotlinx.serialization.Serializable import net.mamoe.mirai.console.compiler.common.ResolveContext import net.mamoe.mirai.console.compiler.common.ResolveContext.Kind.* -import net.mamoe.mirai.console.internal.util.getCallerClassloader +import net.mamoe.mirai.console.internal.util.findLoader import net.mamoe.mirai.console.plugin.description.PluginDependency import net.mamoe.mirai.console.plugin.description.PluginDescription import net.mamoe.mirai.console.util.SemVersion @@ -65,13 +67,13 @@ public interface JvmPluginDescription : PluginDescription { * 从 [pluginClassloader] 读取资源文件 [filename] 并以 YAML 格式解析为 [SimpleJvmPluginDescription] * * @param filename [ClassLoader.getResourceAsStream] 的参数 `name` - * @param pluginClassloader 默认通过 [Thread.getStackTrace] 获取调用方 [Class] 然后获取其 [Class.getClassLoader]. + * @param pluginClassloader 默认通过 [CallerFinder.getCaller] 获取调用方 [StackFrame] 然后获取其 [Class.getClassLoader]. */ // @JvmOverloads // compiler error @JvmStatic public fun loadFromResource( filename: String = "plugin.yml", - pluginClassloader: ClassLoader = getCallerClassloader() ?: error("Cannot find caller classloader, please specify manually."), + pluginClassloader: ClassLoader = CallerFinder.getCaller()?.findLoader() ?: error("Cannot find caller classloader, please specify manually."), ): JvmPluginDescription { val stream = pluginClassloader.getResourceAsStream(filename) ?: error("Cannot find plugin description resource '$filename'") diff --git a/build.gradle.kts b/build.gradle.kts index dcb502a8d..29fe2bea4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -26,6 +26,7 @@ allprojects { maven(url = "https://dl.bintray.com/kotlin/kotlin-eap") jcenter() mavenCentral() + maven(url = "https://dl.bintray.com/karlatemp/misc") } } diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index 2c0ffc0c7..6957a14d2 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -63,3 +63,6 @@ const val `mirai-core-api` = "net.mamoe:mirai-core-api:${Versions.core}" const val yamlkt = "net.mamoe.yamlkt:yamlkt:${Versions.yamlkt}" const val `jetbrains-annotations` = "org.jetbrains:annotations:19.0.0" + + +const val `caller-finder` = "io.github.karlatemp:caller:1.0.1"