Update docs

This commit is contained in:
Him188 2020-11-17 10:47:50 +08:00
parent 21428094a8
commit 0a55743567
5 changed files with 86 additions and 14 deletions

View File

@ -14,6 +14,7 @@ import net.mamoe.mirai.console.command.descriptor.AbstractCommandValueParameter.
import net.mamoe.mirai.console.command.descriptor.AbstractCommandValueParameter.UserDefinedType.Companion.createRequired import net.mamoe.mirai.console.command.descriptor.AbstractCommandValueParameter.UserDefinedType.Companion.createRequired
import net.mamoe.mirai.console.command.descriptor.ArgumentAcceptance.Companion.isAcceptable import net.mamoe.mirai.console.command.descriptor.ArgumentAcceptance.Companion.isAcceptable
import net.mamoe.mirai.console.command.parse.CommandValueArgument import net.mamoe.mirai.console.command.parse.CommandValueArgument
import net.mamoe.mirai.console.command.resolve.ResolvedCommandValueArgument
import net.mamoe.mirai.console.internal.data.classifierAsKClass import net.mamoe.mirai.console.internal.data.classifierAsKClass
import net.mamoe.mirai.console.internal.data.classifierAsKClassOrNull import net.mamoe.mirai.console.internal.data.classifierAsKClassOrNull
import net.mamoe.mirai.console.internal.data.typeOf0 import net.mamoe.mirai.console.internal.data.typeOf0
@ -52,13 +53,31 @@ public abstract class AbstractCommandParameter<T> : CommandParameter<T> {
} }
/** /**
* Inherited instances must be [AbstractCommandValueParameter] * Inherited instances must be [AbstractCommandValueParameter].
*
* ### Implementation details
*
* [CommandValueParameter] should:
* - implement [equals], [hashCode] since used in [ResolvedCommandValueArgument].
* - implement [toString] to produce user-friendly textual representation of this parameter with type info.
*
*/ */
@ExperimentalCommandDescriptors @ExperimentalCommandDescriptors
public interface CommandValueParameter<T : Any?> : CommandParameter<T> { public interface CommandValueParameter<T : Any?> : CommandParameter<T> {
public val isVararg: Boolean public val isVararg: Boolean
/**
* Checks whether this [CommandValueParameter] accepts [argument].
*
* An [argument] can be accepted if:
* - [CommandValueArgument.type] is subtype of, or equals to [CommandValueParameter.type] (nullability considered), or
* - [CommandValueArgument.typeVariants] produces
*
* @return `true` if [argument] may be accepted through any approach mentioned above.
*
* @see accepting
*/
public fun accepts(argument: CommandValueArgument, commandArgumentContext: CommandArgumentContext?): Boolean = public fun accepts(argument: CommandValueArgument, commandArgumentContext: CommandArgumentContext?): Boolean =
accepting(argument, commandArgumentContext).isAcceptable accepting(argument, commandArgumentContext).isAcceptable

View File

@ -9,8 +9,6 @@
package net.mamoe.mirai.console.command.descriptor package net.mamoe.mirai.console.command.descriptor
import net.mamoe.mirai.console.command.parse.CommandCall
import net.mamoe.mirai.console.command.parse.CommandCallParser
import net.mamoe.mirai.console.command.parse.CommandValueArgument import net.mamoe.mirai.console.command.parse.CommandValueArgument
import net.mamoe.mirai.console.internal.data.castOrNull import net.mamoe.mirai.console.internal.data.castOrNull
import net.mamoe.mirai.console.internal.data.kClassQualifiedName import net.mamoe.mirai.console.internal.data.kClassQualifiedName
@ -19,9 +17,18 @@ import kotlin.reflect.KType
import kotlin.reflect.typeOf import kotlin.reflect.typeOf
/** /**
* Implicit type variant specified by [CommandCallParser]. * Intrinsic variant of an [CommandValueArgument].
* *
* [TypeVariant] is not necessary for all [CommandCall]s. * The *intrinsic* reveals the independent conversion property of this type.
* Conversion with [TypeVariant] is out of any contextual resource,
* except the [output type][TypeVariant.outType] declared by the [TypeVariant] itself.
*
*
* [TypeVariant] is not necessary for all [CommandValueArgument]s.
*
* @param OutType the type this [TypeVariant] can map a argument [Message] to .
*
* @see CommandValueArgument.typeVariants
*/ */
@ExperimentalCommandDescriptors @ExperimentalCommandDescriptors
public interface TypeVariant<out OutType> { public interface TypeVariant<out OutType> {
@ -31,17 +38,22 @@ public interface TypeVariant<out OutType> {
public val outType: KType public val outType: KType
/** /**
* Maps an [valueArgument] to [outType]
*
* @see CommandValueArgument.value * @see CommandValueArgument.value
*/ */
public fun mapValue(valueParameter: Message): OutType public fun mapValue(valueArgument: Message): OutType
public companion object { public companion object {
/**
* Creates a [TypeVariant] with reified [OutType].
*/
@OptIn(ExperimentalStdlibApi::class) @OptIn(ExperimentalStdlibApi::class)
@JvmSynthetic @JvmSynthetic
public inline operator fun <reified OutType> invoke(crossinline block: (valueParameter: Message) -> OutType): TypeVariant<OutType> { public inline operator fun <reified OutType> invoke(crossinline block: (valueParameter: Message) -> OutType): TypeVariant<OutType> {
return object : TypeVariant<OutType> { return object : TypeVariant<OutType> {
override val outType: KType = typeOf<OutType>() override val outType: KType = typeOf<OutType>()
override fun mapValue(valueParameter: Message): OutType = block(valueParameter) override fun mapValue(valueArgument: Message): OutType = block(valueArgument)
} }
} }
} }
@ -51,20 +63,20 @@ public interface TypeVariant<out OutType> {
public object MessageContentTypeVariant : TypeVariant<MessageContent> { public object MessageContentTypeVariant : TypeVariant<MessageContent> {
@OptIn(ExperimentalStdlibApi::class) @OptIn(ExperimentalStdlibApi::class)
override val outType: KType = typeOf<MessageContent>() override val outType: KType = typeOf<MessageContent>()
override fun mapValue(valueParameter: Message): MessageContent = override fun mapValue(valueArgument: Message): MessageContent =
valueParameter.castOrNull<MessageContent>() ?: error("Accepts MessageContent only but given ${valueParameter.kClassQualifiedName}") valueArgument.castOrNull<MessageContent>() ?: error("Accepts MessageContent only but given ${valueArgument.kClassQualifiedName}")
} }
@ExperimentalCommandDescriptors @ExperimentalCommandDescriptors
public object MessageChainTypeVariant : TypeVariant<MessageChain> { public object MessageChainTypeVariant : TypeVariant<MessageChain> {
@OptIn(ExperimentalStdlibApi::class) @OptIn(ExperimentalStdlibApi::class)
override val outType: KType = typeOf<MessageChain>() override val outType: KType = typeOf<MessageChain>()
override fun mapValue(valueParameter: Message): MessageChain = valueParameter.asMessageChain() override fun mapValue(valueArgument: Message): MessageChain = valueArgument.asMessageChain()
} }
@ExperimentalCommandDescriptors @ExperimentalCommandDescriptors
public object ContentStringTypeVariant : TypeVariant<String> { public object ContentStringTypeVariant : TypeVariant<String> {
@OptIn(ExperimentalStdlibApi::class) @OptIn(ExperimentalStdlibApi::class)
override val outType: KType = typeOf<String>() override val outType: KType = typeOf<String>()
override fun mapValue(valueParameter: Message): String = valueParameter.content override fun mapValue(valueArgument: Message): String = valueArgument.content
} }

View File

@ -12,29 +12,45 @@
package net.mamoe.mirai.console.command.parse package net.mamoe.mirai.console.command.parse
import net.mamoe.mirai.console.command.Command 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.CommandSender
import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
import net.mamoe.mirai.console.command.resolve.CommandCallResolver import net.mamoe.mirai.console.command.resolve.CommandCallResolver
import net.mamoe.mirai.console.command.resolve.ResolvedCommandCall
import net.mamoe.mirai.message.data.MessageChain
/** /**
* Unresolved [CommandCall]. * Unresolved [CommandCall].
* *
* ### Implementation details
* [CommandCall] should be _immutable_,
* meaning all of its properties must be *pure* and should be implemented as an immutable property, or delegated by a lazy initializer.
*
* @see CommandCallParser * @see CommandCallParser
* @see CommandCallResolver * @see CommandCallResolver
*
* @see ResolvedCommandCall
*/ */
@ExperimentalCommandDescriptors @ExperimentalCommandDescriptors
public interface CommandCall { public interface CommandCall {
/**
* The [CommandSender] responsible to this call.
*/
public val caller: CommandSender public val caller: CommandSender
/** /**
* One of callee [Command]'s [Command.allNames] * One of callee [Command]'s [Command.allNames].
*
* Generally [CommandCallResolver] use [calleeName] to find target [Command] registered in [CommandManager]
*/ */
public val calleeName: String public val calleeName: String
/** /**
* Explicit value arguments * Explicit value arguments parsed from raw [MessageChain] or implicit ones deduced by the [CommandCallResolver].
*/ */
public val valueArguments: List<CommandValueArgument> public val valueArguments: List<CommandValueArgument>
// maybe add contextual arguments, i.e. from MessageMetadata
} }
@ExperimentalCommandDescriptors @ExperimentalCommandDescriptors

View File

@ -42,6 +42,12 @@ public interface CommandValueArgument : CommandArgument {
* [MessageChain] is vararg * [MessageChain] is vararg
*/ */
public val value: Message public val value: Message
/**
* Intrinsic variants of this argument.
*
* @see TypeVariant
*/
public val typeVariants: List<TypeVariant<*>> public val typeVariants: List<TypeVariant<*>>
} }

View File

@ -24,10 +24,17 @@ import net.mamoe.mirai.console.util.cast
/** /**
* The resolved [CommandCall]. * The resolved [CommandCall].
* *
* ### Implementation details
* [ResolvedCommandCall] should be _immutable_,
* meaning all of its properties must be *pure* and should be implemented as an immutable property, or delegated by a lazy initializer.
*
* @see ResolvedCommandCallImpl * @see ResolvedCommandCallImpl
*/ */
@ExperimentalCommandDescriptors @ExperimentalCommandDescriptors
public interface ResolvedCommandCall { public interface ResolvedCommandCall {
/**
* The [CommandSender] responsible to this call.
*/
public val caller: CommandSender public val caller: CommandSender
/** /**
@ -48,7 +55,7 @@ public interface ResolvedCommandCall {
/** /**
* Resolved value arguments arranged mapping the [CommandSignature.valueParameters] by index. * Resolved value arguments arranged mapping the [CommandSignature.valueParameters] by index.
* *
* **Implementation details**: Lazy calculation. * **Default implementation details**: Lazy calculation.
*/ */
@ConsoleExperimentalApi @ConsoleExperimentalApi
public val resolvedValueArguments: List<ResolvedCommandValueArgument<*>> public val resolvedValueArguments: List<ResolvedCommandValueArgument<*>>
@ -56,18 +63,30 @@ public interface ResolvedCommandCall {
public companion object public companion object
} }
/**
* Resolved [CommandValueParameter] for [ResolvedCommandCall.resolvedValueArguments]
*/
@ExperimentalCommandDescriptors @ExperimentalCommandDescriptors
public data class ResolvedCommandValueArgument<T>( public data class ResolvedCommandValueArgument<T>(
val parameter: CommandValueParameter<T>, val parameter: CommandValueParameter<T>,
/**
* Argument value expected by the [parameter]
*/
val value: T, val value: T,
) )
// Don't move into companion, compilation error // Don't move into companion, compilation error
/**
* Invoke this resolved call.
*/
@ExperimentalCommandDescriptors @ExperimentalCommandDescriptors
public suspend inline fun ResolvedCommandCall.call() { public suspend inline fun ResolvedCommandCall.call() {
return this@call.calleeSignature.call(this@call) return this@call.calleeSignature.call(this@call)
} }
/**
* Default implementation.
*/
@ExperimentalCommandDescriptors @ExperimentalCommandDescriptors
public class ResolvedCommandCallImpl( public class ResolvedCommandCallImpl(
override val caller: CommandSender, override val caller: CommandSender,