From ce0bf8d8beb627a68c869a959043a4bb08e86cb1 Mon Sep 17 00:00:00 2001 From: Him188 Date: Sun, 25 Oct 2020 21:40:41 +0800 Subject: [PATCH] Review extension --- .../parse/SpaceSeparatedCommandCallParser.kt | 3 +- .../mirai/console/extension/ExtensionPoint.kt | 60 ++++++++++++++++--- .../extension/PluginComponentStorage.kt | 31 +++++++--- .../extensions/CommandCallParserProvider.kt | 16 ++++- .../extensions/CommandCallResolverProvider.kt | 5 +- .../extensions/PermissionServiceProvider.kt | 7 +-- .../MiraiConsoleImplementationBridge.kt | 4 +- .../extension/ComponentStorageInternal.kt | 2 +- .../console/permission/PermissionService.kt | 6 +- 9 files changed, 100 insertions(+), 34 deletions(-) diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/parse/SpaceSeparatedCommandCallParser.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/parse/SpaceSeparatedCommandCallParser.kt index 8cb917344..b17cabdaf 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/parse/SpaceSeparatedCommandCallParser.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/parse/SpaceSeparatedCommandCallParser.kt @@ -3,6 +3,7 @@ package net.mamoe.mirai.console.command.parse import net.mamoe.mirai.console.command.CommandSender import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors import net.mamoe.mirai.console.extensions.CommandCallParserProvider +import net.mamoe.mirai.console.extensions.CommandCallParserProviderImpl import net.mamoe.mirai.console.internal.command.flattenCommandComponents import net.mamoe.mirai.console.util.ConsoleExperimentalApi import net.mamoe.mirai.message.data.MessageChain @@ -22,5 +23,5 @@ public object SpaceSeparatedCommandCallParser : CommandCallParser { ) } - public object Provider : CommandCallParserProvider(SpaceSeparatedCommandCallParser) + public object Provider : CommandCallParserProvider by CommandCallParserProviderImpl(SpaceSeparatedCommandCallParser) } \ No newline at end of file diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extension/ExtensionPoint.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extension/ExtensionPoint.kt index d076776c0..b5580db83 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extension/ExtensionPoint.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extension/ExtensionPoint.kt @@ -7,30 +7,72 @@ * https://github.com/mamoe/mirai/blob/master/LICENSE */ -@file:Suppress("unused", "INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +@file:Suppress("unused", "INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "MemberVisibilityCanBePrivate") package net.mamoe.mirai.console.extension +import net.mamoe.mirai.console.extensions.SingletonExtensionSelector +import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage +import net.mamoe.mirai.console.util.ConsoleExperimentalApi import kotlin.reflect.KClass + /** - * 由 [Extension] 的 `companion` 实现. + * 由 [Extension] 的伴生对象实现. + * + * @see AbstractExtensionPoint */ public interface ExtensionPoint { + /** + * 扩展实例 [T] 的类型 + */ public val extensionType: KClass } -public open class AbstractExtensionPoint( +public abstract class AbstractExtensionPoint( public override val extensionType: KClass, ) : ExtensionPoint -public open class InstanceExtensionPoint, T>( - extensionType: KClass, - public vararg val builtinImplementations: E, -) : AbstractExtensionPoint(extensionType) - /** * 表示一个 [SingletonExtension] 的 [ExtensionPoint] */ -public interface SingletonExtensionPoint> : ExtensionPoint \ No newline at end of file +public interface SingletonExtensionPoint> : ExtensionPoint + +/** + * 表示一个 [InstanceExtension] 的 [ExtensionPoint] + */ +public interface InstanceExtensionPoint> : ExtensionPoint + +/** + * 表示一个 [FunctionExtension] 的 [ExtensionPoint] + */ +public interface FunctionExtensionPoint : ExtensionPoint + + +public abstract class AbstractInstanceExtensionPoint, T>( + extensionType: KClass, + /** + * 内建的实现列表. + */ + @ConsoleExperimentalApi + public vararg val builtinImplementations: E, +) : AbstractExtensionPoint(extensionType) + +public abstract class AbstractSingletonExtensionPoint, T>( + extensionType: KClass, + /** + * 内建的实现. + */ + @ConsoleExperimentalApi + public val builtinImplementation: T, +) : AbstractExtensionPoint(extensionType), SingletonExtensionPoint { + + /** + * 由 [SingletonExtensionSelector] 选择后的实例. + */ + @ConsoleExperimentalApi + public val selectedInstance: T by lazy { + GlobalComponentStorage.run { this@AbstractSingletonExtensionPoint.findSingletonInstance(extensionType, builtinImplementation) } + } +} \ No newline at end of file diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extension/PluginComponentStorage.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extension/PluginComponentStorage.kt index 74acd845c..402b075df 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extension/PluginComponentStorage.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extension/PluginComponentStorage.kt @@ -9,6 +9,8 @@ package net.mamoe.mirai.console.extension +import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors +import net.mamoe.mirai.console.command.parse.CommandCallParser import net.mamoe.mirai.console.extensions.* import net.mamoe.mirai.console.internal.extension.AbstractConcurrentComponentStorage import net.mamoe.mirai.console.permission.PermissionService @@ -35,7 +37,7 @@ public class PluginComponentStorage( ): Unit = contribute(extensionPoint, plugin, lazyInstance) /** - * 注册一个扩展 + * 注册一个扩展. [E] 必须拥有伴生对象为 [ExtensionPoint]. */ public inline fun contribute( noinline lazyInstance: () -> E, @@ -74,16 +76,14 @@ public class PluginComponentStorage( /** 注册一个 [PermissionServiceProvider] */ @OverloadResolutionByLambdaReturnType - public fun contributePermissionService( - lazyInstance: () -> PermissionService<*>, - ): Unit = contribute(PermissionServiceProvider, plugin, LazyPermissionServiceProviderImpl(lazyInstance)) + public fun contributePermissionService(lazyInstance: () -> PermissionService<*>): Unit = + contribute(PermissionServiceProvider, plugin, LazyPermissionServiceProviderImpl(lazyInstance)) /** 注册一个 [PermissionServiceProvider] */ @JvmName("contributePermissionServiceProvider") @OverloadResolutionByLambdaReturnType - public fun contributePermissionService( - lazyProvider: () -> PermissionServiceProvider, - ): Unit = contribute(PermissionServiceProvider, plugin, lazyProvider) + public fun contributePermissionService(lazyProvider: () -> PermissionServiceProvider): Unit = + contribute(PermissionServiceProvider, plugin, lazyProvider) ///////////////////////////////////// @@ -96,5 +96,20 @@ public class PluginComponentStorage( @JvmName("contributePluginLoaderProvider") @OverloadResolutionByLambdaReturnType public fun contributePluginLoader(lazyProvider: () -> PluginLoaderProvider): Unit = - contribute(PluginLoaderProvider, plugin, lazyProvider) + contribute(PluginLoaderProvider, plugin, lazyProvider) // lazy for safety + + ///////////////////////////////////// + + /** 注册一个 [CommandCallParserProvider] */ + @ExperimentalCommandDescriptors + @OverloadResolutionByLambdaReturnType + public fun contributeCommandCallParser(lazyInstance: () -> CommandCallParser): Unit = + contribute(CommandCallParserProvider, plugin, LazyCommandCallParserProviderImpl(lazyInstance)) + + /** 注册一个 [CommandCallParserProvider] */ + @ExperimentalCommandDescriptors + @JvmName("contributeCommandCallParserProvider") + @OverloadResolutionByLambdaReturnType + public fun contributeCommandCallParser(provider: CommandCallParserProvider): Unit = + contribute(CommandCallParserProvider, plugin, provider) } \ No newline at end of file diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/CommandCallParserProvider.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/CommandCallParserProvider.kt index 4a19a0fac..399d748dd 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/CommandCallParserProvider.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/CommandCallParserProvider.kt @@ -12,14 +12,24 @@ package net.mamoe.mirai.console.extensions import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors import net.mamoe.mirai.console.command.parse.CommandCallParser import net.mamoe.mirai.console.command.parse.SpaceSeparatedCommandCallParser +import net.mamoe.mirai.console.extension.AbstractInstanceExtensionPoint import net.mamoe.mirai.console.extension.InstanceExtension -import net.mamoe.mirai.console.extension.InstanceExtensionPoint /** * The provider of [CommandCallParser] */ @ExperimentalCommandDescriptors -public open class CommandCallParserProvider(override val instance: CommandCallParser) : InstanceExtension { +public interface CommandCallParserProvider : InstanceExtension { public companion object ExtensionPoint : - InstanceExtensionPoint(CommandCallParserProvider::class, SpaceSeparatedCommandCallParser.Provider) + AbstractInstanceExtensionPoint(CommandCallParserProvider::class, + SpaceSeparatedCommandCallParser.Provider) +} + + +@ExperimentalCommandDescriptors +public class CommandCallParserProviderImpl(override val instance: CommandCallParser) : CommandCallParserProvider + +@ExperimentalCommandDescriptors +public class LazyCommandCallParserProviderImpl(instanceCalculator: () -> CommandCallParser) : CommandCallParserProvider { + override val instance: CommandCallParser by lazy(instanceCalculator) } \ No newline at end of file diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/CommandCallResolverProvider.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/CommandCallResolverProvider.kt index e6e390d99..8be92c470 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/CommandCallResolverProvider.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/CommandCallResolverProvider.kt @@ -12,11 +12,12 @@ package net.mamoe.mirai.console.extensions import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors import net.mamoe.mirai.console.command.resolve.BuiltInCommandCallResolver import net.mamoe.mirai.console.command.resolve.CommandCallResolver +import net.mamoe.mirai.console.extension.AbstractInstanceExtensionPoint import net.mamoe.mirai.console.extension.InstanceExtension -import net.mamoe.mirai.console.extension.InstanceExtensionPoint @ExperimentalCommandDescriptors public open class CommandCallResolverProvider(override val instance: CommandCallResolver) : InstanceExtension { public companion object ExtensionPoint : - InstanceExtensionPoint(CommandCallResolverProvider::class, BuiltInCommandCallResolver.Provider) + AbstractInstanceExtensionPoint(CommandCallResolverProvider::class, + BuiltInCommandCallResolver.Provider) } \ No newline at end of file diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/PermissionServiceProvider.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/PermissionServiceProvider.kt index 0fa2b9f26..0415d1f8f 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/PermissionServiceProvider.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/PermissionServiceProvider.kt @@ -9,9 +9,9 @@ package net.mamoe.mirai.console.extensions -import net.mamoe.mirai.console.extension.AbstractExtensionPoint +import net.mamoe.mirai.console.extension.AbstractSingletonExtensionPoint import net.mamoe.mirai.console.extension.SingletonExtension -import net.mamoe.mirai.console.extension.SingletonExtensionPoint +import net.mamoe.mirai.console.internal.permission.BuiltInPermissionService import net.mamoe.mirai.console.permission.PermissionService /** @@ -21,8 +21,7 @@ import net.mamoe.mirai.console.permission.PermissionService */ public interface PermissionServiceProvider : SingletonExtension> { public companion object ExtensionPoint : - AbstractExtensionPoint(PermissionServiceProvider::class), - SingletonExtensionPoint + AbstractSingletonExtensionPoint>(PermissionServiceProvider::class, BuiltInPermissionService) } /** diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/MiraiConsoleImplementationBridge.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/MiraiConsoleImplementationBridge.kt index fd587247b..6b98780cc 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/MiraiConsoleImplementationBridge.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/MiraiConsoleImplementationBridge.kt @@ -163,9 +163,7 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI phase `load PermissionService`@{ mainLogger.verbose { "Loading PermissionService..." } - PermissionService.instanceField = GlobalComponentStorage.run { - PermissionServiceProvider.findSingletonInstance(BuiltInPermissionService) - } + PermissionServiceProvider.selectedInstance // init PermissionService.INSTANCE.let { ps -> if (ps is BuiltInPermissionService) { diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/extension/ComponentStorageInternal.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/extension/ComponentStorageInternal.kt index b3072ad49..803ccc8d4 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/extension/ComponentStorageInternal.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/extension/ComponentStorageInternal.kt @@ -54,7 +54,7 @@ internal abstract class AbstractConcurrentComponentStorage : ComponentStorage { internal fun ExtensionPoint.getExtensions(): Set> { val userDefined = instances.getOrPut(this, ::CopyOnWriteArraySet) as Set> - val builtins = if (this is InstanceExtensionPoint<*, *>) { + val builtins = if (this is AbstractInstanceExtensionPoint<*, *>) { this.builtinImplementations.mapTo(HashSet()) { DataExtensionRegistry(null, it) } as Set> } else null diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/permission/PermissionService.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/permission/PermissionService.kt index 130fe28fd..b86f97612 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/permission/PermissionService.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/permission/PermissionService.kt @@ -139,15 +139,15 @@ public interface PermissionService

{ public fun cancel(permitteeId: PermitteeId, permission: P, recursive: Boolean) public companion object { - internal var instanceField: PermissionService<*>? = null - /** * [PermissionService] 实例 + * + * @see PermissionServiceProvider.selectedInstance */ @get:JvmName("getInstance") @JvmStatic public val INSTANCE: PermissionService - get() = instanceField ?: error("PermissionService is not yet initialized therefore cannot be used.") + get() = PermissionServiceProvider.selectedInstance /** * 获取一个权限, 失败时抛出 [NoSuchElementException]