Reflection: add KType.classifier

#KT-8998 In Progress
This commit is contained in:
Alexander Udalov
2016-07-12 16:09:29 +03:00
parent 2ab0f489b5
commit c1dd831e65
8 changed files with 284 additions and 1 deletions
@@ -16,9 +16,18 @@
package kotlin.reflect.jvm.internal
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.load.java.structure.reflect.createArrayType
import org.jetbrains.kotlin.load.java.structure.reflect.primitiveByWrapper
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
import java.lang.reflect.Type
import kotlin.reflect.KClass
import kotlin.reflect.KClassifier
import kotlin.reflect.KType
import kotlin.reflect.KTypeParameter
internal class KTypeImpl(
val type: KotlinType,
@@ -26,11 +35,49 @@ internal class KTypeImpl(
) : KType {
internal val javaType: Type by ReflectProperties.lazySoft(computeJavaType)
override val classifier: KClassifier?
get() = convert(type)
private fun convert(type: KotlinType): KClassifier? {
val descriptor = type.constructor.declarationDescriptor
when (descriptor) {
is ClassDescriptor -> {
val jClass = descriptor.toJavaClass() ?: return null
if (jClass.isArray) {
// There may be no argument if it's a primitive array (such as IntArray)
val argument = type.arguments.singleOrNull()?.type ?: return KClassImpl(jClass)
val elementClassifier = convert(argument)
val elementType = when (elementClassifier) {
is KClass<*> -> elementClassifier
is KTypeParameter -> {
// For arrays of type parameters (`Array<T>`) we return the KClass representing `Array<Any>`
// since there's no other sensible option
// TODO: return `Array<erasure-of-T>`
Any::class
}
else -> TODO("Arrays of type alias classifiers are not yet supported")
}
return KClassImpl(elementType.java.createArrayType())
}
if (!TypeUtils.isNullableType(type)) {
return KClassImpl(jClass.primitiveByWrapper ?: jClass)
}
return KClassImpl(jClass)
}
is TypeParameterDescriptor -> return KTypeParameterImpl(descriptor)
is TypeAliasDescriptor -> TODO("Type alias classifiers are not yet supported")
else -> return null
}
}
override val isMarkedNullable: Boolean
get() = type.isMarkedNullable
override fun equals(other: Any?) =
other is KTypeImpl && type.equals(other.type)
other is KTypeImpl && type == other.type
override fun hashCode() =
type.hashCode()