[Command] Support detect receiver parameter with first parameter; fix #295

This commit is contained in:
Karlatemp 2021-02-17 15:15:05 +08:00
parent 78e8203abd
commit bc009263b5
No known key found for this signature in database
GPG Key ID: 21FBDDF664FF06F8
2 changed files with 48 additions and 5 deletions

View File

@ -203,10 +203,12 @@ internal class CommandReflector(
)
fun CommandParameter<*>.toErasedParameterInfo(index: Int): ErasedParameterInfo {
return ErasedParameterInfo(index,
return ErasedParameterInfo(
index,
this.name,
this.type.withNullability(false),
if (this is AbstractCommandValueParameter.StringConstant) this.expectingValue else null)
if (this is AbstractCommandValueParameter.StringConstant) this.expectingValue else null
)
}
val candidates = signatures.map { variant ->
@ -244,11 +246,21 @@ internal class CommandReflector(
name?.split(' ')?.mapIndexed { index, s -> createStringConstantParameterForName(index, s) }
.orEmpty()
val valueParameters = function.valueParameters.toMutableList()
var receiverParameter = function.extensionReceiverParameter
if (receiverParameter == null && valueParameters.isNotEmpty()) {
val valueFirstParameter = valueParameters[0]
if (valueFirstParameter.type.classifierAsKClassOrNull()?.isSubclassOf(CommandSender::class) == true) {
receiverParameter = valueFirstParameter
valueParameters.removeAt(0)
}
}
val functionValueParameters =
function.valueParameters.associateBy { it.toUserDefinedCommandParameter() }
valueParameters.associateBy { it.toUserDefinedCommandParameter() }
CommandSignatureFromKFunctionImpl(
receiverParameter = function.extensionReceiverParameter?.toCommandReceiverParameter(),
receiverParameter = receiverParameter?.toCommandReceiverParameter(),
valueParameters = functionNameAsValueParameter + functionValueParameters.keys,
originFunction = function
) { call ->
@ -272,7 +284,6 @@ internal class CommandReflector(
args[instanceParameter] = command
}
val receiverParameter = function.extensionReceiverParameter
if (receiverParameter != null) {
check(receiverParameter.type.classifierAsKClass().isInstance(call.caller)) {
"Bad command call resolved. " +

View File

@ -69,9 +69,11 @@ object TestEnumArgCommand : CompositeCommand(owner, "testenum") {
enum class TestEnum {
V1, V2, V3
}
enum class TestCase {
A, a
}
enum class TestCamelCase {
A, B, A_B
}
@ -295,6 +297,36 @@ internal class TestCommand {
}
}
@Test
fun `test first param command sender`() = runBlocking<Unit> {
object : CompositeCommand(owner, "cmd") {
@SubCommand
fun handle(sender: CommandSender, arg: String) {
Testing.ok(arg)
}
}.withRegistration {
assertEquals("test", withTesting { assertSuccess(execute(sender, "handle test")) })
}
object : SimpleCommand(owner, "cmd") {
@Handler
fun handle(sender: CommandSender, arg: String) {
Testing.ok(arg)
}
}.withRegistration {
assertEquals("hello", withTesting { assertSuccess(execute(sender, "hello")) })
}
object : SimpleCommand(owner, "cmd") {
@Handler
fun handle(arg: String, sender: CommandSender) {
Testing.ok(arg)
}
}.withRegistration {
assertFailure(execute(sender, "hello"))
}
}
@Test
fun `composite sub command resolution conflict`() {
runBlocking {