From 86c3b18bca7005c09514d93c8319a9d73fdd461c Mon Sep 17 00:00:00 2001 From: Him188 Date: Fri, 9 Oct 2020 12:35:16 +0800 Subject: [PATCH] CommandValueArgumentParser --- .../mirai/console/command/BuiltInCommands.kt | 4 +- .../mirai/console/command/CompositeCommand.kt | 2 +- .../mirai/console/command/SimpleCommand.kt | 2 +- .../descriptor/CommandArgumentContext.kt | 84 +++++++++---------- .../CommandArgumentParserBuiltins.kt | 50 +++++------ .../CommandArgumentParserException.kt | 4 +- .../command/descriptor/CommandDescriptor.kt | 2 +- ...arser.kt => CommandValueArgumentParser.kt} | 46 +++++----- .../console/command/descriptor/TypeVariant.kt | 7 +- .../command/parse/CommandValueArgument.kt | 13 ++- .../command/CompositeCommand.CommandParam.kt | 14 ++-- .../mirai/console/command/TestCommand.kt | 4 +- 12 files changed, 122 insertions(+), 110 deletions(-) rename backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/{CommandArgumentParser.kt => CommandValueArgumentParser.kt} (74%) diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/BuiltInCommands.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/BuiltInCommands.kt index d5c56ecfd..f37299e00 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/BuiltInCommands.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/BuiltInCommands.kt @@ -150,8 +150,8 @@ public object BuiltInCommands { ConsoleCommandOwner, "permission", "权限", "perm", description = "管理权限", overrideContext = buildCommandArgumentContext { - PermitteeId::class with PermitteeIdArgumentParser - Permission::class with PermissionIdArgumentParser.map { id -> + PermitteeId::class with PermitteeIdValueArgumentParser + Permission::class with PermissionIdValueArgumentParser.map { id -> kotlin.runCatching { id.findCorrespondingPermissionOrFail() }.getOrElse { illegalArgument("指令不存在: $id", it) } diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CompositeCommand.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CompositeCommand.kt index 3dcb105b7..77126b96b 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CompositeCommand.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CompositeCommand.kt @@ -99,7 +99,7 @@ public abstract class CompositeCommand( public override val usage: String get() = super.usage /** - * [CommandArgumentParser] 的环境 + * [CommandValueArgumentParser] 的环境 */ public final override val context: CommandArgumentContext = CommandArgumentContext.Builtins + overrideContext diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/SimpleCommand.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/SimpleCommand.kt index 1f4fef692..7a4a0e985 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/SimpleCommand.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/SimpleCommand.kt @@ -31,7 +31,7 @@ import net.mamoe.mirai.message.data.MessageChain * 简单的, 支持参数自动解析的指令. * * 要查看指令解析流程, 参考 [CommandManager.executeCommand] - * 要查看参数解析方式, 参考 [CommandArgumentParser] + * 要查看参数解析方式, 参考 [CommandValueArgumentParser] * * Kotlin 实现: * ``` diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/CommandArgumentContext.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/CommandArgumentContext.kt index a169f30b1..acc3d3d25 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/CommandArgumentContext.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/CommandArgumentContext.kt @@ -29,7 +29,7 @@ import kotlin.reflect.full.isSubclassOf /** - * 指令参数环境, 即 [CommandArgumentParser] 的集合, 用于 [CompositeCommand] 和 [SimpleCommand]. + * 指令参数环境, 即 [CommandValueArgumentParser] 的集合, 用于 [CompositeCommand] 和 [SimpleCommand]. * * 在指令解析时, 总是从 [CommandArgumentContextAware.context] 搜索相关解析器 * @@ -38,20 +38,20 @@ import kotlin.reflect.full.isSubclassOf * @see SimpleCommandArgumentContext 简单实现 * @see EmptyCommandArgumentContext 空实现, 类似 [emptyList] * - * @see CommandArgumentContext.Builtins 内建 [CommandArgumentParser] + * @see CommandArgumentContext.Builtins 内建 [CommandValueArgumentParser] * * @see buildCommandArgumentContext DSL 构造 */ public interface CommandArgumentContext { /** - * [KClass] 到 [CommandArgumentParser] 的匹配 + * [KClass] 到 [CommandValueArgumentParser] 的匹配 */ public data class ParserPair( val klass: KClass, - val parser: CommandArgumentParser, + val parser: CommandValueArgumentParser, ) - public operator fun get(klass: KClass): CommandArgumentParser? + public operator fun get(klass: KClass): CommandValueArgumentParser? public fun toList(): List> @@ -66,32 +66,32 @@ public interface CommandArgumentContext { } /** - * 内建的默认 [CommandArgumentParser] + * 内建的默认 [CommandValueArgumentParser] */ public object Builtins : CommandArgumentContext by (buildCommandArgumentContext { - Int::class with IntArgumentParser - Byte::class with ByteArgumentParser - Short::class with ShortArgumentParser - Boolean::class with BooleanArgumentParser - String::class with StringArgumentParser - Long::class with LongArgumentParser - Double::class with DoubleArgumentParser - Float::class with FloatArgumentParser + Int::class with IntValueArgumentParser + Byte::class with ByteValueArgumentParser + Short::class with ShortValueArgumentParser + Boolean::class with BooleanValueArgumentParser + String::class with StringValueArgumentParser + Long::class with LongValueArgumentParser + Double::class with DoubleValueArgumentParser + Float::class with FloatValueArgumentParser - Image::class with ImageArgumentParser - PlainText::class with PlainTextArgumentParser + Image::class with ImageValueArgumentParser + PlainText::class with PlainTextValueArgumentParser - Contact::class with ExistingContactArgumentParser - User::class with ExistingUserArgumentParser - Member::class with ExistingMemberArgumentParser - Group::class with ExistingGroupArgumentParser - Friend::class with ExistingFriendArgumentParser - Bot::class with ExistingBotArgumentParser + Contact::class with ExistingContactValueArgumentParser + User::class with ExistingUserValueArgumentParser + Member::class with ExistingMemberValueArgumentParser + Group::class with ExistingGroupValueArgumentParser + Friend::class with ExistingFriendValueArgumentParser + Bot::class with ExistingBotValueArgumentParser - PermissionId::class with PermissionIdArgumentParser - PermitteeId::class with PermitteeIdArgumentParser + PermissionId::class with PermissionIdValueArgumentParser + PermitteeId::class with PermitteeIdValueArgumentParser - MessageContent::class with RawContentArgumentParser + MessageContent::class with RawContentValueArgumentParser }) } @@ -103,7 +103,7 @@ public interface CommandArgumentContext { */ public interface CommandArgumentContextAware { /** - * [CommandArgumentParser] 的集合 + * [CommandValueArgumentParser] 的集合 */ public val context: CommandArgumentContext } @@ -117,7 +117,7 @@ public operator fun CommandArgumentContext.plus(replacer: CommandArgumentContext if (replacer == EmptyCommandArgumentContext) return this if (this == EmptyCommandArgumentContext) return replacer return object : CommandArgumentContext { - override fun get(klass: KClass): CommandArgumentParser? = + override fun get(klass: KClass): CommandValueArgumentParser? = replacer[klass] ?: this@plus[klass] override fun toList(): List> = replacer.toList() + this@plus.toList() @@ -132,8 +132,8 @@ public operator fun CommandArgumentContext.plus(replacer: List>): if (this == EmptyCommandArgumentContext) return SimpleCommandArgumentContext(replacer) return object : CommandArgumentContext { @Suppress("UNCHECKED_CAST") - override fun get(klass: KClass): CommandArgumentParser? = - replacer.firstOrNull { klass.isSubclassOf(it.klass) }?.parser as CommandArgumentParser? + override fun get(klass: KClass): CommandValueArgumentParser? = + replacer.firstOrNull { klass.isSubclassOf(it.klass) }?.parser as CommandValueArgumentParser? ?: this@plus[klass] override fun toList(): List> = replacer.toList() + this@plus.toList() @@ -149,9 +149,9 @@ public operator fun CommandArgumentContext.plus(replacer: List>): public class SimpleCommandArgumentContext( public val list: List>, ) : CommandArgumentContext { - override fun get(klass: KClass): CommandArgumentParser? = + override fun get(klass: KClass): CommandValueArgumentParser? = (this.list.firstOrNull { klass == it.klass }?.parser - ?: this.list.firstOrNull { klass.isSubclassOf(it.klass) }?.parser) as CommandArgumentParser? + ?: this.list.firstOrNull { klass.isSubclassOf(it.klass) }?.parser) as CommandValueArgumentParser? override fun toList(): List> = list } @@ -203,14 +203,14 @@ public class CommandArgumentContextBuilder : MutableList> by mutab * 添加一个指令解析器. */ @JvmName("add") - public infix fun Class.with(parser: CommandArgumentParser): CommandArgumentContextBuilder = + public infix fun Class.with(parser: CommandValueArgumentParser): CommandArgumentContextBuilder = this.kotlin with parser /** * 添加一个指令解析器 */ @JvmName("add") - public inline infix fun KClass.with(parser: CommandArgumentParser): CommandArgumentContextBuilder { + public inline infix fun KClass.with(parser: CommandValueArgumentParser): CommandArgumentContextBuilder { add(ParserPair(this, parser)) return this@CommandArgumentContextBuilder } @@ -221,9 +221,9 @@ public class CommandArgumentContextBuilder : MutableList> by mutab @JvmSynthetic @LowPriorityInOverloadResolution public inline infix fun KClass.with( - crossinline parser: CommandArgumentParser.(s: String, sender: CommandSender) -> T, + crossinline parser: CommandValueArgumentParser.(s: String, sender: CommandSender) -> T, ): CommandArgumentContextBuilder { - add(ParserPair(this, object : CommandArgumentParser { + add(ParserPair(this, object : CommandValueArgumentParser { override fun parse(raw: String, sender: CommandSender): T = parser(raw, sender) })) return this@CommandArgumentContextBuilder @@ -234,16 +234,16 @@ public class CommandArgumentContextBuilder : MutableList> by mutab */ @JvmSynthetic public inline infix fun KClass.with( - crossinline parser: CommandArgumentParser.(s: String) -> T, + crossinline parser: CommandValueArgumentParser.(s: String) -> T, ): CommandArgumentContextBuilder { - add(ParserPair(this, object : CommandArgumentParser { + add(ParserPair(this, object : CommandValueArgumentParser { override fun parse(raw: String, sender: CommandSender): T = parser(raw) })) return this@CommandArgumentContextBuilder } @JvmSynthetic - public inline fun add(parser: CommandArgumentParser): CommandArgumentContextBuilder { + public inline fun add(parser: CommandValueArgumentParser): CommandArgumentContextBuilder { add(ParserPair(T::class, parser)) return this@CommandArgumentContextBuilder } @@ -254,8 +254,8 @@ public class CommandArgumentContextBuilder : MutableList> by mutab @ConsoleExperimentalApi @JvmSynthetic public inline infix fun add( - crossinline parser: CommandArgumentParser<*>.(s: String) -> T, - ): CommandArgumentContextBuilder = T::class with object : CommandArgumentParser { + crossinline parser: CommandValueArgumentParser<*>.(s: String) -> T, + ): CommandArgumentContextBuilder = T::class with object : CommandValueArgumentParser { override fun parse(raw: String, sender: CommandSender): T = parser(raw) } @@ -266,8 +266,8 @@ public class CommandArgumentContextBuilder : MutableList> by mutab @JvmSynthetic @LowPriorityInOverloadResolution public inline infix fun add( - crossinline parser: CommandArgumentParser<*>.(s: String, sender: CommandSender) -> T, - ): CommandArgumentContextBuilder = T::class with object : CommandArgumentParser { + crossinline parser: CommandValueArgumentParser<*>.(s: String, sender: CommandSender) -> T, + ): CommandArgumentContextBuilder = T::class with object : CommandValueArgumentParser { override fun parse(raw: String, sender: CommandSender): T = parser(raw, sender) } diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/CommandArgumentParserBuiltins.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/CommandArgumentParserBuiltins.kt index 6eec15173..a1fc279e3 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/CommandArgumentParserBuiltins.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/CommandArgumentParserBuiltins.kt @@ -25,7 +25,7 @@ import net.mamoe.mirai.message.data.* /** * 使用 [String.toInt] 解析 */ -public object IntArgumentParser : InternalCommandArgumentParserExtensions { +public object IntValueArgumentParser : InternalCommandValueArgumentParserExtensions { public override fun parse(raw: String, sender: CommandSender): Int = raw.toIntOrNull() ?: illegalArgument("无法解析 $raw 为整数") } @@ -33,7 +33,7 @@ public object IntArgumentParser : InternalCommandArgumentParserExtensions { /** * 使用 [String.toLong] 解析 */ -public object LongArgumentParser : InternalCommandArgumentParserExtensions { +public object LongValueArgumentParser : InternalCommandValueArgumentParserExtensions { public override fun parse(raw: String, sender: CommandSender): Long = raw.toLongOrNull() ?: illegalArgument("无法解析 $raw 为长整数") } @@ -41,7 +41,7 @@ public object LongArgumentParser : InternalCommandArgumentParserExtensions /** * 使用 [String.toShort] 解析 */ -public object ShortArgumentParser : InternalCommandArgumentParserExtensions { +public object ShortValueArgumentParser : InternalCommandValueArgumentParserExtensions { public override fun parse(raw: String, sender: CommandSender): Short = raw.toShortOrNull() ?: illegalArgument("无法解析 $raw 为短整数") } @@ -49,7 +49,7 @@ public object ShortArgumentParser : InternalCommandArgumentParserExtensions { +public object ByteValueArgumentParser : InternalCommandValueArgumentParserExtensions { public override fun parse(raw: String, sender: CommandSender): Byte = raw.toByteOrNull() ?: illegalArgument("无法解析 $raw 为字节") } @@ -57,7 +57,7 @@ public object ByteArgumentParser : InternalCommandArgumentParserExtensions /** * 使用 [String.toDouble] 解析 */ -public object DoubleArgumentParser : InternalCommandArgumentParserExtensions { +public object DoubleValueArgumentParser : InternalCommandValueArgumentParserExtensions { public override fun parse(raw: String, sender: CommandSender): Double = raw.toDoubleOrNull() ?: illegalArgument("无法解析 $raw 为小数") } @@ -65,7 +65,7 @@ public object DoubleArgumentParser : InternalCommandArgumentParserExtensions { +public object FloatValueArgumentParser : InternalCommandValueArgumentParserExtensions { public override fun parse(raw: String, sender: CommandSender): Float = raw.toFloatOrNull() ?: illegalArgument("无法解析 $raw 为小数") } @@ -73,14 +73,14 @@ public object FloatArgumentParser : InternalCommandArgumentParserExtensions { +public object StringValueArgumentParser : InternalCommandValueArgumentParserExtensions { public override fun parse(raw: String, sender: CommandSender): String = raw } /** * 解析 [String] 通过 [Image]. */ -public object ImageArgumentParser : InternalCommandArgumentParserExtensions { +public object ImageValueArgumentParser : InternalCommandValueArgumentParserExtensions { public override fun parse(raw: String, sender: CommandSender): Image { return kotlin.runCatching { Image(raw) @@ -95,7 +95,7 @@ public object ImageArgumentParser : InternalCommandArgumentParserExtensions { +public object PlainTextValueArgumentParser : InternalCommandValueArgumentParserExtensions { public override fun parse(raw: String, sender: CommandSender): PlainText { return PlainText(raw) } @@ -109,7 +109,7 @@ public object PlainTextArgumentParser : InternalCommandArgumentParserExtensions< /** * 当字符串内容为(不区分大小写) "true", "yes", "enabled" */ -public object BooleanArgumentParser : InternalCommandArgumentParserExtensions<Boolean> { +public object BooleanValueArgumentParser : InternalCommandValueArgumentParserExtensions<Boolean> { public override fun parse(raw: String, sender: CommandSender): Boolean = raw.trim().let { str -> str.equals("true", ignoreCase = true) || str.equals("yes", ignoreCase = true) @@ -121,7 +121,7 @@ public object BooleanArgumentParser : InternalCommandArgumentParserExtensions<Bo /** * 根据 [Bot.id] 解析一个登录后的 [Bot] */ -public object ExistingBotArgumentParser : InternalCommandArgumentParserExtensions<Bot> { +public object ExistingBotValueArgumentParser : InternalCommandValueArgumentParserExtensions<Bot> { public override fun parse(raw: String, sender: CommandSender): Bot = if (raw == "~") sender.inferBotOrFail() else raw.findBotOrFail() @@ -136,7 +136,7 @@ public object ExistingBotArgumentParser : InternalCommandArgumentParserExtension /** * 解析任意一个存在的好友. */ -public object ExistingFriendArgumentParser : InternalCommandArgumentParserExtensions<Friend> { +public object ExistingFriendValueArgumentParser : InternalCommandValueArgumentParserExtensions<Friend> { private val syntax = """ - `botId.friendId` - `botId.friendNick` (模糊搜索, 寻找最优匹配) @@ -175,7 +175,7 @@ public object ExistingFriendArgumentParser : InternalCommandArgumentParserExtens /** * 解析任意一个存在的群. */ -public object ExistingGroupArgumentParser : InternalCommandArgumentParserExtensions<Group> { +public object ExistingGroupValueArgumentParser : InternalCommandValueArgumentParserExtensions<Group> { private val syntax = """ - `botId.groupId` - `~` (指代指令调用人自己所在群. 仅群聊天环境下) @@ -202,7 +202,7 @@ public object ExistingGroupArgumentParser : InternalCommandArgumentParserExtensi } } -public object ExistingUserArgumentParser : InternalCommandArgumentParserExtensions<User> { +public object ExistingUserValueArgumentParser : InternalCommandValueArgumentParserExtensions<User> { private val syntax: String = """ - `botId.groupId.memberId` - `botId.groupId.memberCard` (模糊搜索, 寻找最优匹配) @@ -215,11 +215,11 @@ public object ExistingUserArgumentParser : InternalCommandArgumentParserExtensio """.trimIndent() override fun parse(raw: String, sender: CommandSender): User { - return parseImpl(sender, raw, ExistingMemberArgumentParser::parse, ExistingFriendArgumentParser::parse) + return parseImpl(sender, raw, ExistingMemberValueArgumentParser::parse, ExistingFriendValueArgumentParser::parse) } override fun parse(raw: MessageContent, sender: CommandSender): User { - return parseImpl(sender, raw, ExistingMemberArgumentParser::parse, ExistingFriendArgumentParser::parse) + return parseImpl(sender, raw, ExistingMemberValueArgumentParser::parse, ExistingFriendValueArgumentParser::parse) } private fun <T> parseImpl( @@ -246,7 +246,7 @@ public object ExistingUserArgumentParser : InternalCommandArgumentParserExtensio } -public object ExistingContactArgumentParser : InternalCommandArgumentParserExtensions<Contact> { +public object ExistingContactValueArgumentParser : InternalCommandValueArgumentParserExtensions<Contact> { private val syntax: String = """ - `botId.groupId.memberId` - `botId.groupId.memberCard` (模糊搜索, 寻找最优匹配) @@ -259,11 +259,11 @@ public object ExistingContactArgumentParser : InternalCommandArgumentParserExten """.trimIndent() override fun parse(raw: String, sender: CommandSender): Contact { - return parseImpl(sender, raw, ExistingUserArgumentParser::parse, ExistingGroupArgumentParser::parse) + return parseImpl(sender, raw, ExistingUserValueArgumentParser::parse, ExistingGroupValueArgumentParser::parse) } override fun parse(raw: MessageContent, sender: CommandSender): Contact { - return parseImpl(sender, raw, ExistingUserArgumentParser::parse, ExistingGroupArgumentParser::parse) + return parseImpl(sender, raw, ExistingUserValueArgumentParser::parse, ExistingGroupValueArgumentParser::parse) } private fun <T> parseImpl( @@ -286,7 +286,7 @@ public object ExistingContactArgumentParser : InternalCommandArgumentParserExten /** * 解析任意一个群成员. */ -public object ExistingMemberArgumentParser : InternalCommandArgumentParserExtensions<Member> { +public object ExistingMemberValueArgumentParser : InternalCommandValueArgumentParserExtensions<Member> { private val syntax: String = """ - `botId.groupId.memberId` - `botId.groupId.memberCard` (模糊搜索, 寻找最优匹配) @@ -333,7 +333,7 @@ public object ExistingMemberArgumentParser : InternalCommandArgumentParserExtens } } -public object PermissionIdArgumentParser : CommandArgumentParser<PermissionId> { +public object PermissionIdValueArgumentParser : CommandValueArgumentParser<PermissionId> { override fun parse(raw: String, sender: CommandSender): PermissionId { return kotlin.runCatching { PermissionId.parseFromString(raw) }.getOrElse { illegalArgument("无法解析 $raw 为 PermissionId") @@ -341,7 +341,7 @@ public object PermissionIdArgumentParser : CommandArgumentParser<PermissionId> { } } -public object PermitteeIdArgumentParser : CommandArgumentParser<PermitteeId> { +public object PermitteeIdValueArgumentParser : CommandValueArgumentParser<PermitteeId> { override fun parse(raw: String, sender: CommandSender): PermitteeId { return if (raw == "~") sender.permitteeId else kotlin.runCatching { AbstractPermitteeId.parseFromString(raw) }.getOrElse { @@ -351,19 +351,19 @@ public object PermitteeIdArgumentParser : CommandArgumentParser<PermitteeId> { override fun parse(raw: MessageContent, sender: CommandSender): PermitteeId { if (raw is At) { - return ExistingUserArgumentParser.parse(raw, sender).asCommandSender(false).permitteeId + return ExistingUserValueArgumentParser.parse(raw, sender).asCommandSender(false).permitteeId } return super.parse(raw, sender) } } /** 直接返回原始参数 [MessageContent] */ -public object RawContentArgumentParser : CommandArgumentParser<MessageContent> { +public object RawContentValueArgumentParser : CommandValueArgumentParser<MessageContent> { override fun parse(raw: String, sender: CommandSender): MessageContent = PlainText(raw) override fun parse(raw: MessageContent, sender: CommandSender): MessageContent = raw } -internal interface InternalCommandArgumentParserExtensions<T : Any> : CommandArgumentParser<T> { +internal interface InternalCommandValueArgumentParserExtensions<T : Any> : CommandValueArgumentParser<T> { fun String.parseToLongOrFail(): Long = toLongOrNull() ?: illegalArgument("无法解析 $this 为整数") fun Long.findBotOrFail(): Bot = Bot.getInstanceOrNull(this) ?: illegalArgument("无法找到 Bot: $this") diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/CommandArgumentParserException.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/CommandArgumentParserException.kt index bed270637..faae4cf1e 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/CommandArgumentParserException.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/CommandArgumentParserException.kt @@ -16,8 +16,8 @@ package net.mamoe.mirai.console.command.descriptor * * [message] 将会发送给指令调用方. * - * @see CommandArgumentParser - * @see CommandArgumentParser.illegalArgument + * @see CommandValueArgumentParser + * @see CommandValueArgumentParser.illegalArgument */ public class CommandArgumentParserException : RuntimeException { public constructor() : super() 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 79f13cd71..1e0a9af2a 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 @@ -65,7 +65,7 @@ public sealed class CommandValueParameter<T> : ICommandParameter<T> { } /** - * Extended by [CommandArgumentParser] + * Extended by [CommandValueArgumentParser] */ public abstract class Extended<T> : CommandValueParameter<T>() } \ No newline at end of file diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/CommandArgumentParser.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/CommandValueArgumentParser.kt similarity index 74% rename from backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/CommandArgumentParser.kt rename to backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/CommandValueArgumentParser.kt index fb796109e..f87d0d66d 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/CommandArgumentParser.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/CommandValueArgumentParser.kt @@ -32,27 +32,27 @@ import kotlin.contracts.contract * ``` * suspend fun CommandSender.mute(target: Member, duration: Int) * ``` - * [CommandManager] 总是从 [SimpleCommand.context] 搜索一个 [T] 为 [Member] 的 [CommandArgumentParser], 并调用其 [CommandArgumentParser.parse] + * [CommandManager] 总是从 [SimpleCommand.context] 搜索一个 [T] 为 [Member] 的 [CommandValueArgumentParser], 并调用其 [CommandValueArgumentParser.parse] * * ### 内建指令解析器 - * - 基础类型: [ByteArgumentParser], [ShortArgumentParser], [IntArgumentParser], [LongArgumentParser] - * [FloatArgumentParser], [DoubleArgumentParser], - * [BooleanArgumentParser], [StringArgumentParser] + * - 基础类型: [ByteValueArgumentParser], [ShortValueArgumentParser], [IntValueArgumentParser], [LongValueArgumentParser] + * [FloatValueArgumentParser], [DoubleValueArgumentParser], + * [BooleanValueArgumentParser], [StringValueArgumentParser] * - * - [Bot]: [ExistingBotArgumentParser] - * - [Friend]: [ExistingFriendArgumentParser] - * - [Group]: [ExistingGroupArgumentParser] - * - [Member]: [ExistingMemberArgumentParser] - * - [User]: [ExistingUserArgumentParser] - * - [Contact]: [ExistingContactArgumentParser] + * - [Bot]: [ExistingBotValueArgumentParser] + * - [Friend]: [ExistingFriendValueArgumentParser] + * - [Group]: [ExistingGroupValueArgumentParser] + * - [Member]: [ExistingMemberValueArgumentParser] + * - [User]: [ExistingUserValueArgumentParser] + * - [Contact]: [ExistingContactValueArgumentParser] * * * @see SimpleCommand 简单指令 * @see CompositeCommand 复合指令 * - * @see buildCommandArgumentContext 指令参数环境, 即 [CommandArgumentParser] 的集合 + * @see buildCommandArgumentContext 指令参数环境, 即 [CommandValueArgumentParser] 的集合 */ -public interface CommandArgumentParser<out T : Any> { +public interface CommandValueArgumentParser<out T : Any> { /** * 解析一个字符串为 [T] 类型参数 * @@ -84,14 +84,14 @@ public interface CommandArgumentParser<out T : Any> { /** * 使用原 [this] 解析, 成功后使用 [mapper] 映射为另一个类型. */ -public fun <T : Any, R : Any> CommandArgumentParser<T>.map( - mapper: CommandArgumentParser<R>.(T) -> R -): CommandArgumentParser<R> = MappingCommandArgumentParser(this, mapper) +public fun <T : Any, R : Any> CommandValueArgumentParser<T>.map( + mapper: CommandValueArgumentParser<R>.(T) -> R, +): CommandValueArgumentParser<R> = MappingCommandValueArgumentParser(this, mapper) -private class MappingCommandArgumentParser<T : Any, R : Any>( - private val original: CommandArgumentParser<T>, - private val mapper: CommandArgumentParser<R>.(T) -> R -) : CommandArgumentParser<R> { +private class MappingCommandValueArgumentParser<T : Any, R : Any>( + private val original: CommandValueArgumentParser<T>, + private val mapper: CommandValueArgumentParser<R>.(T) -> R, +) : CommandValueArgumentParser<R> { override fun parse(raw: String, sender: CommandSender): R = mapper(original.parse(raw, sender)) override fun parse(raw: MessageContent, sender: CommandSender): R = mapper(original.parse(raw, sender)) } @@ -103,7 +103,7 @@ private class MappingCommandArgumentParser<T : Any, R : Any>( */ @JvmSynthetic @Throws(IllegalArgumentException::class) -public fun <T : Any> CommandArgumentParser<T>.parse(raw: Any, sender: CommandSender): T { +public fun <T : Any> CommandValueArgumentParser<T>.parse(raw: Any, sender: CommandSender): T { contract { returns() implies (raw is String || raw is SingleMessage) } @@ -123,7 +123,7 @@ public fun <T : Any> CommandArgumentParser<T>.parse(raw: Any, sender: CommandSen @Suppress("unused") @JvmSynthetic @Throws(CommandArgumentParserException::class) -public inline fun CommandArgumentParser<*>.illegalArgument(message: String, cause: Throwable? = null): Nothing { +public inline fun CommandValueArgumentParser<*>.illegalArgument(message: String, cause: Throwable? = null): Nothing { throw CommandArgumentParserException(message, cause) } @@ -134,9 +134,9 @@ public inline fun CommandArgumentParser<*>.illegalArgument(message: String, caus */ @Throws(CommandArgumentParserException::class) @JvmSynthetic -public inline fun CommandArgumentParser<*>.checkArgument( +public inline fun CommandValueArgumentParser<*>.checkArgument( condition: Boolean, - crossinline message: () -> String = { "Check failed." } + crossinline message: () -> String = { "Check failed." }, ) { contract { returns() implies condition diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/TypeVariant.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/TypeVariant.kt index b4cadf0ce..fd234b803 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/TypeVariant.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/descriptor/TypeVariant.kt @@ -16,6 +16,9 @@ import kotlin.reflect.typeOf @ExperimentalCommandDescriptors public interface TypeVariant<out OutType> { + /** + * The reified type of [OutType] + */ public val outType: KType public fun mapValue(valueParameter: MessageContent): OutType @@ -33,8 +36,8 @@ public interface TypeVariant<out OutType> { } @ExperimentalCommandDescriptors -public object StringTypeVariant : TypeVariant<RawCommandArgument> { +public object MessageContentTypeVariant : TypeVariant<MessageContent> { @OptIn(ExperimentalStdlibApi::class) override val outType: KType = typeOf<String>() - override fun mapValue(valueParameter: RawCommandArgument): RawCommandArgument = valueParameter + override fun mapValue(valueParameter: MessageContent): MessageContent = valueParameter } diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/parse/CommandValueArgument.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/parse/CommandValueArgument.kt index 0524ce1ea..3c473e21a 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/parse/CommandValueArgument.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/parse/CommandValueArgument.kt @@ -10,8 +10,8 @@ package net.mamoe.mirai.console.command.parse import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors +import net.mamoe.mirai.console.command.descriptor.MessageContentTypeVariant import net.mamoe.mirai.console.command.descriptor.NoValueArgumentMappingException -import net.mamoe.mirai.console.command.descriptor.StringTypeVariant import net.mamoe.mirai.console.command.descriptor.TypeVariant import net.mamoe.mirai.message.data.MessageContent import kotlin.reflect.full.isSubtypeOf @@ -23,20 +23,29 @@ import kotlin.reflect.typeOf */ public typealias RawCommandArgument = MessageContent +/** + * @see CommandValueArgument + */ @ExperimentalCommandDescriptors public interface CommandArgument +/** + * @see InvariantCommandValueArgument + */ @ExperimentalCommandDescriptors public interface CommandValueArgument : CommandArgument { public val value: RawCommandArgument public val typeVariants: List<TypeVariant<*>> } +/** + * The [CommandValueArgument] that doesn't vary in type (remaining [MessageContent]). + */ @ExperimentalCommandDescriptors public data class InvariantCommandValueArgument( public override val value: RawCommandArgument, ) : CommandValueArgument { - override val typeVariants: List<TypeVariant<*>> = listOf(StringTypeVariant) + override val typeVariants: List<TypeVariant<*>> = listOf(MessageContentTypeVariant) } @ExperimentalCommandDescriptors diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/command/CompositeCommand.CommandParam.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/command/CompositeCommand.CommandParam.kt index 72a34842c..16bae5667 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/command/CompositeCommand.CommandParam.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/command/CompositeCommand.CommandParam.kt @@ -12,7 +12,7 @@ package net.mamoe.mirai.console.internal.command import net.mamoe.mirai.console.command.CompositeCommand -import net.mamoe.mirai.console.command.descriptor.CommandArgumentParser +import net.mamoe.mirai.console.command.descriptor.CommandValueArgumentParser import kotlin.reflect.KClass import kotlin.reflect.KParameter @@ -37,12 +37,12 @@ internal data class CommandParameter<T : Any>( */ val name: String, /** - * 参数类型. 将从 [CompositeCommand.context] 中寻找 [CommandArgumentParser] 解析. + * 参数类型. 将从 [CompositeCommand.context] 中寻找 [CommandValueArgumentParser] 解析. */ val type: KClass<T>, // exact type val parameter: KParameter, // source parameter ) { - constructor(name: String, type: KClass<T>, parameter: KParameter, parser: CommandArgumentParser<T>) : this( + constructor(name: String, type: KClass<T>, parameter: KParameter, parser: CommandValueArgumentParser<T>) : this( name, type, parameter ) { this._overrideParser = parser @@ -50,14 +50,14 @@ internal data class CommandParameter<T : Any>( @Suppress("PropertyName") @JvmField - internal var _overrideParser: CommandArgumentParser<T>? = null + internal var _overrideParser: CommandValueArgumentParser<T>? = null /** - * 覆盖的 [CommandArgumentParser]. + * 覆盖的 [CommandValueArgumentParser]. * - * 如果非 `null`, 将不会从 [CommandArgumentContext] 寻找 [CommandArgumentParser] + * 如果非 `null`, 将不会从 [CommandArgumentContext] 寻找 [CommandValueArgumentParser] */ - val overrideParser: CommandArgumentParser<T>? get() = _overrideParser + val overrideParser: CommandValueArgumentParser<T>? get() = _overrideParser } 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 99a4349db..b7937225a 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,7 +22,7 @@ import net.mamoe.mirai.console.command.CommandManager.INSTANCE.register import net.mamoe.mirai.console.command.CommandManager.INSTANCE.registeredCommands 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.CommandArgumentParser +import net.mamoe.mirai.console.command.descriptor.CommandValueArgumentParser import net.mamoe.mirai.console.command.descriptor.buildCommandArgumentContext import net.mamoe.mirai.console.initTestEnvironment import net.mamoe.mirai.console.internal.command.CommandManagerImpl @@ -191,7 +191,7 @@ internal class TestCommand { ConsoleCommandOwner, "test22", overrideContext = buildCommandArgumentContext { - add(object : CommandArgumentParser<MyClass> { + add(object : CommandValueArgumentParser<MyClass> { override fun parse(raw: String, sender: CommandSender): MyClass { return MyClass(raw.toInt()) }