Fix reflection for repeated annotations with array arguments

This is related to 8308f5d7d3 (KT-44977).

It turns out that it's necessary to create `ArrayValue` with a
precomputed type not only in case of annotations stored directly in
Kotlin metadata (i.e. annotations on types and type parameters), but
also for arguments of repeated annotations. The reason is that repeated
annotations are stored in an array themselves, as an argument to another
(container) annotation. The annotation-reading code unwraps this array
to load repeated annotations as individual instances of
`AnnotationDescriptor`, but in contrast to loading normal annotations,
it doesn't set `source` to the reflection object, it uses `NO_SOURCE`
(see BinaryClassAnnotationAndConstantLoaderImpl.AbstractAnnotationArgumentVisitor.visitArray).

So when kotlin-reflect is later asked for the arguments of the
annotation, it needs to recreate the reflection object from
`AnnotationDescriptor` in `util.kt`. Doing so requires knowing the array
type, which is now present because we're creating a `TypedArrayValue`
(previously `DeserializedArrayValue`) in places where arrays are read as
annotation arguments.

Alternative solution would be to fix source passed to
`AnnotationDescriptorImpl` in the annotation-reading code, but that
seems a bit messy because the code is very abstract and is used in lots
of other places.

 #KT-53279 Fixed
This commit is contained in:
Alexander Udalov
2022-09-29 00:57:29 +02:00
committed by Space Team
parent 51ce829b96
commit 4dcf50d483
10 changed files with 164 additions and 32 deletions
@@ -45,7 +45,6 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
import org.jetbrains.kotlin.resolve.isInlineClassType
import org.jetbrains.kotlin.serialization.deserialization.DeserializationContext
import org.jetbrains.kotlin.serialization.deserialization.DeserializedArrayValue
import org.jetbrains.kotlin.serialization.deserialization.MemberDeserializer
import java.lang.reflect.Type
import kotlin.jvm.internal.FunctionReference
@@ -188,7 +187,7 @@ private fun ConstantValue<*>.toRuntimeValue(classLoader: ClassLoader): Any? = wh
}
private fun ArrayValue.arrayToRuntimeValue(classLoader: ClassLoader): Any? {
val type = (this as? DeserializedArrayValue)?.type ?: return null
val type = (this as? TypedArrayValue)?.type ?: return null
val values = value.map { it.toRuntimeValue(classLoader) }
return when (KotlinBuiltIns.getPrimitiveArrayElementType(type)) {