From c29b58d728bf97f12d83ecdbcdbf27f2cdbcda3e Mon Sep 17 00:00:00 2001 From: Him188 Date: Tue, 1 Sep 2020 22:46:51 +0800 Subject: [PATCH] Support static field INSTANCE for JavaPlugin --- .../mirai/console/internal/util/ServiceHelper.kt | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/util/ServiceHelper.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/util/ServiceHelper.kt index 0824d2a02..04e8db113 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/util/ServiceHelper.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/util/ServiceHelper.kt @@ -12,7 +12,9 @@ package net.mamoe.mirai.console.internal.util import net.mamoe.mirai.console.internal.data.cast import net.mamoe.mirai.console.internal.data.createInstanceOrNull import java.io.InputStream +import java.lang.reflect.Modifier import kotlin.reflect.KClass +import java.lang.reflect.Member as JReflectionMember @Suppress("unused") internal class ServiceList( @@ -37,13 +39,16 @@ internal object ServiceHelper { fun ClassLoader.loadService( classname: String ): T? { + @Suppress("UNCHECKED_CAST") return kotlin.runCatching { val clazz = Class.forName(classname, true, this).cast>() - @Suppress("UNCHECKED_CAST") clazz.kotlin.objectInstance + ?: kotlin.runCatching { + clazz.declaredFields.firstOrNull { it.isStatic() && it.name == "INSTANCE" }?.get(null) + }.getOrNull() ?: clazz.kotlin.createInstanceOrNull() - ?: clazz.constructors.firstOrNull { it.parameterCount == 0 }?.newInstance() as T? + ?: clazz.constructors.firstOrNull { it.parameterCount == 0 }?.newInstance() ?: error("Cannot find a no-arg constructor") }.getOrElse { throw ServiceLoadException("Could not load service ${classname}.", it) @@ -53,10 +58,12 @@ internal object ServiceHelper { { "Could not load PluginLoader ${pluginQualifiedName}." }, PluginLoadException("Could not load PluginLoader ${pluginQualifiedName}.", it) )*/ - } + } as T? } } +internal fun JReflectionMember.isStatic(): Boolean = this.modifiers.and(Modifier.STATIC) != 0 + @Suppress("unused", "RedundantVisibilityModifier") internal open class ServiceLoadException : RuntimeException { public constructor() : super()