diff --git a/backend/mirai-console/src/command/resolve/BuiltInCommandCallResolver.kt b/backend/mirai-console/src/command/resolve/BuiltInCommandCallResolver.kt index f07b09eca..39ab70db7 100644 --- a/backend/mirai-console/src/command/resolve/BuiltInCommandCallResolver.kt +++ b/backend/mirai-console/src/command/resolve/BuiltInCommandCallResolver.kt @@ -17,8 +17,6 @@ import net.mamoe.mirai.console.command.descriptor.ArgumentAcceptance.Companion.i 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 @@ -31,21 +29,20 @@ import net.mamoe.mirai.message.data.asMessageChain @ConsoleExperimentalApi @ExperimentalCommandDescriptors public object BuiltInCommandCallResolver : CommandCallResolver { - public object Provider : CommandCallResolverProvider by CommandCallResolverProviderImpl(BuiltInCommandCallResolver) - - override fun resolve(call: CommandCall): ResolvedCommandCall? { - val callee = CommandManager.matchCommand(call.calleeName) ?: return null + override fun resolve(call: CommandCall): CommandResolveResult { + val callee = CommandManager.matchCommand(call.calleeName) ?: return CommandResolveResult(null) val valueArguments = call.valueArguments val context = callee.safeCast()?.context - val signature = resolveImpl(call.caller, callee, valueArguments, context) ?: return null + val signature = resolveImpl(call.caller, callee, valueArguments, context) ?: return CommandResolveResult(null) - return ResolvedCommandCallImpl(call.caller, + return CommandResolveResult(ResolvedCommandCallImpl(call.caller, callee, signature.signature, signature.zippedArguments.map { it.second }, context ?: EmptyCommandArgumentContext) + ) } private data class ResolveData( diff --git a/backend/mirai-console/src/command/resolve/CommandCallResolver.kt b/backend/mirai-console/src/command/resolve/CommandCallResolver.kt index e4a0ff675..798d3c1c1 100644 --- a/backend/mirai-console/src/command/resolve/CommandCallResolver.kt +++ b/backend/mirai-console/src/command/resolve/CommandCallResolver.kt @@ -9,11 +9,45 @@ package net.mamoe.mirai.console.command.resolve +import net.mamoe.mirai.console.command.CommandExecuteResult import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors import net.mamoe.mirai.console.command.parse.CommandCall import net.mamoe.mirai.console.extensions.CommandCallResolverProvider import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage import net.mamoe.mirai.console.util.ConsoleExperimentalApi +import net.mamoe.mirai.console.util.safeCast +import org.jetbrains.annotations.Contract +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract + +@ExperimentalCommandDescriptors +public class CommandResolveResult private constructor( + internal val value: Any?, +) { + @get:Contract(pure = true) + public val call: ResolvedCommandCall? + get() = value.safeCast() + + @get:Contract(pure = true) + public val failure: CommandExecuteResult.Failure? + get() = value.safeCast() + + public inline fun fold( + onSuccess: (ResolvedCommandCall) -> R, + onFailure: (CommandExecuteResult.Failure) -> R, + ): R { + contract { + callsInPlace(onSuccess, InvocationKind.AT_MOST_ONCE) + callsInPlace(onFailure, InvocationKind.AT_MOST_ONCE) + } + call?.let(onSuccess) + failure?.let(onFailure) + null!! + } + + public constructor(call: ResolvedCommandCall?) : this(call as Any?) + public constructor(failure: CommandExecuteResult.Failure) : this(failure as Any) +} /** * The resolver converting a [CommandCall] into [ResolvedCommandCall] based on registered [] @@ -23,19 +57,17 @@ import net.mamoe.mirai.console.util.ConsoleExperimentalApi */ @ExperimentalCommandDescriptors public interface CommandCallResolver { - public fun resolve(call: CommandCall): ResolvedCommandCall? + public fun resolve(call: CommandCall): CommandResolveResult public companion object { @JvmName("resolveCall") @ConsoleExperimentalApi @ExperimentalCommandDescriptors - public fun CommandCall.resolve(): ResolvedCommandCall? { + public fun CommandCall.resolve(): CommandResolveResult { GlobalComponentStorage.run { - CommandCallResolverProvider.useExtensions { provider -> - provider.instance.resolve(this@resolve)?.let { return it } - } + val instance = CommandCallResolverProvider.findSingletonInstance(CommandCallResolverProvider.builtinImplementation) + return instance.resolve(this@resolve) } - return null } } } \ No newline at end of file diff --git a/backend/mirai-console/src/extensions/CommandCallResolverProvider.kt b/backend/mirai-console/src/extensions/CommandCallResolverProvider.kt index bf63c771d..3b8b5cb35 100644 --- a/backend/mirai-console/src/extensions/CommandCallResolverProvider.kt +++ b/backend/mirai-console/src/extensions/CommandCallResolverProvider.kt @@ -12,14 +12,13 @@ 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.AbstractSingletonExtensionPoint +import net.mamoe.mirai.console.extension.SingletonExtension @ExperimentalCommandDescriptors -public interface CommandCallResolverProvider : InstanceExtension { +public interface CommandCallResolverProvider : SingletonExtension { public companion object ExtensionPoint : - AbstractInstanceExtensionPoint(CommandCallResolverProvider::class, - BuiltInCommandCallResolver.Provider) + AbstractSingletonExtensionPoint(CommandCallResolverProvider::class, BuiltInCommandCallResolver) } @ExperimentalCommandDescriptors