Reflection: add KClass.{supertypes,superclasses,allSupertypes,allSuperclasses}

Some things are not implemented yet for allSupertypes, such as KType->Type
mapping of types and generic substitution of built-in types
This commit is contained in:
Alexander Udalov
2016-07-12 18:42:46 +03:00
parent 486ea62c72
commit 4cd252d9d5
9 changed files with 262 additions and 4 deletions
@@ -18,6 +18,9 @@
package kotlin.reflect
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.utils.DFS
import kotlin.reflect.jvm.internal.KClassImpl
import kotlin.reflect.jvm.internal.KFunctionImpl
import kotlin.reflect.jvm.internal.KTypeImpl
@@ -170,3 +173,53 @@ val <T : Any> KClass<T>.declaredMemberExtensionProperties: Collection<KProperty2
.getMembers(memberScope, declaredOnly = true, nonExtensions = false, extensions = true)
.filterIsInstance<KProperty2<T, *, *>>()
.toList()
/**
* Immediate superclasses of this class, in the order they are listed in the source code.
* Includes superclasses and superinterfaces of the class, but does not include the class itself.
*/
val KClass<*>.superclasses: List<KClass<*>>
get() = supertypes.mapNotNull { it.classifier as? KClass<*> }
/**
* All supertypes of this class, including indirect ones, in no particular order.
* There is not more than one type in the returned collection that has any given classifier.
*/
val KClass<*>.allSupertypes: Collection<KType>
get() = DFS.dfs(
supertypes,
DFS.Neighbors { current ->
val klass = current.classifier as? KClass<*> ?: throw KotlinReflectionInternalError("Supertype not a class: $current")
val supertypes = klass.supertypes
val typeArguments = current.arguments
if (typeArguments.isEmpty()) supertypes
else TypeSubstitutor.create((current as KTypeImpl).type).let { substitutor ->
supertypes.map { supertype ->
val substituted = substitutor.substitute((supertype as KTypeImpl).type, Variance.INVARIANT)
?: throw KotlinReflectionInternalError("Type substitution failed: $supertype ($current)")
KTypeImpl(substituted) {
// TODO
TODO("Java type for supertype")
}
}
}
},
DFS.VisitedWithSet(),
object : DFS.NodeHandlerWithListResult<KType, KType>() {
override fun beforeChildren(current: KType): Boolean {
result.add(current)
return true
}
}
)
/**
* All superclasses of this class, including indirect ones, in no particular order.
* Includes superclasses and superinterfaces of the class, but does not include the class itself.
* The returned collection does not contain more than one instance of any given class.
*/
val KClass<*>.allSuperclasses: Collection<KClass<*>>
get() = allSupertypes.map { supertype ->
supertype.classifier as? KClass<*> ?: throw KotlinReflectionInternalError("Supertype not a class: $supertype")
}
@@ -139,6 +139,26 @@ internal class KClassImpl<T : Any>(override val jClass: Class<T>) :
override val typeParameters: List<KTypeParameter>
get() = descriptor.declaredTypeParameters.map(::KTypeParameterImpl)
override val supertypes: List<KType>
get() = descriptor.typeConstructor.supertypes.map { kotlinType ->
KTypeImpl(kotlinType) {
val superClass = kotlinType.constructor.declarationDescriptor
if (superClass !is ClassDescriptor) throw KotlinReflectionInternalError("Supertype not a class: $superClass")
val superJavaClass = superClass.toJavaClass()
?: throw KotlinReflectionInternalError("Unsupported superclass of $this: $superClass")
if (jClass.superclass == superJavaClass) {
jClass.genericSuperclass
}
else {
val index = jClass.interfaces.indexOf(superJavaClass)
if (index < 0) throw KotlinReflectionInternalError("No superclass of $this in Java reflection for $superClass")
jClass.genericInterfaces[index]
}
}
}
override fun equals(other: Any?): Boolean =
other is KClassImpl<*> && jClass == other.jClass