[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 { fun CommandParameter<*>.toErasedParameterInfo(index: Int): ErasedParameterInfo {
return ErasedParameterInfo(index, return ErasedParameterInfo(
index,
this.name, this.name,
this.type.withNullability(false), 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 -> val candidates = signatures.map { variant ->
@ -244,11 +246,21 @@ internal class CommandReflector(
name?.split(' ')?.mapIndexed { index, s -> createStringConstantParameterForName(index, s) } name?.split(' ')?.mapIndexed { index, s -> createStringConstantParameterForName(index, s) }
.orEmpty() .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 = val functionValueParameters =
function.valueParameters.associateBy { it.toUserDefinedCommandParameter() } valueParameters.associateBy { it.toUserDefinedCommandParameter() }
CommandSignatureFromKFunctionImpl( CommandSignatureFromKFunctionImpl(
receiverParameter = function.extensionReceiverParameter?.toCommandReceiverParameter(), receiverParameter = receiverParameter?.toCommandReceiverParameter(),
valueParameters = functionNameAsValueParameter + functionValueParameters.keys, valueParameters = functionNameAsValueParameter + functionValueParameters.keys,
originFunction = function originFunction = function
) { call -> ) { call ->
@ -272,7 +284,6 @@ internal class CommandReflector(
args[instanceParameter] = command args[instanceParameter] = command
} }
val receiverParameter = function.extensionReceiverParameter
if (receiverParameter != null) { if (receiverParameter != null) {
check(receiverParameter.type.classifierAsKClass().isInstance(call.caller)) { check(receiverParameter.type.classifierAsKClass().isInstance(call.caller)) {
"Bad command call resolved. " + "Bad command call resolved. " +

View File

@ -69,9 +69,11 @@ object TestEnumArgCommand : CompositeCommand(owner, "testenum") {
enum class TestEnum { enum class TestEnum {
V1, V2, V3 V1, V2, V3
} }
enum class TestCase { enum class TestCase {
A, a A, a
} }
enum class TestCamelCase { enum class TestCamelCase {
A, B, A_B 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 @Test
fun `composite sub command resolution conflict`() { fun `composite sub command resolution conflict`() {
runBlocking { runBlocking {