From 77e344b4aa487295b62ed703424b88a551bfafb8 Mon Sep 17 00:00:00 2001 From: Him188 Date: Mon, 26 Oct 2020 08:08:49 +0800 Subject: [PATCH 1/4] Support receivers in resolving command --- .../command/resolve/BuiltInCommandCallResolver.kt | 13 ++++++++++--- .../extensions/CommandCallResolverProvider.kt | 10 +++++++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/resolve/BuiltInCommandCallResolver.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/resolve/BuiltInCommandCallResolver.kt index 97774d55c..7f43e3d2b 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/resolve/BuiltInCommandCallResolver.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/resolve/BuiltInCommandCallResolver.kt @@ -2,12 +2,15 @@ package net.mamoe.mirai.console.command.resolve import net.mamoe.mirai.console.command.Command import net.mamoe.mirai.console.command.CommandManager +import net.mamoe.mirai.console.command.CommandSender import net.mamoe.mirai.console.command.descriptor.* import net.mamoe.mirai.console.command.descriptor.ArgumentAcceptance.Companion.isNotAcceptable import net.mamoe.mirai.console.command.parse.CommandCall import net.mamoe.mirai.console.command.parse.CommandValueArgument import net.mamoe.mirai.console.command.parse.DefaultCommandValueArgument import net.mamoe.mirai.console.extensions.CommandCallResolverProvider +import net.mamoe.mirai.console.extensions.CommandCallResolverProviderImpl +import net.mamoe.mirai.console.internal.data.classifierAsKClass import net.mamoe.mirai.console.util.ConsoleExperimentalApi import net.mamoe.mirai.console.util.safeCast import net.mamoe.mirai.message.data.EmptyMessageChain @@ -19,7 +22,7 @@ import net.mamoe.mirai.message.data.asMessageChain @ConsoleExperimentalApi @ExperimentalCommandDescriptors public object BuiltInCommandCallResolver : CommandCallResolver { - public object Provider : CommandCallResolverProvider(BuiltInCommandCallResolver) + public object Provider : CommandCallResolverProvider by CommandCallResolverProviderImpl(BuiltInCommandCallResolver) override fun resolve(call: CommandCall): ResolvedCommandCall? { val callee = CommandManager.matchCommand(call.calleeName) ?: return null @@ -27,7 +30,7 @@ public object BuiltInCommandCallResolver : CommandCallResolver { val valueArguments = call.valueArguments val context = callee.safeCast()?.context - val signature = resolveImpl(callee, valueArguments, context) ?: return null + val signature = resolveImpl(call.caller, callee, valueArguments, context) ?: return null return ResolvedCommandCallImpl(call.caller, callee, @@ -51,14 +54,18 @@ public object BuiltInCommandCallResolver : CommandCallResolver { ) private fun resolveImpl( + caller: CommandSender, callee: Command, valueArguments: List, context: CommandArgumentContext?, ): ResolveData? { - callee.overloads .mapNotNull l@{ signature -> + if (signature.receiverParameter?.type?.classifierAsKClass()?.isInstance(caller) == false) { + return@l null // not compatible receiver + } + val valueParameters = signature.valueParameters val zipped = valueParameters.zip(valueArguments).toMutableList() 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 8be92c470..43e2a6fca 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 @@ -16,8 +16,16 @@ import net.mamoe.mirai.console.extension.AbstractInstanceExtensionPoint import net.mamoe.mirai.console.extension.InstanceExtension @ExperimentalCommandDescriptors -public open class CommandCallResolverProvider(override val instance: CommandCallResolver) : InstanceExtension { +public interface CommandCallResolverProvider : InstanceExtension { public companion object ExtensionPoint : AbstractInstanceExtensionPoint(CommandCallResolverProvider::class, BuiltInCommandCallResolver.Provider) +} + +@ExperimentalCommandDescriptors +public class CommandCallResolverProviderImpl(override val instance: CommandCallResolver) : CommandCallResolverProvider + +@ExperimentalCommandDescriptors +public class CommandCallResolverProviderImplLazy(instanceCalculator: () -> CommandCallResolver) : CommandCallResolverProvider { + override val instance: CommandCallResolver by lazy(instanceCalculator) } \ No newline at end of file From 3933c3e8fbd376bfe031138500e0f259cf3b5a60 Mon Sep 17 00:00:00 2001 From: Him188 Date: Mon, 26 Oct 2020 08:13:59 +0800 Subject: [PATCH 2/4] CommandDeclarationException --- .../mirai/console/command/descriptor/Exceptions.kt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/Exceptions.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/Exceptions.kt index b92ab8b68..4ce6f7338 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/Exceptions.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/Exceptions.kt @@ -29,13 +29,20 @@ public open class NoValueArgumentMappingException( public val forType: KType, ) : CommandResolutionException("Cannot find a CommandArgument mapping for ${forType.qualifiedName}") +public open class CommandResolutionException : RuntimeException { + public constructor() : super() + public constructor(message: String?) : super(message) + public constructor(message: String?, cause: Throwable?) : super(message, cause) + public constructor(cause: Throwable?) : super(cause) +} + @ExperimentalCommandDescriptors public open class CommandDeclarationClashException( public val command: Command, public val signatures: List, -) : CommandResolutionException("Command declaration clash: \n${signatures.joinToString("\n")}") +) : CommandDeclarationException("Declaration clash for command '${command.primaryName}': \n${signatures.joinToString("\n")}") -public open class CommandResolutionException : RuntimeException { +public open class CommandDeclarationException : RuntimeException { public constructor() : super() public constructor(message: String?) : super(message) public constructor(message: String?, cause: Throwable?) : super(message, cause) From 3f0d12342180376ca684f911639cb19414eb185c Mon Sep 17 00:00:00 2001 From: Him188 Date: Mon, 26 Oct 2020 08:14:32 +0800 Subject: [PATCH 3/4] Check receiver type in init --- .../mirai/console/command/descriptor/CommandDescriptor.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/CommandDescriptor.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/CommandDescriptor.kt index b83e6907a..562cc9b40 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/CommandDescriptor.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/CommandDescriptor.kt @@ -22,6 +22,7 @@ import net.mamoe.mirai.console.util.ConsoleExperimentalApi import kotlin.reflect.KClass import kotlin.reflect.KFunction import kotlin.reflect.KType +import kotlin.reflect.full.isSubclassOf import kotlin.reflect.full.isSubtypeOf import kotlin.reflect.typeOf @@ -183,9 +184,13 @@ public class CommandReceiverParameter( override val name: String get() = PARAMETER_NAME init { - check(type.classifier is KClass<*>) { + val classifier = type.classifier + require(classifier is KClass<*>) { "CommandReceiverParameter.type.classifier must be KClass." } + require(classifier.isSubclassOf(CommandSender::class)) { + "CommandReceiverParameter.type.classifier must be subclass of CommandSender." + } } public companion object { From 7c3485ef9b418b40728c5a31073545b0a601e9d6 Mon Sep 17 00:00:00 2001 From: Him188 Date: Mon, 26 Oct 2020 08:28:25 +0800 Subject: [PATCH 4/4] Rename extension impls --- .../extension/PluginComponentStorage.kt | 22 ++++++++++++++++--- .../extensions/CommandCallParserProvider.kt | 2 +- .../extensions/PermissionServiceProvider.kt | 2 +- .../extensions/PluginLoaderProvider.kt | 4 ++-- 4 files changed, 23 insertions(+), 7 deletions(-) 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 402b075df..2eb1451ad 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 @@ -11,6 +11,7 @@ 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.command.resolve.CommandCallResolver import net.mamoe.mirai.console.extensions.* import net.mamoe.mirai.console.internal.extension.AbstractConcurrentComponentStorage import net.mamoe.mirai.console.permission.PermissionService @@ -77,7 +78,7 @@ public class PluginComponentStorage( /** 注册一个 [PermissionServiceProvider] */ @OverloadResolutionByLambdaReturnType public fun contributePermissionService(lazyInstance: () -> PermissionService<*>): Unit = - contribute(PermissionServiceProvider, plugin, LazyPermissionServiceProviderImpl(lazyInstance)) + contribute(PermissionServiceProvider, plugin, PermissionServiceProviderImplLazy(lazyInstance)) /** 注册一个 [PermissionServiceProvider] */ @JvmName("contributePermissionServiceProvider") @@ -90,7 +91,7 @@ public class PluginComponentStorage( /** 注册一个 [PluginLoaderProvider] */ @OverloadResolutionByLambdaReturnType public fun contributePluginLoader(lazyInstance: () -> PluginLoader<*, *>): Unit = - contribute(PluginLoaderProvider, plugin, LazyPluginLoaderProviderImpl(lazyInstance)) + contribute(PluginLoaderProvider, plugin, PluginLoaderProviderImplLazy(lazyInstance)) /** 注册一个 [PluginLoaderProvider] */ @JvmName("contributePluginLoaderProvider") @@ -104,7 +105,7 @@ public class PluginComponentStorage( @ExperimentalCommandDescriptors @OverloadResolutionByLambdaReturnType public fun contributeCommandCallParser(lazyInstance: () -> CommandCallParser): Unit = - contribute(CommandCallParserProvider, plugin, LazyCommandCallParserProviderImpl(lazyInstance)) + contribute(CommandCallParserProvider, plugin, CommandCallParserProviderImplLazy(lazyInstance)) /** 注册一个 [CommandCallParserProvider] */ @ExperimentalCommandDescriptors @@ -112,4 +113,19 @@ public class PluginComponentStorage( @OverloadResolutionByLambdaReturnType public fun contributeCommandCallParser(provider: CommandCallParserProvider): Unit = contribute(CommandCallParserProvider, plugin, provider) + + ///////////////////////////////////// + + /** 注册一个 [CommandCallResolverProvider] */ + @ExperimentalCommandDescriptors + @OverloadResolutionByLambdaReturnType + public fun contributeCommandCallResolver(lazyInstance: () -> CommandCallResolver): Unit = + contribute(CommandCallResolverProvider, plugin, CommandCallResolverProviderImplLazy(lazyInstance)) + + /** 注册一个 [CommandCallResolverProvider] */ + @ExperimentalCommandDescriptors + @JvmName("contributeCommandCallResolverProvider") + @OverloadResolutionByLambdaReturnType + public fun contributeCommandCallParser(provider: CommandCallResolverProvider): Unit = + contribute(CommandCallResolverProvider, 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 399d748dd..51cc23a9f 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 @@ -30,6 +30,6 @@ public interface CommandCallParserProvider : InstanceExtension CommandCallParser) : CommandCallParserProvider { +public class CommandCallParserProviderImplLazy(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/PermissionServiceProvider.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/PermissionServiceProvider.kt index 0415d1f8f..e5c353ae7 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 @@ -32,6 +32,6 @@ public class PermissionServiceProviderImpl(override val instance: PermissionServ /** * @see PermissionServiceProvider */ -public class LazyPermissionServiceProviderImpl(initializer: () -> PermissionService<*>) : PermissionServiceProvider { +public class PermissionServiceProviderImplLazy(initializer: () -> PermissionService<*>) : PermissionServiceProvider { override val instance: PermissionService<*> by lazy(initializer) } \ No newline at end of file diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/PluginLoaderProvider.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/PluginLoaderProvider.kt index 3b96f4ac6..6722e9743 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/PluginLoaderProvider.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/extensions/PluginLoaderProvider.kt @@ -24,7 +24,7 @@ import net.mamoe.mirai.console.plugin.loader.PluginLoader * @see Extension * @see PluginLoader * - * @see LazyPluginLoaderProviderImpl + * @see PluginLoaderProviderImplLazy */ public interface PluginLoaderProvider : InstanceExtension> { public companion object ExtensionPoint : AbstractExtensionPoint(PluginLoaderProvider::class) @@ -32,6 +32,6 @@ public interface PluginLoaderProvider : InstanceExtension> { public class PluginLoaderProviderImpl(override val instance: PluginLoader<*, *>) : PluginLoaderProvider -public class LazyPluginLoaderProviderImpl(initializer: () -> PluginLoader<*, *>) : PluginLoaderProvider { +public class PluginLoaderProviderImplLazy(initializer: () -> PluginLoader<*, *>) : PluginLoaderProvider { override val instance: PluginLoader<*, *> by lazy(initializer) } \ No newline at end of file