Support array class literals in annotation serializer/deserializer

Note that this change brings an incompatibility: `Array<Foo>::class`
will be seen as `Foo::class` by the old deserializer. We consider this
OK because the compiler never had any logic that relied on reading class
literal arguments correctly (otherwise it wouldn't have worked because
it could only see `Array<*>::class` before this commit), and the support
of annotations on types in JVM reflection is only available in the
upcoming 1.3 release (KT-16795)

 #KT-22069 Fixed
This commit is contained in:
Alexander Udalov
2018-09-04 18:24:01 +03:00
parent f3f93ed6cc
commit f90303315d
11 changed files with 549 additions and 189 deletions
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.serialization
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationArgumentVisitor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
@@ -99,11 +100,23 @@ class AnnotationSerializer(private val stringTable: DescriptorAwareStringTable)
}
override fun visitKClassValue(value: KClassValue, data: Unit) {
val descriptor = value.value.constructor.declarationDescriptor as? ClassDescriptor
?: throw UnsupportedOperationException("Class literal annotation argument should be a class: $value")
var kotlinType = value.value
var arrayDimensions = 0
while (KotlinBuiltIns.isArray(kotlinType)) {
// We only support invariant projections and non-null array element types, see KT-26568
kotlinType = kotlinType.arguments.single().type
arrayDimensions++
}
val descriptor = kotlinType.constructor.declarationDescriptor as? ClassDescriptor
?: throw UnsupportedOperationException("Class literal annotation argument should be a class: $value")
type = Type.CLASS
classId = stringTable.getFqNameIndex(descriptor)
if (arrayDimensions > 0) {
arrayDimensionCount = arrayDimensions
}
}
override fun visitLongValue(value: LongValue, data: Unit) {