mirror of
https://github.com/mamoe/mirai.git
synced 2025-02-05 12:22:24 +08:00
Extract to separate files
This commit is contained in:
parent
7d589a0dec
commit
4eccb1a778
@ -2,11 +2,6 @@
|
||||
|
||||
package net.mamoe.mirai.console.command
|
||||
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.console.command.AbstractCommandParserContext.Node
|
||||
import net.mamoe.mirai.contact.Group
|
||||
import net.mamoe.mirai.contact.Member
|
||||
import kotlin.internal.LowPriorityInOverloadResolution
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
@ -34,70 +29,6 @@ class CommandDescriptor(
|
||||
val permission: CommandPermission = CommandPermission.Default
|
||||
)
|
||||
|
||||
/**
|
||||
* 指令形式参数.
|
||||
*/
|
||||
data class CommandParam<T : Any>(
|
||||
/**
|
||||
* 参数名, 为 `null` 时即为匿名参数.
|
||||
* 参数名允许重复 (尽管并不建议这样做).
|
||||
* 参数名仅提供给 [CommandArgParser] 以发送更好的错误信息.
|
||||
*/
|
||||
val name: String?,
|
||||
/**
|
||||
* 参数类型. 将从 [CommandDescriptor.context] 中寻找 [CommandArgParser] 解析.
|
||||
*/
|
||||
val type: KClass<T> // exact type
|
||||
) {
|
||||
constructor(name: String?, type: KClass<T>, parser: CommandArgParser<T>) : this(name, type) {
|
||||
this.parser = parser
|
||||
}
|
||||
|
||||
@JvmField
|
||||
internal var parser: CommandArgParser<T>? = null
|
||||
|
||||
|
||||
/**
|
||||
* 覆盖的 [CommandArgParser].
|
||||
*
|
||||
* 如果非 `null`, 将不会从 [CommandParserContext] 寻找 [CommandArgParser]
|
||||
*/
|
||||
val overrideParser: CommandArgParser<T>? get() = parser
|
||||
}
|
||||
|
||||
private fun preview() {
|
||||
class MyArg(val string: String)
|
||||
|
||||
CommandDescriptor("test") {
|
||||
permission(CommandPermission.GroupOwner or CommandPermission.Console)
|
||||
|
||||
permission {
|
||||
println("正在检查 $this 的权限")
|
||||
true
|
||||
}
|
||||
|
||||
param<String>("test")
|
||||
param<Boolean>("test")
|
||||
param<String>("test")
|
||||
|
||||
param("p2", String::class)
|
||||
param("p2", String::class)
|
||||
|
||||
params {
|
||||
"p2" typed String::class
|
||||
"testPram" typed CharSequence::class using StringArgParser
|
||||
"p3" using StringArgParser
|
||||
}
|
||||
|
||||
context {
|
||||
MyArg::class with {
|
||||
println("正在解析 $it")
|
||||
MyArg(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建一个 [CommandDescriptor]
|
||||
*/
|
||||
@ -146,13 +77,27 @@ class CommandDescriptorBuilder(
|
||||
this.params.addAll(params)
|
||||
}
|
||||
|
||||
fun param(name: String?, type: KClass<*>): CommandDescriptorBuilder = apply {
|
||||
this.params.add(CommandParam(name, type))
|
||||
@JvmSynthetic
|
||||
fun <T : Any> param(
|
||||
name: String?,
|
||||
type: KClass<T>,
|
||||
overrideParser: CommandArgParser<T>? = null
|
||||
): CommandDescriptorBuilder = apply {
|
||||
this.params.add(CommandParam(name, type).apply { this.parser = overrideParser })
|
||||
}
|
||||
|
||||
inline fun <reified T : Any> param(name: String? = null): CommandDescriptorBuilder = apply {
|
||||
this.params.add(CommandParam(name, T::class))
|
||||
}
|
||||
fun <T : Any> param(
|
||||
name: String?,
|
||||
type: Class<T>,
|
||||
overrideParser: CommandArgParser<T>? = null
|
||||
): CommandDescriptorBuilder =
|
||||
param(name, type, overrideParser)
|
||||
|
||||
inline fun <reified T : Any> param(
|
||||
name: String? = null,
|
||||
overrideParser: CommandArgParser<T>? = null
|
||||
): CommandDescriptorBuilder =
|
||||
param(name, T::class, overrideParser)
|
||||
|
||||
@JvmSynthetic
|
||||
fun param(vararg pairs: Pair<String?, KClass<*>>): CommandDescriptorBuilder = apply {
|
||||
@ -178,7 +123,8 @@ class CommandDescriptorBuilder(
|
||||
fun build(): CommandDescriptor = CommandDescriptor(fullName, context, params, permission)
|
||||
}
|
||||
|
||||
inline class ParamBlock(@PublishedApi internal val list: MutableList<CommandParam<*>>) {
|
||||
@Suppress("NON_PUBLIC_PRIMARY_CONSTRUCTOR_OF_INLINE_CLASS")
|
||||
inline class ParamBlock internal constructor(@PublishedApi internal val list: MutableList<CommandParam<*>>) {
|
||||
/** 添加一个名称为 [this], 类型为 [klass] 的参数. 返回添加成功的对象 */
|
||||
infix fun <T : Any> String.typed(klass: KClass<T>): CommandParam<T> =
|
||||
CommandParam(this, klass).also { list.add(it) }
|
||||
@ -190,114 +136,4 @@ inline class ParamBlock(@PublishedApi internal val list: MutableList<CommandPara
|
||||
/** 覆盖 [CommandArgParser] */
|
||||
inline infix fun <reified T : Any> String.using(parser: CommandArgParser<T>): CommandParam<T> =
|
||||
this typed T::class using parser
|
||||
}
|
||||
|
||||
/**
|
||||
* [KClass] 到 [CommandArgParser] 的匹配
|
||||
*/
|
||||
interface CommandParserContext {
|
||||
operator fun <T : Any> get(klass: KClass<T>): CommandArgParser<T>?
|
||||
|
||||
/**
|
||||
* 内建的默认 [CommandArgParser]
|
||||
*/
|
||||
object Builtins : CommandParserContext by (CommandParserContext {
|
||||
Int::class with IntArgParser
|
||||
Byte::class with ByteArgParser
|
||||
Short::class with ShortArgParser
|
||||
Boolean::class with BooleanArgParser
|
||||
String::class with StringArgParser
|
||||
Long::class with LongArgParser
|
||||
Double::class with DoubleArgParser
|
||||
Float::class with FloatArgParser
|
||||
|
||||
Member::class with ExistMemberArgParser
|
||||
Group::class with ExistGroupArgParser
|
||||
Bot::class with ExistBotArgParser
|
||||
})
|
||||
}
|
||||
|
||||
fun <T : Any> CommandParserContext.parserFor(param: CommandParam<T>): CommandArgParser<T>? = this[param.type]
|
||||
|
||||
/**
|
||||
* 合并两个 [CommandParserContext], [replacer] 将会替换 [this] 中重复的 parser.
|
||||
*/
|
||||
operator fun CommandParserContext.plus(replacer: CommandParserContext): CommandParserContext {
|
||||
return object : CommandParserContext {
|
||||
override fun <T : Any> get(klass: KClass<T>): CommandArgParser<T>? = replacer[klass] ?: this@plus[klass]
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
open class AbstractCommandParserContext(val list: List<Node<*>>) : CommandParserContext {
|
||||
class Node<T : Any>(
|
||||
val klass: KClass<T>,
|
||||
val parser: CommandArgParser<T>
|
||||
)
|
||||
|
||||
override fun <T : Any> get(klass: KClass<T>): CommandArgParser<T>? =
|
||||
this.list.firstOrNull { it.klass == klass }?.parser as CommandArgParser<T>?
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建一个 [CommandParserContext].
|
||||
*
|
||||
* ```
|
||||
* CommandParserContext {
|
||||
* Int::class with IntArgParser
|
||||
* Member::class with ExistMemberArgParser
|
||||
* Group::class with { s: String, sender: CommandSender ->
|
||||
* Bot.getInstance(s.toLong()).getGroup(s.toLong())
|
||||
* }
|
||||
* Bot::class with { s: String ->
|
||||
* Bot.getInstance(s.toLong())
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
@Suppress("FunctionName")
|
||||
@JvmSynthetic
|
||||
inline fun CommandParserContext(block: CommandParserContextBuilder.() -> Unit): CommandParserContext {
|
||||
return AbstractCommandParserContext(
|
||||
CommandParserContextBuilder().apply(block).distinctByReversed { it.klass })
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CommandParserContext
|
||||
*/
|
||||
class CommandParserContextBuilder : MutableList<Node<*>> by mutableListOf() {
|
||||
@JvmName("add")
|
||||
inline infix fun <T : Any> KClass<T>.with(parser: CommandArgParser<T>): Node<*> =
|
||||
Node(this, parser)
|
||||
|
||||
/**
|
||||
* 添加一个指令解析器
|
||||
*/
|
||||
@JvmSynthetic
|
||||
@LowPriorityInOverloadResolution
|
||||
inline infix fun <T : Any> KClass<T>.with(
|
||||
crossinline parser: CommandArgParser<T>.(s: String, sender: CommandSender) -> T
|
||||
): Node<*> = Node(this, CommandArgParser(parser))
|
||||
|
||||
/**
|
||||
* 添加一个指令解析器
|
||||
*/
|
||||
@JvmSynthetic
|
||||
inline infix fun <T : Any> KClass<T>.with(
|
||||
crossinline parser: CommandArgParser<T>.(s: String) -> T
|
||||
): Node<*> = Node(this, CommandArgParser { s: String, _: CommandSender -> parser(s) })
|
||||
}
|
||||
|
||||
|
||||
@PublishedApi
|
||||
internal inline fun <T, K> Iterable<T>.distinctByReversed(selector: (T) -> K): List<T> {
|
||||
val set = HashSet<K>()
|
||||
val list = ArrayList<T>()
|
||||
for (i in list.indices.reversed()) {
|
||||
val element = list[i]
|
||||
if (set.add(element.let(selector))) {
|
||||
list.add(element)
|
||||
}
|
||||
}
|
||||
return list
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
@file:Suppress("unused")
|
||||
|
||||
package net.mamoe.mirai.console.command
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* 指令形式参数.
|
||||
*/
|
||||
data class CommandParam<T : Any>(
|
||||
/**
|
||||
* 参数名, 为 `null` 时即为匿名参数.
|
||||
* 参数名允许重复 (尽管并不建议这样做).
|
||||
* 参数名仅提供给 [CommandArgParser] 以发送更好的错误信息.
|
||||
*/
|
||||
val name: String?,
|
||||
/**
|
||||
* 参数类型. 将从 [CommandDescriptor.context] 中寻找 [CommandArgParser] 解析.
|
||||
*/
|
||||
val type: KClass<T> // exact type
|
||||
) {
|
||||
constructor(name: String?, type: KClass<T>, parser: CommandArgParser<T>) : this(name, type) {
|
||||
this.parser = parser
|
||||
}
|
||||
|
||||
@JvmField
|
||||
internal var parser: CommandArgParser<T>? = null
|
||||
|
||||
|
||||
/**
|
||||
* 覆盖的 [CommandArgParser].
|
||||
*
|
||||
* 如果非 `null`, 将不会从 [CommandParserContext] 寻找 [CommandArgParser]
|
||||
*/
|
||||
val overrideParser: CommandArgParser<T>? get() = parser
|
||||
}
|
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright 2020 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
@file:Suppress("NOTHING_TO_INLINE", "INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "unused", "MemberVisibilityCanBePrivate")
|
||||
|
||||
package net.mamoe.mirai.console.command
|
||||
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.console.command.AbstractCommandParserContext.Node
|
||||
import net.mamoe.mirai.contact.Group
|
||||
import net.mamoe.mirai.contact.Member
|
||||
import kotlin.internal.LowPriorityInOverloadResolution
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
|
||||
/**
|
||||
* [KClass] 到 [CommandArgParser] 的匹配
|
||||
*/
|
||||
interface CommandParserContext {
|
||||
operator fun <T : Any> get(klass: KClass<T>): CommandArgParser<T>?
|
||||
|
||||
/**
|
||||
* 内建的默认 [CommandArgParser]
|
||||
*/
|
||||
object Builtins : CommandParserContext by (CommandParserContext {
|
||||
Int::class with IntArgParser
|
||||
Byte::class with ByteArgParser
|
||||
Short::class with ShortArgParser
|
||||
Boolean::class with BooleanArgParser
|
||||
String::class with StringArgParser
|
||||
Long::class with LongArgParser
|
||||
Double::class with DoubleArgParser
|
||||
Float::class with FloatArgParser
|
||||
|
||||
Member::class with ExistMemberArgParser
|
||||
Group::class with ExistGroupArgParser
|
||||
Bot::class with ExistBotArgParser
|
||||
})
|
||||
}
|
||||
|
||||
fun <T : Any> CommandParserContext.parserFor(param: CommandParam<T>): CommandArgParser<T>? = this[param.type]
|
||||
|
||||
/**
|
||||
* 合并两个 [CommandParserContext], [replacer] 将会替换 [this] 中重复的 parser.
|
||||
*/
|
||||
operator fun CommandParserContext.plus(replacer: CommandParserContext): CommandParserContext {
|
||||
return object : CommandParserContext {
|
||||
override fun <T : Any> get(klass: KClass<T>): CommandArgParser<T>? = replacer[klass] ?: this@plus[klass]
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
open class AbstractCommandParserContext(val list: List<Node<*>>) : CommandParserContext {
|
||||
class Node<T : Any>(
|
||||
val klass: KClass<T>,
|
||||
val parser: CommandArgParser<T>
|
||||
)
|
||||
|
||||
override fun <T : Any> get(klass: KClass<T>): CommandArgParser<T>? =
|
||||
this.list.firstOrNull { it.klass == klass }?.parser as CommandArgParser<T>?
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建一个 [CommandParserContext].
|
||||
*
|
||||
* ```
|
||||
* CommandParserContext {
|
||||
* Int::class with IntArgParser
|
||||
* Member::class with ExistMemberArgParser
|
||||
* Group::class with { s: String, sender: CommandSender ->
|
||||
* Bot.getInstance(s.toLong()).getGroup(s.toLong())
|
||||
* }
|
||||
* Bot::class with { s: String ->
|
||||
* Bot.getInstance(s.toLong())
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
@Suppress("FunctionName")
|
||||
@JvmSynthetic
|
||||
inline fun CommandParserContext(block: CommandParserContextBuilder.() -> Unit): CommandParserContext {
|
||||
return AbstractCommandParserContext(
|
||||
CommandParserContextBuilder().apply(block).distinctByReversed { it.klass })
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CommandParserContext
|
||||
*/
|
||||
class CommandParserContextBuilder : MutableList<Node<*>> by mutableListOf() {
|
||||
@JvmName("add")
|
||||
inline infix fun <T : Any> KClass<T>.with(parser: CommandArgParser<T>): Node<*> =
|
||||
Node(this, parser)
|
||||
|
||||
/**
|
||||
* 添加一个指令解析器
|
||||
*/
|
||||
@JvmSynthetic
|
||||
@LowPriorityInOverloadResolution
|
||||
inline infix fun <T : Any> KClass<T>.with(
|
||||
crossinline parser: CommandArgParser<T>.(s: String, sender: CommandSender) -> T
|
||||
): Node<*> = Node(this, CommandArgParser(parser))
|
||||
|
||||
/**
|
||||
* 添加一个指令解析器
|
||||
*/
|
||||
@JvmSynthetic
|
||||
inline infix fun <T : Any> KClass<T>.with(
|
||||
crossinline parser: CommandArgParser<T>.(s: String) -> T
|
||||
): Node<*> = Node(this, CommandArgParser { s: String, _: CommandSender -> parser(s) })
|
||||
}
|
||||
|
||||
|
||||
@PublishedApi
|
||||
internal inline fun <T, K> Iterable<T>.distinctByReversed(selector: (T) -> K): List<T> {
|
||||
val set = HashSet<K>()
|
||||
val list = ArrayList<T>()
|
||||
for (i in list.indices.reversed()) {
|
||||
val element = list[i]
|
||||
if (set.add(element.let(selector))) {
|
||||
list.add(element)
|
||||
}
|
||||
}
|
||||
return list
|
||||
}
|
Loading…
Reference in New Issue
Block a user