Fix vararg argument mapping for generic args convertor
This commit is contained in:
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.script
|
package org.jetbrains.kotlin.script
|
||||||
|
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
|
||||||
import kotlin.reflect.*
|
import kotlin.reflect.*
|
||||||
import kotlin.reflect.full.isSubclassOf
|
import kotlin.reflect.full.isSubclassOf
|
||||||
import kotlin.reflect.jvm.jvmErasure
|
import kotlin.reflect.jvm.jvmErasure
|
||||||
@@ -160,18 +159,6 @@ private class StringArgsConverter : ArgsConverter<String> {
|
|||||||
|
|
||||||
override fun tryConvertVararg(parameter: KParameter, firstArg: NamedArgument<String>, restArgsIt: Iterator<NamedArgument<String>>): ArgsConverter.Result {
|
override fun tryConvertVararg(parameter: KParameter, firstArg: NamedArgument<String>, restArgsIt: Iterator<NamedArgument<String>>): ArgsConverter.Result {
|
||||||
|
|
||||||
fun convertAnyArray(classifier: KClassifier?, args: Sequence<String?>): Any? =
|
|
||||||
when (classifier) {
|
|
||||||
String::class -> args.toList().toTypedArray()
|
|
||||||
is KClass<*> -> classifier.constructors.firstNotNullResult { ctor ->
|
|
||||||
try {
|
|
||||||
args.map { ctor.call(it) }.toList().toTypedArray()
|
|
||||||
}
|
|
||||||
catch (e: Exception) { null }
|
|
||||||
}
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
|
|
||||||
fun convertPrimitivesArray(type: KType, args: Sequence<String?>): Any? =
|
fun convertPrimitivesArray(type: KType, args: Sequence<String?>): Any? =
|
||||||
when (type.classifier) {
|
when (type.classifier) {
|
||||||
IntArray::class -> args.map { it?.toIntOrNull() }
|
IntArray::class -> args.map { it?.toIntOrNull() }
|
||||||
@@ -228,9 +215,42 @@ private class AnyArgsConverter : ArgsConverter<Any> {
|
|||||||
?: ArgsConverter.Result.Failure
|
?: ArgsConverter.Result.Failure
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun tryConvertVararg(parameter: KParameter, firstArg: NamedArgument<Any>, restArgsIt: Iterator<NamedArgument<Any>>): ArgsConverter.Result =
|
override fun tryConvertVararg(
|
||||||
ArgsConverter.Result.Failure
|
parameter: KParameter, firstArg: NamedArgument<Any>, restArgsIt: Iterator<NamedArgument<Any>>
|
||||||
|
): ArgsConverter.Result {
|
||||||
|
|
||||||
|
val parameterType = parameter.type
|
||||||
|
if (parameterType.jvmErasure.java.isArray) {
|
||||||
|
val argsSequence = sequenceOf(firstArg.value) + restArgsIt.asSequence().map { it.value }
|
||||||
|
val arrayElementType = parameterType.arguments.firstOrNull()?.type
|
||||||
|
val arrayArgCandidate = convertAnyArray(arrayElementType?.classifier, argsSequence)
|
||||||
|
if (arrayArgCandidate != null)
|
||||||
|
return ArgsConverter.Result.Success(arrayArgCandidate)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ArgsConverter.Result.Failure
|
||||||
|
}
|
||||||
|
|
||||||
override fun tryConvertTail(parameter: KParameter, firstArg: NamedArgument<Any>, restArgsIt: Iterator<NamedArgument<Any>>): ArgsConverter.Result =
|
override fun tryConvertTail(parameter: KParameter, firstArg: NamedArgument<Any>, restArgsIt: Iterator<NamedArgument<Any>>): ArgsConverter.Result =
|
||||||
tryConvertSingle(parameter, firstArg)
|
tryConvertSingle(parameter, firstArg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
private inline fun <reified T> convertAnyArray(classifier: KClassifier?, args: Sequence<T?>): Any? =
|
||||||
|
if (classifier == T::class) args.toList().toTypedArray() // simple case
|
||||||
|
else convertAnyArrayImpl<T>(classifier, args)
|
||||||
|
|
||||||
|
private fun <T> convertAnyArrayImpl(classifier: KClassifier?, args: Sequence<T?>): Any? {
|
||||||
|
val elementClass = (classifier as? KClass<*>) ?: return null
|
||||||
|
|
||||||
|
val argsList = args.toList()
|
||||||
|
val result = java.lang.reflect.Array.newInstance(elementClass.java, argsList.size)
|
||||||
|
argsList.forEachIndexed { idx, arg ->
|
||||||
|
try {
|
||||||
|
java.lang.reflect.Array.set(result, idx, arg)
|
||||||
|
} catch (e: IllegalArgumentException) {
|
||||||
|
return@convertAnyArrayImpl null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|||||||
@@ -74,6 +74,9 @@ class ArgsToParamsMatchingTest {
|
|||||||
assertParamMapsEquals(tryCreateCallableMappingFromNamedArgs(::notNullNumber, listOf(null to 42)),
|
assertParamMapsEquals(tryCreateCallableMappingFromNamedArgs(::notNullNumber, listOf(null to 42)),
|
||||||
"n" to 42)
|
"n" to 42)
|
||||||
Assert.assertNull(tryCreateCallableMappingFromNamedArgs(::notNullNumber, listOf(null to "42")))
|
Assert.assertNull(tryCreateCallableMappingFromNamedArgs(::notNullNumber, listOf(null to "42")))
|
||||||
|
|
||||||
|
assertParamMapsEquals(tryCreateCallableMappingFromNamedArgs(::varargStrings, listOf("a", "b", "c").map { null to it }),
|
||||||
|
"s" to arrayOf("a", "b", "c"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user