diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandManager.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandManager.kt index 8d99ab6cc..17b992d79 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandManager.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandManager.kt @@ -15,6 +15,7 @@ package net.mamoe.mirai.console.command +import net.mamoe.kjbb.JvmBlockingBridge import net.mamoe.mirai.console.command.CommandManager.INSTANCE.executeCommand import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors import net.mamoe.mirai.console.command.parse.CommandCall @@ -22,7 +23,6 @@ import net.mamoe.mirai.console.command.parse.CommandCallParser import net.mamoe.mirai.console.command.parse.CommandCallParser.Companion.parseCommandCall import net.mamoe.mirai.console.command.resolve.CommandCallResolver import net.mamoe.mirai.console.command.resolve.ResolvedCommandCall -import net.mamoe.mirai.console.command.resolve.ResolvedCommandCall.Companion.call import net.mamoe.mirai.console.extensions.CommandCallResolverProvider import net.mamoe.mirai.console.internal.command.CommandManagerImpl import net.mamoe.mirai.console.internal.command.CommandManagerImpl.executeCommand @@ -122,35 +122,16 @@ public interface CommandManager { * * @return 执行结果 */ - // @JvmBlockingBridge + @JvmBlockingBridge @OptIn(ExperimentalCommandDescriptors::class) public suspend fun executeCommand( caller: CommandSender, message: Message, checkPermission: Boolean = true, ): CommandExecuteResult { - val call = message.asMessageChain().parseCommandCall(caller) ?: return CommandExecuteResult.CommandNotFound("") - val resolved = call.resolve() ?: return CommandExecuteResult.CommandNotFound(call.calleeName) - - val command = resolved.callee - - if (checkPermission && !command.permission.testPermission(caller)) { - return CommandExecuteResult.PermissionDenied(command, call.calleeName) - } - - return kotlin.runCatching { - resolved.call() - }.fold( - onSuccess = { - CommandExecuteResult.Success(resolved.callee, call.calleeName, EmptyMessageChain) - }, - onFailure = { - CommandExecuteResult.ExecutionFailed(it, resolved.callee, call.calleeName, EmptyMessageChain) - } - ) + return executeCommandImpl(this, message, caller, checkPermission) } - /** * 解析并执行一个指令 * @@ -160,7 +141,7 @@ public interface CommandManager { * @return 执行结果 * @see executeCommand */ - // @JvmBlockingBridge + @JvmBlockingBridge public suspend fun CommandSender.executeCommand( message: String, checkPermission: Boolean = true, @@ -191,6 +172,7 @@ public interface CommandManager { public companion object INSTANCE : CommandManager by CommandManagerImpl { // TODO: 2020/8/20 https://youtrack.jetbrains.com/issue/KT-41191 + override val CommandOwner.registeredCommands: List get() = CommandManagerImpl.run { this@registeredCommands.registeredCommands } override fun CommandOwner.unregisterAllCommands(): Unit = CommandManagerImpl.run { unregisterAllCommands() } override fun Command.register(override: Boolean): Boolean = CommandManagerImpl.run { register(override) } @@ -234,4 +216,31 @@ public suspend fun Command.execute( append(arguments) } return CommandManager.executeCommand(sender, chain, checkPermission) -} \ No newline at end of file +} + + +// Don't move into CommandManager, compilation error / VerifyError +@OptIn(ExperimentalCommandDescriptors::class) +internal suspend fun executeCommandImpl( + receiver: CommandManager, + message: Message, + caller: CommandSender, + checkPermission: Boolean, +): CommandExecuteResult = with(receiver) { + val call = message.asMessageChain().parseCommandCall(caller) ?: return CommandExecuteResult.CommandNotFound("") + val resolved = call.resolve() ?: return CommandExecuteResult.CommandNotFound(call.calleeName) + + val command = resolved.callee + + if (checkPermission && !command.permission.testPermission(caller)) { + return CommandExecuteResult.PermissionDenied(command, call.calleeName) + } + + return try { + resolved.calleeSignature.call(resolved) + CommandExecuteResult.Success(resolved.callee, call.calleeName, EmptyMessageChain) + } catch (e: Throwable) { + CommandExecuteResult.ExecutionFailed(e, resolved.callee, call.calleeName, EmptyMessageChain) + } +} + 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 2fdc5f424..3a59735ad 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 @@ -9,7 +9,6 @@ package net.mamoe.mirai.console.command.descriptor -import net.mamoe.kjbb.JvmBlockingBridge import net.mamoe.mirai.console.command.descriptor.ArgumentAcceptance.Companion.isAcceptable import net.mamoe.mirai.console.command.descriptor.CommandValueParameter.UserDefinedType.Companion.createOptional import net.mamoe.mirai.console.command.descriptor.CommandValueParameter.UserDefinedType.Companion.createRequired @@ -30,7 +29,6 @@ import kotlin.reflect.typeOf public interface CommandSignatureVariant { public val valueParameters: List> - @JvmBlockingBridge public suspend fun call(resolvedCommandCall: ResolvedCommandCall) } diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/resolve/ResolvedCommandCall.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/resolve/ResolvedCommandCall.kt index e0505279e..9639fc970 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/resolve/ResolvedCommandCall.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/resolve/ResolvedCommandCall.kt @@ -50,13 +50,13 @@ public interface ResolvedCommandCall { @ConsoleExperimentalApi public val resolvedValueArguments: List - public companion object { - @JvmStatic - @ExperimentalCommandDescriptors - public suspend fun ResolvedCommandCall.call() { - return this.calleeSignature.call(this) - } - } + public companion object +} + +// Don't move into companion, compilation error +@ExperimentalCommandDescriptors +public suspend inline fun ResolvedCommandCall.call() { + return this@call.calleeSignature.call(this@call) } @ExperimentalCommandDescriptors diff --git a/backend/mirai-console/src/test/kotlin/net/mamoe/mirai/console/command/TestCommand.kt b/backend/mirai-console/src/test/kotlin/net/mamoe/mirai/console/command/TestCommand.kt index bd3b1487f..90e55be2a 100644 --- a/backend/mirai-console/src/test/kotlin/net/mamoe/mirai/console/command/TestCommand.kt +++ b/backend/mirai-console/src/test/kotlin/net/mamoe/mirai/console/command/TestCommand.kt @@ -22,6 +22,7 @@ import net.mamoe.mirai.console.command.CommandManager.INSTANCE.registeredCommand import net.mamoe.mirai.console.command.CommandManager.INSTANCE.unregister import net.mamoe.mirai.console.command.CommandManager.INSTANCE.unregisterAllCommands import net.mamoe.mirai.console.command.descriptor.CommandValueArgumentParser +import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors import net.mamoe.mirai.console.command.descriptor.buildCommandArgumentContext import net.mamoe.mirai.console.initTestEnvironment import net.mamoe.mirai.console.internal.command.CommandManagerImpl @@ -87,9 +88,11 @@ internal class TestCommand { @Test fun testSimpleExecute() = runBlocking { - assertEquals("test", withTesting { - assertSuccess(TestSimpleCommand.execute(sender, "test")) - }.contentToString()) + TestSimpleCommand.withRegistration { + assertEquals("test", withTesting { + assertSuccess(TestSimpleCommand.execute(sender, "test")) + }.contentToString()) + } } @Test @@ -263,6 +266,7 @@ internal class TestCommand { } } +@OptIn(ExperimentalCommandDescriptors::class) internal fun assertSuccess(result: CommandExecuteResult) { if (result.isFailure()) { throw result.exception ?: AssertionError(result.toString())