Fix annotation construction with array literals

Turns out the issue happens to be that ArrayValue uses a list of values which needs to be translated to an array of the percise type before it is used by callBy

This also addresses handling of arguments after a vararg in an annotation
This commit is contained in:
Mathias Quintero
2020-06-10 16:26:42 +02:00
committed by Ilya Chernikov
parent 8cb4f59114
commit f0bc52222d
9 changed files with 237 additions and 19 deletions
@@ -14,10 +14,10 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.BindingTraceContext
import org.jetbrains.kotlin.resolve.CollectionLiteralResolver
import org.jetbrains.kotlin.resolve.CollectionLiteralResolver.Companion.ARRAY_OF_FUNCTION
import org.jetbrains.kotlin.resolve.CollectionLiteralResolver.Companion.PRIMITIVE_TYPE_TO_ARRAY
import org.jetbrains.kotlin.resolve.ArrayFqNames.ARRAY_OF_FUNCTION
import org.jetbrains.kotlin.resolve.ArrayFqNames.PRIMITIVE_TYPE_TO_ARRAY
import org.jetbrains.kotlin.resolve.constants.ArrayValue
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
import org.jetbrains.kotlin.storage.LockBasedStorageManager
@@ -69,7 +69,7 @@ internal fun constructAnnotation(psi: KtAnnotationEntry, targetClass: KClass<out
// TODO: consider inspecting `trace` to find diagnostics reported during the computation (such as division by zero, integer overflow, invalid annotation parameters etc.)
val argName = arg.getArgumentName()?.asName?.toString()
argName to result?.value
argName to result?.toRuntimeValue()
}
val mappedArguments: Map<KParameter, Any?> =
tryCreateCallableMappingFromNamedArgs(targetClass.constructors.first(), valueArguments)
@@ -92,6 +92,11 @@ internal fun ConstantExpressionEvaluator.evaluateToConstantArrayValue(
return ConstantValueFactory.createArrayValue(constants, TypeUtils.NO_EXPECTED_TYPE)
}
private fun ConstantValue<*>.toRuntimeValue(): Any? = when (this) {
is ArrayValue -> value.map { it.toRuntimeValue() }.toTypedArray()
else -> value
}
// NOTE: this class is used for error reporting. But in order to pass plugin verification, it should derive directly from java's Annotation
// and implement annotationType method (see #KT-16621 for details).
// TODO: instead of the workaround described above, consider using a sum-type for returning errors from constructAnnotation