Reformat module reflection.jvm, fix inspections/warnings

This commit is contained in:
Alexander Udalov
2018-06-28 18:43:17 +02:00
parent 25ee67a644
commit a7c80f2df1
27 changed files with 450 additions and 473 deletions
@@ -15,6 +15,7 @@
*/ */
@file:JvmName("KCallablesJvm") @file:JvmName("KCallablesJvm")
package kotlin.reflect.jvm package kotlin.reflect.jvm
import java.lang.reflect.AccessibleObject import java.lang.reflect.AccessibleObject
@@ -40,21 +41,21 @@ var KCallable<*>.isAccessible: Boolean
return when (this) { return when (this) {
is KMutableProperty -> is KMutableProperty ->
javaField?.isAccessible ?: true && javaField?.isAccessible ?: true &&
javaGetter?.isAccessible ?: true && javaGetter?.isAccessible ?: true &&
javaSetter?.isAccessible ?: true javaSetter?.isAccessible ?: true
is KProperty -> is KProperty ->
javaField?.isAccessible ?: true && javaField?.isAccessible ?: true &&
javaGetter?.isAccessible ?: true javaGetter?.isAccessible ?: true
is KProperty.Getter -> is KProperty.Getter ->
property.javaField?.isAccessible ?: true && property.javaField?.isAccessible ?: true &&
javaMethod?.isAccessible ?: true javaMethod?.isAccessible ?: true
is KMutableProperty.Setter<*> -> is KMutableProperty.Setter<*> ->
property.javaField?.isAccessible ?: true && property.javaField?.isAccessible ?: true &&
javaMethod?.isAccessible ?: true javaMethod?.isAccessible ?: true
is KFunction -> is KFunction ->
javaMethod?.isAccessible ?: true && javaMethod?.isAccessible ?: true &&
(this.asKCallableImpl()?.defaultCaller?.member as? AccessibleObject)?.isAccessible ?: true && (this.asKCallableImpl()?.defaultCaller?.member as? AccessibleObject)?.isAccessible ?: true &&
this.javaConstructor?.isAccessible ?: true this.javaConstructor?.isAccessible ?: true
else -> throw UnsupportedOperationException("Unknown callable: $this ($javaClass)") else -> throw UnsupportedOperationException("Unknown callable: $this ($javaClass)")
} }
} }
@@ -15,6 +15,7 @@
*/ */
@file:JvmName("KClassesJvm") @file:JvmName("KClassesJvm")
package kotlin.reflect.jvm package kotlin.reflect.jvm
import kotlin.reflect.KClass import kotlin.reflect.KClass
@@ -26,6 +27,4 @@ import kotlin.reflect.jvm.internal.KClassImpl
* @see [java.lang.Class.getName] * @see [java.lang.Class.getName]
*/ */
val KClass<*>.jvmName: String val KClass<*>.jvmName: String
get() { get() = (this as KClassImpl).jClass.name
return (this as KClassImpl).jClass.name
}
@@ -15,14 +15,18 @@
*/ */
@file:JvmName("KTypesJvm") @file:JvmName("KTypesJvm")
package kotlin.reflect.jvm package kotlin.reflect.jvm
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind.ANNOTATION_CLASS import org.jetbrains.kotlin.descriptors.ClassKind.ANNOTATION_CLASS
import org.jetbrains.kotlin.descriptors.ClassKind.INTERFACE import org.jetbrains.kotlin.descriptors.ClassKind.INTERFACE
import kotlin.reflect.* import kotlin.reflect.KClass
import kotlin.reflect.jvm.internal.KotlinReflectionInternalError import kotlin.reflect.KClassifier
import kotlin.reflect.KType
import kotlin.reflect.KTypeParameter
import kotlin.reflect.jvm.internal.KTypeImpl import kotlin.reflect.jvm.internal.KTypeImpl
import kotlin.reflect.jvm.internal.KotlinReflectionInternalError
/** /**
* Returns the [KClass] instance representing the runtime class to which this type is erased to on JVM. * Returns the [KClass] instance representing the runtime class to which this type is erased to on JVM.
@@ -15,11 +15,11 @@
*/ */
@file:JvmName("ReflectJvmMapping") @file:JvmName("ReflectJvmMapping")
package kotlin.reflect.jvm package kotlin.reflect.jvm
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import java.lang.reflect.* import java.lang.reflect.*
import java.util.*
import kotlin.reflect.* import kotlin.reflect.*
import kotlin.reflect.full.companionObject import kotlin.reflect.full.companionObject
import kotlin.reflect.full.functions import kotlin.reflect.full.functions
@@ -65,7 +65,8 @@ val KFunction<*>.javaMethod: Method?
* Returns a Java [Constructor] instance corresponding to the given Kotlin function, * Returns a Java [Constructor] instance corresponding to the given Kotlin function,
* or `null` if this function is not a constructor or cannot be represented by a Java [Constructor]. * or `null` if this function is not a constructor or cannot be represented by a Java [Constructor].
*/ */
@Suppress("UNCHECKED_CAST") val <T> KFunction<T>.javaConstructor: Constructor<T>? @Suppress("UNCHECKED_CAST")
val <T> KFunction<T>.javaConstructor: Constructor<T>?
get() = this.asKCallableImpl()?.caller?.member as? Constructor<T> get() = this.asKCallableImpl()?.caller?.member as? Constructor<T>
@@ -78,7 +79,6 @@ val KType.javaType: Type
get() = (this as KTypeImpl).javaType get() = (this as KTypeImpl).javaType
// Java reflection -> Kotlin reflection // Java reflection -> Kotlin reflection
/** /**
@@ -102,11 +102,11 @@ val Field.kotlinProperty: KProperty<*>?
private fun Member.getKPackage(): KDeclarationContainer? = private fun Member.getKPackage(): KDeclarationContainer? =
when (ReflectKotlinClass.create(declaringClass)?.classHeader?.kind) { when (ReflectKotlinClass.create(declaringClass)?.classHeader?.kind) {
KotlinClassHeader.Kind.FILE_FACADE, KotlinClassHeader.Kind.MULTIFILE_CLASS, KotlinClassHeader.Kind.MULTIFILE_CLASS_PART -> KotlinClassHeader.Kind.FILE_FACADE, KotlinClassHeader.Kind.MULTIFILE_CLASS, KotlinClassHeader.Kind.MULTIFILE_CLASS_PART ->
KPackageImpl(declaringClass) KPackageImpl(declaringClass)
else -> null else -> null
} }
/** /**
* Returns a [KFunction] instance corresponding to the given Java [Method] instance, * Returns a [KFunction] instance corresponding to the given Java [Method] instance,
@@ -129,7 +129,7 @@ val Method.kotlinFunction: KFunction<*>?
companion.functions.firstOrNull { companion.functions.firstOrNull {
val m = it.javaMethod val m = it.javaMethod
m != null && m.name == this.name && m != null && m.name == this.name &&
Arrays.equals(m.parameterTypes, this.parameterTypes) && m.returnType == this.returnType m.parameterTypes!!.contentEquals(this.parameterTypes) && m.returnType == this.returnType
}?.let { return it } }?.let { return it }
} }
} }
@@ -23,13 +23,13 @@ import kotlin.reflect.jvm.internal.structure.wrapperByPrimitive
import java.lang.reflect.Method as ReflectMethod import java.lang.reflect.Method as ReflectMethod
internal class AnnotationConstructorCaller( internal class AnnotationConstructorCaller(
private val jClass: Class<*>, private val jClass: Class<*>,
private val parameterNames: List<String>, private val parameterNames: List<String>,
private val callMode: CallMode, private val callMode: CallMode,
origin: Origin, origin: Origin,
private val methods: List<ReflectMethod> = parameterNames.map { name -> jClass.getDeclaredMethod(name) } private val methods: List<ReflectMethod> = parameterNames.map { name -> jClass.getDeclaredMethod(name) }
) : FunctionCaller<Nothing?>( ) : FunctionCaller<Nothing?>(
null, jClass, null, methods.map { it.genericReturnType }.toTypedArray() null, jClass, null, methods.map { it.genericReturnType }.toTypedArray()
) { ) {
enum class CallMode { CALL_BY_NAME, POSITIONAL_CALL } enum class CallMode { CALL_BY_NAME, POSITIONAL_CALL }
@@ -44,9 +44,9 @@ internal class AnnotationConstructorCaller(
// TODO: consider lifting this restriction once KT-8957 is implemented // TODO: consider lifting this restriction once KT-8957 is implemented
if (callMode == CallMode.POSITIONAL_CALL && origin == Origin.JAVA && (parameterNames - "value").isNotEmpty()) { if (callMode == CallMode.POSITIONAL_CALL && origin == Origin.JAVA && (parameterNames - "value").isNotEmpty()) {
throw UnsupportedOperationException( throw UnsupportedOperationException(
"Positional call of a Java annotation constructor is allowed only if there are no parameters " + "Positional call of a Java annotation constructor is allowed only if there are no parameters " +
"or one parameter named \"value\". This restriction exists because Java annotations (in contrast to Kotlin)" + "or one parameter named \"value\". This restriction exists because Java annotations (in contrast to Kotlin)" +
"do not impose any order on their arguments. Use KCallable#callBy instead." "do not impose any order on their arguments. Use KCallable#callBy instead."
) )
} }
} }
@@ -56,8 +56,8 @@ internal class AnnotationConstructorCaller(
val values = args.mapIndexed { index, arg -> val values = args.mapIndexed { index, arg ->
val value = val value =
if (arg == null && callMode == CallMode.CALL_BY_NAME) defaultValues[index] if (arg == null && callMode == CallMode.CALL_BY_NAME) defaultValues[index]
else arg.transformKotlinToJvm(erasedParameterTypes[index]) else arg.transformKotlinToJvm(erasedParameterTypes[index])
value ?: throwIllegalArgumentType(index, parameterNames[index], erasedParameterTypes[index]) value ?: throwIllegalArgumentType(index, parameterNames[index], erasedParameterTypes[index])
} }
@@ -103,23 +103,23 @@ private fun throwIllegalArgumentType(index: Int, name: String, expectedJvmType:
private fun createAnnotationInstance(annotationClass: Class<*>, methods: List<ReflectMethod>, values: Map<String, Any>): Any { private fun createAnnotationInstance(annotationClass: Class<*>, methods: List<ReflectMethod>, values: Map<String, Any>): Any {
fun equals(other: Any?): Boolean = fun equals(other: Any?): Boolean =
(other as? Annotation)?.annotationClass?.java == annotationClass && (other as? Annotation)?.annotationClass?.java == annotationClass &&
methods.all { method -> methods.all { method ->
val ours = values[method.name] val ours = values[method.name]
val theirs = method(other) val theirs = method(other)
when (ours) { when (ours) {
is BooleanArray -> Arrays.equals(ours, theirs as BooleanArray) is BooleanArray -> Arrays.equals(ours, theirs as BooleanArray)
is CharArray -> Arrays.equals(ours, theirs as CharArray) is CharArray -> Arrays.equals(ours, theirs as CharArray)
is ByteArray -> Arrays.equals(ours, theirs as ByteArray) is ByteArray -> Arrays.equals(ours, theirs as ByteArray)
is ShortArray -> Arrays.equals(ours, theirs as ShortArray) is ShortArray -> Arrays.equals(ours, theirs as ShortArray)
is IntArray -> Arrays.equals(ours, theirs as IntArray) is IntArray -> Arrays.equals(ours, theirs as IntArray)
is FloatArray -> Arrays.equals(ours, theirs as FloatArray) is FloatArray -> Arrays.equals(ours, theirs as FloatArray)
is LongArray -> Arrays.equals(ours, theirs as LongArray) is LongArray -> Arrays.equals(ours, theirs as LongArray)
is DoubleArray -> Arrays.equals(ours, theirs as DoubleArray) is DoubleArray -> Arrays.equals(ours, theirs as DoubleArray)
is Array<*> -> Arrays.equals(ours, theirs as Array<*>) is Array<*> -> Arrays.equals(ours, theirs as Array<*>)
else -> ours == theirs else -> ours == theirs
}
} }
}
val hashCode by lazy { val hashCode by lazy {
values.entries.sumBy { entry -> values.entries.sumBy { entry ->
@@ -163,7 +163,7 @@ private fun createAnnotationInstance(annotationClass: Class<*>, methods: List<Re
} }
} }
return Proxy.newProxyInstance(annotationClass.classLoader, arrayOf(annotationClass)) { proxy, method, args -> return Proxy.newProxyInstance(annotationClass.classLoader, arrayOf(annotationClass)) { _, method, args ->
val name = method.name val name = method.name
when (name) { when (name) {
"annotationType" -> annotationClass "annotationType" -> annotationClass
@@ -39,7 +39,6 @@ internal object EmptyContainerForLocal : KDeclarationContainerImpl() {
override fun getLocalProperty(index: Int): PropertyDescriptor? = null override fun getLocalProperty(index: Int): PropertyDescriptor? = null
private fun fail(): Nothing = throw KotlinReflectionInternalError( private fun fail(): Nothing = throw KotlinReflectionInternalError(
"Introspecting local functions, lambdas, anonymous functions and local variables " + "Introspecting local functions, lambdas, anonymous functions and local variables is not yet fully supported in Kotlin reflection"
"is not yet fully supported in Kotlin reflection"
) )
} }
@@ -24,14 +24,13 @@ import java.lang.reflect.Field as ReflectField
import java.lang.reflect.Method as ReflectMethod import java.lang.reflect.Method as ReflectMethod
internal abstract class FunctionCaller<out M : Member?>( internal abstract class FunctionCaller<out M : Member?>(
internal val member: M, internal val member: M,
internal val returnType: Type, internal val returnType: Type,
internal val instanceClass: Class<*>?, internal val instanceClass: Class<*>?,
valueParameterTypes: Array<Type> valueParameterTypes: Array<Type>
) { ) {
val parameterTypes: List<Type> = val parameterTypes: List<Type> =
instanceClass?.let { listOf(it, *valueParameterTypes) } ?: instanceClass?.let { listOf(it, *valueParameterTypes) } ?: valueParameterTypes.toList()
valueParameterTypes.toList()
val arity: Int val arity: Int
get() = parameterTypes.size get() = parameterTypes.size
@@ -53,13 +52,13 @@ internal abstract class FunctionCaller<out M : Member?>(
// Constructors // Constructors
class Constructor(constructor: ReflectConstructor<*>) : FunctionCaller<ReflectConstructor<*>>( class Constructor(constructor: ReflectConstructor<*>) : FunctionCaller<ReflectConstructor<*>>(
constructor, constructor,
constructor.declaringClass, constructor.declaringClass,
constructor.declaringClass.let { klass -> constructor.declaringClass.let { klass ->
val outerClass = klass.declaringClass val outerClass = klass.declaringClass
if (outerClass != null && !Modifier.isStatic(klass.modifiers)) outerClass else null if (outerClass != null && !Modifier.isStatic(klass.modifiers)) outerClass else null
}, },
constructor.genericParameterTypes constructor.genericParameterTypes
) { ) {
override fun call(args: Array<*>): Any? { override fun call(args: Array<*>): Any? {
checkArguments(args) checkArguments(args)
@@ -70,10 +69,10 @@ internal abstract class FunctionCaller<out M : Member?>(
// TODO fix 'callBy' for bound (and non-bound) inner class constructor references // TODO fix 'callBy' for bound (and non-bound) inner class constructor references
// See https://youtrack.jetbrains.com/issue/KT-14990 // See https://youtrack.jetbrains.com/issue/KT-14990
class BoundConstructor(constructor: ReflectConstructor<*>, private val boundReceiver: Any?) : class BoundConstructor(constructor: ReflectConstructor<*>, private val boundReceiver: Any?) :
FunctionCaller<ReflectConstructor<*>>( FunctionCaller<ReflectConstructor<*>>(
constructor, constructor.declaringClass, null, constructor, constructor.declaringClass, null,
constructor.genericParameterTypes constructor.genericParameterTypes
) { ) {
override fun call(args: Array<*>): Any? { override fun call(args: Array<*>): Any? {
checkArguments(args) checkArguments(args)
return member.newInstance(*argsWithReceiver(boundReceiver, args)) return member.newInstance(*argsWithReceiver(boundReceiver, args))
@@ -83,14 +82,14 @@ internal abstract class FunctionCaller<out M : Member?>(
// Methods // Methods
abstract class Method( abstract class Method(
method: ReflectMethod, method: ReflectMethod,
requiresInstance: Boolean = !Modifier.isStatic(method.modifiers), requiresInstance: Boolean = !Modifier.isStatic(method.modifiers),
parameterTypes: Array<Type> = method.genericParameterTypes parameterTypes: Array<Type> = method.genericParameterTypes
) : FunctionCaller<ReflectMethod>( ) : FunctionCaller<ReflectMethod>(
method, method,
method.genericReturnType, method.genericReturnType,
if (requiresInstance) method.declaringClass else null, if (requiresInstance) method.declaringClass else null,
parameterTypes parameterTypes
) { ) {
private val isVoidMethod = returnType == Void.TYPE private val isVoidMethod = returnType == Void.TYPE
@@ -124,24 +123,23 @@ internal abstract class FunctionCaller<out M : Member?>(
} }
} }
class BoundStaticMethod(method: ReflectMethod, private val boundReceiver: Any?) : class BoundStaticMethod(method: ReflectMethod, private val boundReceiver: Any?) : Method(
Method(method, requiresInstance = false, parameterTypes = method.genericParameterTypes.dropFirst()) { method, requiresInstance = false, parameterTypes = method.genericParameterTypes.dropFirst()
) {
override fun call(args: Array<*>): Any? { override fun call(args: Array<*>): Any? {
checkArguments(args) checkArguments(args)
return callMethod(null, argsWithReceiver(boundReceiver, args)) return callMethod(null, argsWithReceiver(boundReceiver, args))
} }
} }
class BoundInstanceMethod(method: ReflectMethod, private val boundReceiver: Any?) : class BoundInstanceMethod(method: ReflectMethod, private val boundReceiver: Any?) : Method(method, requiresInstance = false) {
Method(method, requiresInstance = false) {
override fun call(args: Array<*>): Any? { override fun call(args: Array<*>): Any? {
checkArguments(args) checkArguments(args)
return callMethod(boundReceiver, args) return callMethod(boundReceiver, args)
} }
} }
class BoundJvmStaticInObject(method: ReflectMethod) : class BoundJvmStaticInObject(method: ReflectMethod) : Method(method, requiresInstance = false) {
Method(method, requiresInstance = false) {
override fun call(args: Array<*>): Any? { override fun call(args: Array<*>): Any? {
checkArguments(args) checkArguments(args)
return callMethod(null, args) return callMethod(null, args)
@@ -151,13 +149,13 @@ internal abstract class FunctionCaller<out M : Member?>(
// Field accessors // Field accessors
abstract class FieldGetter( abstract class FieldGetter(
field: ReflectField, field: ReflectField,
requiresInstance: Boolean = !Modifier.isStatic(field.modifiers) requiresInstance: Boolean = !Modifier.isStatic(field.modifiers)
) : FunctionCaller<ReflectField>( ) : FunctionCaller<ReflectField>(
field, field,
field.genericType, field.genericType,
if (requiresInstance) field.declaringClass else null, if (requiresInstance) field.declaringClass else null,
emptyArray() emptyArray()
) { ) {
override fun call(args: Array<*>): Any? { override fun call(args: Array<*>): Any? {
checkArguments(args) checkArguments(args)
@@ -166,14 +164,14 @@ internal abstract class FunctionCaller<out M : Member?>(
} }
abstract class FieldSetter( abstract class FieldSetter(
field: ReflectField, field: ReflectField,
private val notNull: Boolean, private val notNull: Boolean,
requiresInstance: Boolean = !Modifier.isStatic(field.modifiers) requiresInstance: Boolean = !Modifier.isStatic(field.modifiers)
) : FunctionCaller<ReflectField>( ) : FunctionCaller<ReflectField>(
field, field,
Void.TYPE, Void.TYPE,
if (requiresInstance) field.declaringClass else null, if (requiresInstance) field.declaringClass else null,
arrayOf(field.genericType) arrayOf(field.genericType)
) { ) {
override fun checkArguments(args: Array<*>) { override fun checkArguments(args: Array<*>) {
super.checkArguments(args) super.checkArguments(args)
@@ -199,16 +197,18 @@ internal abstract class FunctionCaller<out M : Member?>(
} }
} }
class ClassCompanionFieldGetter(field: ReflectField, klass: Class<*>) : class ClassCompanionFieldGetter(field: ReflectField, klass: Class<*>) : FunctionCaller<ReflectField>(
FunctionCaller<ReflectField>(field, field.genericType, klass, emptyArray()) { field, field.genericType, klass, emptyArray()
) {
override fun call(args: Array<*>): Any? { override fun call(args: Array<*>): Any? {
checkArguments(args) checkArguments(args)
return member.get(args.first()) return member.get(args.first())
} }
} }
class BoundInstanceFieldGetter(field: ReflectField, private val boundReceiver: Any?) : class BoundInstanceFieldGetter(field: ReflectField, private val boundReceiver: Any?) : FieldGetter(
FieldGetter(field, requiresInstance = false) { field, requiresInstance = false
) {
override fun call(args: Array<*>): Any? { override fun call(args: Array<*>): Any? {
checkArguments(args) checkArguments(args)
return member.get(boundReceiver) return member.get(boundReceiver)
@@ -217,8 +217,9 @@ internal abstract class FunctionCaller<out M : Member?>(
class BoundJvmStaticInObjectFieldGetter(field: ReflectField) : FieldGetter(field, requiresInstance = false) class BoundJvmStaticInObjectFieldGetter(field: ReflectField) : FieldGetter(field, requiresInstance = false)
class BoundClassCompanionFieldGetter(field: ReflectField, private val boundReceiver: Any?) : class BoundClassCompanionFieldGetter(field: ReflectField, private val boundReceiver: Any?) : FieldGetter(
FieldGetter(field, requiresInstance = false) { field, requiresInstance = false
) {
override fun call(args: Array<*>): Any? { override fun call(args: Array<*>): Any? {
checkArguments(args) checkArguments(args)
return member.get(boundReceiver) return member.get(boundReceiver)
@@ -236,32 +237,36 @@ internal abstract class FunctionCaller<out M : Member?>(
} }
} }
class ClassCompanionFieldSetter(field: ReflectField, klass: Class<*>) : class ClassCompanionFieldSetter(field: ReflectField, klass: Class<*>) : FunctionCaller<ReflectField>(
FunctionCaller<ReflectField>(field, Void.TYPE, klass, arrayOf(field.genericType)) { field, Void.TYPE, klass, arrayOf(field.genericType)
) {
override fun call(args: Array<*>): Any? { override fun call(args: Array<*>): Any? {
checkArguments(args) checkArguments(args)
return member.set(null, args.last()) return member.set(null, args.last())
} }
} }
class BoundInstanceFieldSetter(field: ReflectField, notNull: Boolean, private val boundReceiver: Any?) : class BoundInstanceFieldSetter(field: ReflectField, notNull: Boolean, private val boundReceiver: Any?) : FieldSetter(
FieldSetter(field, notNull, false) { field, notNull, false
) {
override fun call(args: Array<*>): Any? { override fun call(args: Array<*>): Any? {
checkArguments(args) checkArguments(args)
return member.set(boundReceiver, args.first()) return member.set(boundReceiver, args.first())
} }
} }
class BoundJvmStaticInObjectFieldSetter(field: ReflectField, notNull: Boolean) : class BoundJvmStaticInObjectFieldSetter(field: ReflectField, notNull: Boolean) : FieldSetter(
FieldSetter(field, notNull, requiresInstance = false) { field, notNull, requiresInstance = false
) {
override fun call(args: Array<*>): Any? { override fun call(args: Array<*>): Any? {
checkArguments(args) checkArguments(args)
return member.set(null, args.last()) return member.set(null, args.last())
} }
} }
class BoundClassCompanionFieldSetter(field: ReflectField, klass: Class<*>) : class BoundClassCompanionFieldSetter(field: ReflectField, klass: Class<*>) : FunctionCaller<ReflectField>(
FunctionCaller<ReflectField>(field, Void.TYPE, klass, arrayOf(field.genericType)) { field, Void.TYPE, klass, arrayOf(field.genericType)
) {
override fun call(args: Array<*>): Any? { override fun call(args: Array<*>): Any? {
checkArguments(args) checkArguments(args)
return member.set(null, args.last()) return member.set(null, args.last())
@@ -277,17 +282,17 @@ internal abstract class FunctionCaller<out M : Member?>(
companion object { companion object {
// TODO lazily allocate array at bound callers? // TODO lazily allocate array at bound callers?
fun argsWithReceiver(receiver: Any?, args: Array<out Any?>): Array<out Any?> = fun argsWithReceiver(receiver: Any?, args: Array<out Any?>): Array<out Any?> =
arrayOfNulls<Any?>(args.size + 1).apply { arrayOfNulls<Any?>(args.size + 1).apply {
this[0] = receiver this[0] = receiver
System.arraycopy(args, 0, this, 1, args.size) System.arraycopy(args, 0, this, 1, args.size)
} }
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
inline fun <reified T> Array<out T>.dropFirst(): Array<T> = inline fun <reified T> Array<out T>.dropFirst(): Array<T> =
if (size <= 1) emptyArray<T>() else copyOfRange(1, size) as Array<T> if (size <= 1) emptyArray() else copyOfRange(1, size) as Array<T>
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
fun Array<*>.dropFirstArg(): Array<Any?> = fun Array<*>.dropFirstArg(): Array<Any?> =
(this as Array<Any?>).dropFirst() (this as Array<Any?>).dropFirst()
} }
} }
@@ -19,31 +19,31 @@ package kotlin.reflect.jvm.internal
import kotlin.reflect.KCallable import kotlin.reflect.KCallable
internal interface FunctionWithAllInvokes : internal interface FunctionWithAllInvokes :
// (0..22).forEach { n -> println("Function$n<" + (0..n).joinToString { "Any?" } + ">,") } // (0..22).forEach { n -> println("Function$n<" + (0..n).joinToString { "Any?" } + ">,") }
Function0<Any?>, Function0<Any?>,
Function1<Any?, Any?>, Function1<Any?, Any?>,
Function2<Any?, Any?, Any?>, Function2<Any?, Any?, Any?>,
Function3<Any?, Any?, Any?, Any?>, Function3<Any?, Any?, Any?, Any?>,
Function4<Any?, Any?, Any?, Any?, Any?>, Function4<Any?, Any?, Any?, Any?, Any?>,
Function5<Any?, Any?, Any?, Any?, Any?, Any?>, Function5<Any?, Any?, Any?, Any?, Any?, Any?>,
Function6<Any?, Any?, Any?, Any?, Any?, Any?, Any?>, Function6<Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function7<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>, Function7<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function8<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>, Function8<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function9<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>, Function9<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function10<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>, Function10<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function11<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>, Function11<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function12<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>, Function12<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function13<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>, Function13<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function14<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>, Function14<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function15<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>, Function15<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function16<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>, Function16<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function17<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>, Function17<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function18<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>, Function18<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function19<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>, Function19<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function20<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>, Function20<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function21<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>, Function21<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function22<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>, Function22<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
KCallable<Any?> KCallable<Any?>
{ {
// (0..22).forEach { n -> println("override fun invoke(" + (1..n).joinToString { "p$it: Any?" } + "): Any? = call(" + (1..n).joinToString { "p$it" } + ")") } // (0..22).forEach { n -> println("override fun invoke(" + (1..n).joinToString { "p$it: Any?" } + "): Any? = call(" + (1..n).joinToString { "p$it" } + ")") }
override fun invoke(): Any? = call() override fun invoke(): Any? = call()
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
import java.lang.reflect.Type import java.lang.reflect.Type
import java.util.* import java.util.*
import kotlin.reflect.* import kotlin.reflect.*
import kotlin.reflect.jvm.internal.KotlinReflectionInternalError
import kotlin.reflect.jvm.javaType import kotlin.reflect.jvm.javaType
internal abstract class KCallableImpl<out R> : KCallable<R> { internal abstract class KCallableImpl<out R> : KCallable<R> {
@@ -38,11 +37,11 @@ internal abstract class KCallableImpl<out R> : KCallable<R> {
abstract val isBound: Boolean abstract val isBound: Boolean
private val annotations_ = ReflectProperties.lazySoft { descriptor.computeAnnotations() } private val _annotations = ReflectProperties.lazySoft { descriptor.computeAnnotations() }
override val annotations: List<Annotation> get() = annotations_() override val annotations: List<Annotation> get() = _annotations()
private val parameters_ = ReflectProperties.lazySoft { private val _parameters = ReflectProperties.lazySoft {
val descriptor = descriptor val descriptor = descriptor
val result = ArrayList<KParameter>() val result = ArrayList<KParameter>()
var index = 0 var index = 0
@@ -71,21 +70,21 @@ internal abstract class KCallableImpl<out R> : KCallable<R> {
} }
override val parameters: List<KParameter> override val parameters: List<KParameter>
get() = parameters_() get() = _parameters()
private val returnType_ = ReflectProperties.lazySoft { private val _returnType = ReflectProperties.lazySoft {
KTypeImpl(descriptor.returnType!!) { caller.returnType } KTypeImpl(descriptor.returnType!!) { caller.returnType }
} }
override val returnType: KType override val returnType: KType
get() = returnType_() get() = _returnType()
private val typeParameters_ = ReflectProperties.lazySoft { private val _typeParameters = ReflectProperties.lazySoft {
descriptor.typeParameters.map(::KTypeParameterImpl) descriptor.typeParameters.map(::KTypeParameterImpl)
} }
override val typeParameters: List<KTypeParameter> override val typeParameters: List<KTypeParameter>
get() = typeParameters_() get() = _typeParameters()
override val visibility: KVisibility? override val visibility: KVisibility?
get() = descriptor.visibility.toKVisibility() get() = descriptor.visibility.toKVisibility()
@@ -184,19 +183,18 @@ internal abstract class KCallableImpl<out R> : KCallable<R> {
} }
private fun defaultPrimitiveValue(type: Type): Any? = private fun defaultPrimitiveValue(type: Type): Any? =
if (type is Class<*> && type.isPrimitive) { if (type is Class<*> && type.isPrimitive) {
when (type) { when (type) {
Boolean::class.java -> false Boolean::class.java -> false
Char::class.java -> 0.toChar() Char::class.java -> 0.toChar()
Byte::class.java -> 0.toByte() Byte::class.java -> 0.toByte()
Short::class.java -> 0.toShort() Short::class.java -> 0.toShort()
Int::class.java -> 0 Int::class.java -> 0
Float::class.java -> 0f Float::class.java -> 0f
Long::class.java -> 0L Long::class.java -> 0L
Double::class.java -> 0.0 Double::class.java -> 0.0
Void.TYPE -> throw IllegalStateException("Parameter with void type is illegal") Void.TYPE -> throw IllegalStateException("Parameter with void type is illegal")
else -> throw UnsupportedOperationException("Unknown primitive: $type") else -> throw UnsupportedOperationException("Unknown primitive: $type")
}
} }
else null } else null
} }
@@ -47,8 +47,8 @@ internal class KClassImpl<T : Any>(override val jClass: Class<T>) : KDeclaration
val moduleData = data().moduleData val moduleData = data().moduleData
val descriptor = val descriptor =
if (classId.isLocal) moduleData.deserialization.deserializeClass(classId) if (classId.isLocal) moduleData.deserialization.deserializeClass(classId)
else moduleData.module.findClassAcrossModuleDependencies(classId) else moduleData.module.findClassAcrossModuleDependencies(classId)
descriptor ?: reportUnresolvedClass() descriptor ?: reportUnresolvedClass()
} }
@@ -94,11 +94,11 @@ internal class KClassImpl<T : Any>(override val jClass: Class<T>) : KDeclaration
} }
val nestedClasses: Collection<KClass<*>> by ReflectProperties.lazySoft { val nestedClasses: Collection<KClass<*>> by ReflectProperties.lazySoft {
descriptor.unsubstitutedInnerClassesScope.getContributedDescriptors().filterNot(DescriptorUtils::isEnumEntry).mapNotNull { descriptor.unsubstitutedInnerClassesScope.getContributedDescriptors().filterNot(DescriptorUtils::isEnumEntry)
nestedClass -> .mapNotNull { nestedClass ->
val jClass = (nestedClass as ClassDescriptor).toJavaClass() val jClass = (nestedClass as ClassDescriptor).toJavaClass()
jClass?.let { KClassImpl(it) } jClass?.let { KClassImpl(it) }
} }
} }
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
@@ -108,8 +108,7 @@ internal class KClassImpl<T : Any>(override val jClass: Class<T>) : KDeclaration
val field = if (descriptor.isCompanionObject && !CompanionObjectMapping.isMappedIntrinsicCompanionObject(descriptor)) { val field = if (descriptor.isCompanionObject && !CompanionObjectMapping.isMappedIntrinsicCompanionObject(descriptor)) {
jClass.enclosingClass.getDeclaredField(descriptor.name.asString()) jClass.enclosingClass.getDeclaredField(descriptor.name.asString())
} } else {
else {
jClass.getDeclaredField(JvmAbi.INSTANCE_FIELD) jClass.getDeclaredField(JvmAbi.INSTANCE_FIELD)
} }
field.get(null) as T field.get(null) as T
@@ -128,12 +127,11 @@ internal class KClassImpl<T : Any>(override val jClass: Class<T>) : KDeclaration
if (superClass !is ClassDescriptor) throw KotlinReflectionInternalError("Supertype not a class: $superClass") if (superClass !is ClassDescriptor) throw KotlinReflectionInternalError("Supertype not a class: $superClass")
val superJavaClass = superClass.toJavaClass() val superJavaClass = superClass.toJavaClass()
?: throw KotlinReflectionInternalError("Unsupported superclass of $this: $superClass") ?: throw KotlinReflectionInternalError("Unsupported superclass of $this: $superClass")
if (jClass.superclass == superJavaClass) { if (jClass.superclass == superJavaClass) {
jClass.genericSuperclass jClass.genericSuperclass
} } else {
else {
val index = jClass.interfaces.indexOf(superJavaClass) val index = jClass.interfaces.indexOf(superJavaClass)
if (index < 0) throw KotlinReflectionInternalError("No superclass of $this in Java reflection for $superClass") if (index < 0) throw KotlinReflectionInternalError("No superclass of $this in Java reflection for $superClass")
jClass.genericInterfaces[index] jClass.genericInterfaces[index]
@@ -151,11 +149,11 @@ internal class KClassImpl<T : Any>(override val jClass: Class<T>) : KDeclaration
val declaredNonStaticMembers: Collection<KCallableImpl<*>> val declaredNonStaticMembers: Collection<KCallableImpl<*>>
by ReflectProperties.lazySoft { getMembers(memberScope, DECLARED) } by ReflectProperties.lazySoft { getMembers(memberScope, DECLARED) }
val declaredStaticMembers: Collection<KCallableImpl<*>> private val declaredStaticMembers: Collection<KCallableImpl<*>>
by ReflectProperties.lazySoft { getMembers(staticScope, DECLARED) } by ReflectProperties.lazySoft { getMembers(staticScope, DECLARED) }
val inheritedNonStaticMembers: Collection<KCallableImpl<*>> private val inheritedNonStaticMembers: Collection<KCallableImpl<*>>
by ReflectProperties.lazySoft { getMembers(memberScope, INHERITED) } by ReflectProperties.lazySoft { getMembers(memberScope, INHERITED) }
val inheritedStaticMembers: Collection<KCallableImpl<*>> private val inheritedStaticMembers: Collection<KCallableImpl<*>>
by ReflectProperties.lazySoft { getMembers(staticScope, INHERITED) } by ReflectProperties.lazySoft { getMembers(staticScope, INHERITED) }
val allNonStaticMembers: Collection<KCallableImpl<*>> val allNonStaticMembers: Collection<KCallableImpl<*>>
@@ -192,12 +190,12 @@ internal class KClassImpl<T : Any>(override val jClass: Class<T>) : KDeclaration
} }
override fun getProperties(name: Name): Collection<PropertyDescriptor> = override fun getProperties(name: Name): Collection<PropertyDescriptor> =
(memberScope.getContributedVariables(name, NoLookupLocation.FROM_REFLECTION) + (memberScope.getContributedVariables(name, NoLookupLocation.FROM_REFLECTION) +
staticScope.getContributedVariables(name, NoLookupLocation.FROM_REFLECTION)) staticScope.getContributedVariables(name, NoLookupLocation.FROM_REFLECTION))
override fun getFunctions(name: Name): Collection<FunctionDescriptor> = override fun getFunctions(name: Name): Collection<FunctionDescriptor> =
memberScope.getContributedFunctions(name, NoLookupLocation.FROM_REFLECTION) + memberScope.getContributedFunctions(name, NoLookupLocation.FROM_REFLECTION) +
staticScope.getContributedFunctions(name, NoLookupLocation.FROM_REFLECTION) staticScope.getContributedFunctions(name, NoLookupLocation.FROM_REFLECTION)
override fun getLocalProperty(index: Int): PropertyDescriptor? { override fun getLocalProperty(index: Int): PropertyDescriptor? {
// TODO: also check that this is a synthetic class (Metadata.k == 3) // TODO: also check that this is a synthetic class (Metadata.k == 3)
@@ -263,10 +261,10 @@ internal class KClassImpl<T : Any>(override val jClass: Class<T>) : KDeclaration
get() = descriptor.isCompanionObject get() = descriptor.isCompanionObject
override fun equals(other: Any?): Boolean = override fun equals(other: Any?): Boolean =
other is KClassImpl<*> && javaObjectType == other.javaObjectType other is KClassImpl<*> && javaObjectType == other.javaObjectType
override fun hashCode(): Int = override fun hashCode(): Int =
javaObjectType.hashCode() javaObjectType.hashCode()
override fun toString(): String { override fun toString(): String {
return "class " + classId.let { classId -> return "class " + classId.let { classId ->
@@ -282,15 +280,15 @@ internal class KClassImpl<T : Any>(override val jClass: Class<T>) : KDeclaration
when (kind) { when (kind) {
KotlinClassHeader.Kind.FILE_FACADE, KotlinClassHeader.Kind.MULTIFILE_CLASS, KotlinClassHeader.Kind.MULTIFILE_CLASS_PART -> { KotlinClassHeader.Kind.FILE_FACADE, KotlinClassHeader.Kind.MULTIFILE_CLASS, KotlinClassHeader.Kind.MULTIFILE_CLASS_PART -> {
throw UnsupportedOperationException( throw UnsupportedOperationException(
"Packages and file facades are not yet supported in Kotlin reflection. " + "Packages and file facades are not yet supported in Kotlin reflection. " +
"Meanwhile please use Java reflection to inspect this class: $jClass" "Meanwhile please use Java reflection to inspect this class: $jClass"
) )
} }
KotlinClassHeader.Kind.SYNTHETIC_CLASS -> { KotlinClassHeader.Kind.SYNTHETIC_CLASS -> {
throw UnsupportedOperationException( throw UnsupportedOperationException(
"This class is an internal synthetic class generated by the Kotlin compiler, such as an anonymous class " + "This class is an internal synthetic class generated by the Kotlin compiler, such as an anonymous class " +
"for a lambda, a SAM wrapper, a callable reference, etc. It's not a Kotlin class or interface, so the reflection " + "for a lambda, a SAM wrapper, a callable reference, etc. It's not a Kotlin class or interface, so the reflection " +
"library has no idea what declarations does it have. Please use Java reflection to inspect this class: $jClass" "library has no idea what declarations does it have. Please use Java reflection to inspect this class: $jClass"
) )
} }
KotlinClassHeader.Kind.UNKNOWN -> { KotlinClassHeader.Kind.UNKNOWN -> {
@@ -50,21 +50,20 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
protected fun getMembers(scope: MemberScope, belonginess: MemberBelonginess): Collection<KCallableImpl<*>> { protected fun getMembers(scope: MemberScope, belonginess: MemberBelonginess): Collection<KCallableImpl<*>> {
val visitor = object : DeclarationDescriptorVisitorEmptyBodies<KCallableImpl<*>, Unit>() { val visitor = object : DeclarationDescriptorVisitorEmptyBodies<KCallableImpl<*>, Unit>() {
override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, data: Unit): KCallableImpl<*> = override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, data: Unit): KCallableImpl<*> =
createProperty(descriptor) createProperty(descriptor)
override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, data: Unit): KCallableImpl<*> = override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, data: Unit): KCallableImpl<*> =
KFunctionImpl(this@KDeclarationContainerImpl, descriptor) KFunctionImpl(this@KDeclarationContainerImpl, descriptor)
override fun visitConstructorDescriptor(descriptor: ConstructorDescriptor, data: Unit): KCallableImpl<*> = override fun visitConstructorDescriptor(descriptor: ConstructorDescriptor, data: Unit): KCallableImpl<*> =
throw IllegalStateException("No constructors should appear in this scope: $descriptor") throw IllegalStateException("No constructors should appear in this scope: $descriptor")
} }
return scope.getContributedDescriptors().mapNotNull { descriptor -> return scope.getContributedDescriptors().mapNotNull { descriptor ->
if (descriptor is CallableMemberDescriptor && if (descriptor is CallableMemberDescriptor &&
descriptor.visibility != Visibilities.INVISIBLE_FAKE && descriptor.visibility != Visibilities.INVISIBLE_FAKE &&
belonginess.accept(descriptor)) belonginess.accept(descriptor)
descriptor.accept(visitor, Unit) ) descriptor.accept(visitor, Unit) else null
else null
}.toList() }.toList()
} }
@@ -73,12 +72,12 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
INHERITED; INHERITED;
fun accept(member: CallableMemberDescriptor): Boolean = fun accept(member: CallableMemberDescriptor): Boolean =
member.kind.isReal == (this == DECLARED) member.kind.isReal == (this == DECLARED)
} }
private fun createProperty(descriptor: PropertyDescriptor): KPropertyImpl<*> { private fun createProperty(descriptor: PropertyDescriptor): KPropertyImpl<*> {
val receiverCount = (descriptor.dispatchReceiverParameter?.let { 1 } ?: 0) + val receiverCount = (descriptor.dispatchReceiverParameter?.let { 1 } ?: 0) +
(descriptor.extensionReceiverParameter?.let { 1 } ?: 0) (descriptor.extensionReceiverParameter?.let { 1 } ?: 0)
when { when {
descriptor.isVar -> when (receiverCount) { descriptor.isVar -> when (receiverCount) {
@@ -101,13 +100,13 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
if (match != null) { if (match != null) {
val (number) = match.destructured val (number) = match.destructured
return getLocalProperty(number.toInt()) return getLocalProperty(number.toInt())
?: throw KotlinReflectionInternalError("Local property #$number not found in $jClass") ?: throw KotlinReflectionInternalError("Local property #$number not found in $jClass")
} }
val properties = getProperties(Name.identifier(name)) val properties = getProperties(Name.identifier(name))
.filter { descriptor -> .filter { descriptor ->
RuntimeTypeMapper.mapPropertySignature(descriptor).asString() == signature RuntimeTypeMapper.mapPropertySignature(descriptor).asString() == signature
} }
if (properties.isEmpty()) { if (properties.isEmpty()) {
throw KotlinReflectionInternalError("Property '$name' (JVM signature: $signature) not resolved in $this") throw KotlinReflectionInternalError("Property '$name' (JVM signature: $signature) not resolved in $this")
@@ -125,16 +124,16 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
// TODO: consider writing additional info (besides signature) to property reference objects to distinguish them in this case // TODO: consider writing additional info (besides signature) to property reference objects to distinguish them in this case
val mostVisibleProperties = properties val mostVisibleProperties = properties
.groupBy { it.visibility } .groupBy { it.visibility }
.toSortedMap(Comparator { first, second -> .toSortedMap(Comparator { first, second ->
Visibilities.compare(first, second) ?: 0 Visibilities.compare(first, second) ?: 0
}).values.last() }).values.last()
if (mostVisibleProperties.size == 1) { if (mostVisibleProperties.size == 1) {
return mostVisibleProperties.first() return mostVisibleProperties.first()
} }
throw KotlinReflectionInternalError( throw KotlinReflectionInternalError(
"${properties.size} properties '$name' (JVM signature: $signature) resolved in $this: $properties" "${properties.size} properties '$name' (JVM signature: $signature) resolved in $this: $properties"
) )
} }
@@ -143,15 +142,15 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
fun findFunctionDescriptor(name: String, signature: String): FunctionDescriptor { fun findFunctionDescriptor(name: String, signature: String): FunctionDescriptor {
val functions = (if (name == "<init>") constructorDescriptors.toList() else getFunctions(Name.identifier(name))) val functions = (if (name == "<init>") constructorDescriptors.toList() else getFunctions(Name.identifier(name)))
.filter { descriptor -> .filter { descriptor ->
RuntimeTypeMapper.mapSignature(descriptor).asString() == signature RuntimeTypeMapper.mapSignature(descriptor).asString() == signature
} }
if (functions.size != 1) { if (functions.size != 1) {
val debugText = "'$name' (JVM signature: $signature)" val debugText = "'$name' (JVM signature: $signature)"
throw KotlinReflectionInternalError( throw KotlinReflectionInternalError(
if (functions.isEmpty()) "Function $debugText not resolved in $this" if (functions.isEmpty()) "Function $debugText not resolved in $this"
else "${functions.size} functions $debugText resolved in $this: $functions" else "${functions.size} functions $debugText resolved in $this: $functions"
) )
} }
@@ -178,35 +177,33 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
} }
private fun Class<*>.tryGetMethod(name: String, parameterTypes: Array<Class<*>>, returnType: Class<*>, declared: Boolean): Method? = private fun Class<*>.tryGetMethod(name: String, parameterTypes: Array<Class<*>>, returnType: Class<*>, declared: Boolean): Method? =
try { try {
val result = if (declared) getDeclaredMethod(name, *parameterTypes) else getMethod(name, *parameterTypes) val result = if (declared) getDeclaredMethod(name, *parameterTypes) else getMethod(name, *parameterTypes)
if (result.returnType == returnType) result if (result.returnType == returnType) result
else { else {
// If we've found a method with an unexpected return type, it's likely that there are several methods in this class // If we've found a method with an unexpected return type, it's likely that there are several methods in this class
// with the given parameter types and Java reflection API has returned not the one we're looking for. // with the given parameter types and Java reflection API has returned not the one we're looking for.
// Falling back to enumerating all methods in the class in this (rather rare) case. // Falling back to enumerating all methods in the class in this (rather rare) case.
// Example: class A(val x: Int) { fun getX(): String = ... } // Example: class A(val x: Int) { fun getX(): String = ... }
val allMethods = if (declared) declaredMethods else methods val allMethods = if (declared) declaredMethods else methods
allMethods.firstOrNull { method -> allMethods.firstOrNull { method ->
method.name == name && method.name == name &&
method.returnType == returnType && method.returnType == returnType &&
method.parameterTypes.contentEquals(parameterTypes) method.parameterTypes!!.contentEquals(parameterTypes)
}
} }
} }
catch (e: NoSuchMethodException) { } catch (e: NoSuchMethodException) {
null null
} }
private fun Class<*>.tryGetConstructor(parameterTypes: List<Class<*>>, declared: Boolean): Constructor<*>? = private fun Class<*>.tryGetConstructor(parameterTypes: List<Class<*>>, declared: Boolean): Constructor<*>? =
try { try {
if (declared) getDeclaredConstructor(*parameterTypes.toTypedArray()) if (declared) getDeclaredConstructor(*parameterTypes.toTypedArray())
else getConstructor(*parameterTypes.toTypedArray()) else getConstructor(*parameterTypes.toTypedArray())
} } catch (e: NoSuchMethodException) {
catch (e: NoSuchMethodException) { null
null }
}
fun findMethodBySignature(name: String, desc: String, isPublic: Boolean): Method? { fun findMethodBySignature(name: String, desc: String, isPublic: Boolean): Method? {
if (name == "<init>") return null if (name == "<init>") return null
@@ -267,23 +264,23 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
} }
private fun parseType(desc: String, begin: Int, end: Int): Class<*> = private fun parseType(desc: String, begin: Int, end: Int): Class<*> =
when (desc[begin]) { when (desc[begin]) {
'L' -> jClass.safeClassLoader.loadClass(desc.substring(begin + 1, end - 1).replace('/', '.')) 'L' -> jClass.safeClassLoader.loadClass(desc.substring(begin + 1, end - 1).replace('/', '.'))
'[' -> parseType(desc, begin + 1, end).createArrayType() '[' -> parseType(desc, begin + 1, end).createArrayType()
'V' -> Void.TYPE 'V' -> Void.TYPE
'Z' -> Boolean::class.java 'Z' -> Boolean::class.java
'C' -> Char::class.java 'C' -> Char::class.java
'B' -> Byte::class.java 'B' -> Byte::class.java
'S' -> Short::class.java 'S' -> Short::class.java
'I' -> Int::class.java 'I' -> Int::class.java
'F' -> Float::class.java 'F' -> Float::class.java
'J' -> Long::class.java 'J' -> Long::class.java
'D' -> Double::class.java 'D' -> Double::class.java
else -> throw KotlinReflectionInternalError("Unknown type prefix in the method signature: $desc") else -> throw KotlinReflectionInternalError("Unknown type prefix in the method signature: $desc")
} }
private fun loadReturnType(desc: String): Class<*> = private fun loadReturnType(desc: String): Class<*> =
parseType(desc, desc.indexOf(')') + 1, desc.length) parseType(desc, desc.indexOf(')') + 1, desc.length)
companion object { companion object {
private val DEFAULT_CONSTRUCTOR_MARKER = Class.forName("kotlin.jvm.internal.DefaultConstructorMarker") private val DEFAULT_CONSTRUCTOR_MARKER = Class.forName("kotlin.jvm.internal.DefaultConstructorMarker")
@@ -32,20 +32,20 @@ import kotlin.reflect.jvm.internal.AnnotationConstructorCaller.Origin.KOTLIN
import kotlin.reflect.jvm.internal.JvmFunctionSignature.* import kotlin.reflect.jvm.internal.JvmFunctionSignature.*
internal class KFunctionImpl private constructor( internal class KFunctionImpl private constructor(
override val container: KDeclarationContainerImpl, override val container: KDeclarationContainerImpl,
name: String, name: String,
private val signature: String, private val signature: String,
descriptorInitialValue: FunctionDescriptor?, descriptorInitialValue: FunctionDescriptor?,
private val boundReceiver: Any? = CallableReference.NO_RECEIVER private val boundReceiver: Any? = CallableReference.NO_RECEIVER
) : KCallableImpl<Any?>(), KFunction<Any?>, FunctionBase, FunctionWithAllInvokes { ) : KCallableImpl<Any?>(), KFunction<Any?>, FunctionBase, FunctionWithAllInvokes {
constructor(container: KDeclarationContainerImpl, name: String, signature: String, boundReceiver: Any?) constructor(container: KDeclarationContainerImpl, name: String, signature: String, boundReceiver: Any?)
: this(container, name, signature, null, boundReceiver) : this(container, name, signature, null, boundReceiver)
constructor(container: KDeclarationContainerImpl, descriptor: FunctionDescriptor) : this( constructor(container: KDeclarationContainerImpl, descriptor: FunctionDescriptor) : this(
container, container,
descriptor.name.asString(), descriptor.name.asString(),
RuntimeTypeMapper.mapSignature(descriptor).asString(), RuntimeTypeMapper.mapSignature(descriptor).asString(),
descriptor descriptor
) )
override val isBound: Boolean get() = boundReceiver != CallableReference.NO_RECEIVER override val isBound: Boolean get() = boundReceiver != CallableReference.NO_RECEIVER
@@ -56,7 +56,7 @@ internal class KFunctionImpl private constructor(
override val name: String get() = descriptor.name.asString() override val name: String get() = descriptor.name.asString()
override val caller: FunctionCaller<*> by ReflectProperties.lazySoft caller@ { override val caller: FunctionCaller<*> by ReflectProperties.lazySoft caller@{
val jvmSignature = RuntimeTypeMapper.mapSignature(descriptor) val jvmSignature = RuntimeTypeMapper.mapSignature(descriptor)
val member: Member? = when (jvmSignature) { val member: Member? = when (jvmSignature) {
is KotlinConstructor -> { is KotlinConstructor -> {
@@ -90,12 +90,14 @@ internal class KFunctionImpl private constructor(
} }
} }
override val defaultCaller: FunctionCaller<*>? by ReflectProperties.lazySoft defaultCaller@ { override val defaultCaller: FunctionCaller<*>? by ReflectProperties.lazySoft defaultCaller@{
val jvmSignature = RuntimeTypeMapper.mapSignature(descriptor) val jvmSignature = RuntimeTypeMapper.mapSignature(descriptor)
val member: Member? = when (jvmSignature) { val member: Member? = when (jvmSignature) {
is KotlinFunction -> { is KotlinFunction -> {
container.findDefaultMethod(jvmSignature.methodName, jvmSignature.methodDesc, container.findDefaultMethod(
!Modifier.isStatic(caller.member!!.modifiers), descriptor.isPublicInBytecode) jvmSignature.methodName, jvmSignature.methodDesc,
!Modifier.isStatic(caller.member!!.modifiers), descriptor.isPublicInBytecode
)
} }
is KotlinConstructor -> { is KotlinConstructor -> {
if (isAnnotationConstructor) if (isAnnotationConstructor)
@@ -120,7 +122,7 @@ internal class KFunctionImpl private constructor(
// In objects, $default's signature does _not_ contain the additional object instance parameter, // In objects, $default's signature does _not_ contain the additional object instance parameter,
// as opposed to companion objects where the first parameter is the companion object instance. // as opposed to companion objects where the first parameter is the companion object instance.
descriptor.annotations.findAnnotation(JVM_STATIC) != null && descriptor.annotations.findAnnotation(JVM_STATIC) != null &&
!(descriptor.containingDeclaration as ClassDescriptor).isCompanionObject -> !(descriptor.containingDeclaration as ClassDescriptor).isCompanionObject ->
createJvmStaticInObjectCaller(member) createJvmStaticInObjectCaller(member)
else -> else ->
@@ -131,16 +133,16 @@ internal class KFunctionImpl private constructor(
} }
private fun createStaticMethodCaller(member: Method) = private fun createStaticMethodCaller(member: Method) =
if (isBound) FunctionCaller.BoundStaticMethod(member, boundReceiver) else FunctionCaller.StaticMethod(member) if (isBound) FunctionCaller.BoundStaticMethod(member, boundReceiver) else FunctionCaller.StaticMethod(member)
private fun createJvmStaticInObjectCaller(member: Method) = private fun createJvmStaticInObjectCaller(member: Method) =
if (isBound) FunctionCaller.BoundJvmStaticInObject(member) else FunctionCaller.JvmStaticInObject(member) if (isBound) FunctionCaller.BoundJvmStaticInObject(member) else FunctionCaller.JvmStaticInObject(member)
private fun createInstanceMethodCaller(member: Method) = private fun createInstanceMethodCaller(member: Method) =
if (isBound) FunctionCaller.BoundInstanceMethod(member, boundReceiver) else FunctionCaller.InstanceMethod(member) if (isBound) FunctionCaller.BoundInstanceMethod(member, boundReceiver) else FunctionCaller.InstanceMethod(member)
private fun createConstructorCaller(member: Constructor<*>) = private fun createConstructorCaller(member: Constructor<*>) =
if (isBound) FunctionCaller.BoundConstructor(member, boundReceiver) else FunctionCaller.Constructor(member) if (isBound) FunctionCaller.BoundConstructor(member, boundReceiver) else FunctionCaller.Constructor(member)
override fun getArity() = caller.arity override fun getArity() = caller.arity
@@ -165,8 +167,8 @@ internal class KFunctionImpl private constructor(
} }
override fun hashCode(): Int = override fun hashCode(): Int =
(container.hashCode() * 31 + name.hashCode()) * 31 + signature.hashCode() (container.hashCode() * 31 + name.hashCode()) * 31 + signature.hashCode()
override fun toString(): String = override fun toString(): String =
ReflectionObjectRenderer.renderFunction(descriptor) ReflectionObjectRenderer.renderFunction(descriptor)
} }
@@ -36,8 +36,8 @@ import kotlin.reflect.jvm.internal.components.ReflectKotlinClass
import kotlin.reflect.jvm.internal.structure.classId import kotlin.reflect.jvm.internal.structure.classId
internal class KPackageImpl( internal class KPackageImpl(
override val jClass: Class<*>, override val jClass: Class<*>,
@Suppress("unused") val usageModuleName: String? = null // may be useful for debug @Suppress("unused") val usageModuleName: String? = null // may be useful for debug
) : KDeclarationContainerImpl() { ) : KDeclarationContainerImpl() {
private inner class Data : KDeclarationContainerImpl.Data() { private inner class Data : KDeclarationContainerImpl.Data() {
private val kotlinClass: ReflectKotlinClass? by ReflectProperties.lazySoft { private val kotlinClass: ReflectKotlinClass? by ReflectProperties.lazySoft {
@@ -58,8 +58,7 @@ internal class KPackageImpl(
// The default value for 'xs' is empty string, as declared in kotlin.Metadata // The default value for 'xs' is empty string, as declared in kotlin.Metadata
if (facadeName != null && facadeName.isNotEmpty()) { if (facadeName != null && facadeName.isNotEmpty()) {
jClass.classLoader.loadClass(facadeName.replace('/', '.')) jClass.classLoader.loadClass(facadeName.replace('/', '.'))
} } else {
else {
jClass jClass
} }
} }
@@ -70,8 +69,7 @@ internal class KPackageImpl(
val strings = header.strings val strings = header.strings
if (data != null && strings != null) { if (data != null && strings != null) {
JvmProtoBufUtil.readPackageDataFrom(data, strings) JvmProtoBufUtil.readPackageDataFrom(data, strings)
} } else null
else null
} }
} }
@@ -97,10 +95,10 @@ internal class KPackageImpl(
get() = emptyList() get() = emptyList()
override fun getProperties(name: Name): Collection<PropertyDescriptor> = override fun getProperties(name: Name): Collection<PropertyDescriptor> =
scope.getContributedVariables(name, NoLookupLocation.FROM_REFLECTION) scope.getContributedVariables(name, NoLookupLocation.FROM_REFLECTION)
override fun getFunctions(name: Name): Collection<FunctionDescriptor> = override fun getFunctions(name: Name): Collection<FunctionDescriptor> =
scope.getContributedFunctions(name, NoLookupLocation.FROM_REFLECTION) scope.getContributedFunctions(name, NoLookupLocation.FROM_REFLECTION)
override fun getLocalProperty(index: Int): PropertyDescriptor? { override fun getLocalProperty(index: Int): PropertyDescriptor? {
return data().metadata?.let { (nameResolver, packageProto) -> return data().metadata?.let { (nameResolver, packageProto) ->
@@ -111,10 +109,10 @@ internal class KPackageImpl(
} }
override fun equals(other: Any?): Boolean = override fun equals(other: Any?): Boolean =
other is KPackageImpl && jClass == other.jClass other is KPackageImpl && jClass == other.jClass
override fun hashCode(): Int = override fun hashCode(): Int =
jClass.hashCode() jClass.hashCode()
override fun toString(): String { override fun toString(): String {
val fqName = jClass.classId.packageFqName val fqName = jClass.classId.packageFqName
@@ -23,21 +23,22 @@ import kotlin.reflect.KParameter
import kotlin.reflect.KType import kotlin.reflect.KType
internal class KParameterImpl( internal class KParameterImpl(
val callable: KCallableImpl<*>, val callable: KCallableImpl<*>,
override val index: Int, override val index: Int,
override val kind: KParameter.Kind, override val kind: KParameter.Kind,
computeDescriptor: () -> ParameterDescriptor computeDescriptor: () -> ParameterDescriptor
) : KParameter { ) : KParameter {
private val descriptor: ParameterDescriptor by ReflectProperties.lazySoft(computeDescriptor) private val descriptor: ParameterDescriptor by ReflectProperties.lazySoft(computeDescriptor)
override val annotations: List<Annotation> by ReflectProperties.lazySoft { descriptor.computeAnnotations() } override val annotations: List<Annotation> by ReflectProperties.lazySoft { descriptor.computeAnnotations() }
override val name: String? get() { override val name: String?
val valueParameter = descriptor as? ValueParameterDescriptor ?: return null get() {
if (valueParameter.containingDeclaration.hasSynthesizedParameterNames()) return null val valueParameter = descriptor as? ValueParameterDescriptor ?: return null
val name = valueParameter.name if (valueParameter.containingDeclaration.hasSynthesizedParameterNames()) return null
return if (name.isSpecial) null else name.asString() val name = valueParameter.name
} return if (name.isSpecial) null else name.asString()
}
override val type: KType override val type: KType
get() = KTypeImpl(descriptor.type) { callable.caller.parameterTypes[index] } get() = KTypeImpl(descriptor.type) { callable.caller.parameterTypes[index] }
@@ -49,11 +50,11 @@ internal class KParameterImpl(
get() = descriptor.let { it is ValueParameterDescriptor && it.varargElementType != null } get() = descriptor.let { it is ValueParameterDescriptor && it.varargElementType != null }
override fun equals(other: Any?) = override fun equals(other: Any?) =
other is KParameterImpl && callable == other.callable && descriptor == other.descriptor other is KParameterImpl && callable == other.callable && descriptor == other.descriptor
override fun hashCode() = override fun hashCode() =
(callable.hashCode() * 31) + descriptor.hashCode() (callable.hashCode() * 31) + descriptor.hashCode()
override fun toString() = override fun toString() =
ReflectionObjectRenderer.renderParameter(this) ReflectionObjectRenderer.renderParameter(this)
} }
@@ -24,11 +24,13 @@ import kotlin.reflect.KProperty0
internal open class KProperty0Impl<out R> : KProperty0<R>, KPropertyImpl<R> { internal open class KProperty0Impl<out R> : KProperty0<R>, KPropertyImpl<R> {
constructor(container: KDeclarationContainerImpl, descriptor: PropertyDescriptor) : super(container, descriptor) constructor(container: KDeclarationContainerImpl, descriptor: PropertyDescriptor) : super(container, descriptor)
constructor(container: KDeclarationContainerImpl, name: String, signature: String, boundReceiver: Any?) : super(container, name, signature, boundReceiver) constructor(container: KDeclarationContainerImpl, name: String, signature: String, boundReceiver: Any?) : super(
container, name, signature, boundReceiver
)
private val getter_ = ReflectProperties.lazy { Getter(this) } private val _getter = ReflectProperties.lazy { Getter(this) }
override val getter: Getter<R> get() = getter_() override val getter: Getter<R> get() = _getter()
override fun get(): R = getter.call() override fun get(): R = getter.call()
@@ -46,11 +48,13 @@ internal open class KProperty0Impl<out R> : KProperty0<R>, KPropertyImpl<R> {
internal class KMutableProperty0Impl<R> : KProperty0Impl<R>, KMutableProperty0<R> { internal class KMutableProperty0Impl<R> : KProperty0Impl<R>, KMutableProperty0<R> {
constructor(container: KDeclarationContainerImpl, descriptor: PropertyDescriptor) : super(container, descriptor) constructor(container: KDeclarationContainerImpl, descriptor: PropertyDescriptor) : super(container, descriptor)
constructor(container: KDeclarationContainerImpl, name: String, signature: String, boundReceiver: Any?) : super(container, name, signature, boundReceiver) constructor(container: KDeclarationContainerImpl, name: String, signature: String, boundReceiver: Any?) : super(
container, name, signature, boundReceiver
)
private val setter_ = ReflectProperties.lazy { Setter(this) } private val _setter = ReflectProperties.lazy { Setter(this) }
override val setter: Setter<R> get() = setter_() override val setter: Setter<R> get() = _setter()
override fun set(value: R) = setter.call(value) override fun set(value: R) = setter.call(value)
@@ -22,13 +22,15 @@ import kotlin.reflect.KMutableProperty1
import kotlin.reflect.KProperty1 import kotlin.reflect.KProperty1
internal open class KProperty1Impl<T, out R> : KProperty1<T, R>, KPropertyImpl<R> { internal open class KProperty1Impl<T, out R> : KProperty1<T, R>, KPropertyImpl<R> {
constructor(container: KDeclarationContainerImpl, name: String, signature: String, boundReceiver: Any?) : super(container, name, signature, boundReceiver) constructor(container: KDeclarationContainerImpl, name: String, signature: String, boundReceiver: Any?) : super(
container, name, signature, boundReceiver
)
constructor(container: KDeclarationContainerImpl, descriptor: PropertyDescriptor) : super(container, descriptor) constructor(container: KDeclarationContainerImpl, descriptor: PropertyDescriptor) : super(container, descriptor)
private val getter_ = ReflectProperties.lazy { Getter(this) } private val _getter = ReflectProperties.lazy { Getter(this) }
override val getter: Getter<T, R> get() = getter_() override val getter: Getter<T, R> get() = _getter()
override fun get(receiver: T): R = getter.call(receiver) override fun get(receiver: T): R = getter.call(receiver)
@@ -44,13 +46,15 @@ internal open class KProperty1Impl<T, out R> : KProperty1<T, R>, KPropertyImpl<R
} }
internal class KMutableProperty1Impl<T, R> : KProperty1Impl<T, R>, KMutableProperty1<T, R> { internal class KMutableProperty1Impl<T, R> : KProperty1Impl<T, R>, KMutableProperty1<T, R> {
constructor(container: KDeclarationContainerImpl, name: String, signature: String, boundReceiver: Any?) : super(container, name, signature, boundReceiver) constructor(container: KDeclarationContainerImpl, name: String, signature: String, boundReceiver: Any?) : super(
container, name, signature, boundReceiver
)
constructor(container: KDeclarationContainerImpl, descriptor: PropertyDescriptor) : super(container, descriptor) constructor(container: KDeclarationContainerImpl, descriptor: PropertyDescriptor) : super(container, descriptor)
private val setter_ = ReflectProperties.lazy { Setter(this) } private val _setter = ReflectProperties.lazy { Setter(this) }
override val setter: Setter<T, R> get() = setter_() override val setter: Setter<T, R> get() = _setter()
override fun set(receiver: T, value: R) = setter.call(receiver, value) override fun set(receiver: T, value: R) = setter.call(receiver, value)
@@ -23,13 +23,15 @@ import kotlin.reflect.KMutableProperty2
import kotlin.reflect.KProperty2 import kotlin.reflect.KProperty2
internal open class KProperty2Impl<D, E, out R> : KProperty2<D, E, R>, KPropertyImpl<R> { internal open class KProperty2Impl<D, E, out R> : KProperty2<D, E, R>, KPropertyImpl<R> {
constructor(container: KDeclarationContainerImpl, name: String, signature: String) : super(container, name, signature, CallableReference.NO_RECEIVER) constructor(container: KDeclarationContainerImpl, name: String, signature: String) : super(
container, name, signature, CallableReference.NO_RECEIVER
)
constructor(container: KDeclarationContainerImpl, descriptor: PropertyDescriptor) : super(container, descriptor) constructor(container: KDeclarationContainerImpl, descriptor: PropertyDescriptor) : super(container, descriptor)
private val getter_ = ReflectProperties.lazy { Getter(this) } private val _getter = ReflectProperties.lazy { Getter(this) }
override val getter: Getter<D, E, R> get() = getter_() override val getter: Getter<D, E, R> get() = _getter()
override fun get(receiver1: D, receiver2: E): R = getter.call(receiver1, receiver2) override fun get(receiver1: D, receiver2: E): R = getter.call(receiver1, receiver2)
@@ -49,13 +51,14 @@ internal class KMutableProperty2Impl<D, E, R> : KProperty2Impl<D, E, R>, KMutabl
constructor(container: KDeclarationContainerImpl, descriptor: PropertyDescriptor) : super(container, descriptor) constructor(container: KDeclarationContainerImpl, descriptor: PropertyDescriptor) : super(container, descriptor)
private val setter_ = ReflectProperties.lazy { Setter(this) } private val _setter = ReflectProperties.lazy { Setter(this) }
override val setter: Setter<D, E, R> get() = setter_() override val setter: Setter<D, E, R> get() = _setter()
override fun set(receiver1: D, receiver2: E, value: R) = setter.call(receiver1, receiver2, value) override fun set(receiver1: D, receiver2: E, value: R) = setter.call(receiver1, receiver2, value)
class Setter<D, E, R>(override val property: KMutableProperty2Impl<D, E, R>) : KPropertyImpl.Setter<R>(), KMutableProperty2.Setter<D, E, R> { class Setter<D, E, R>(override val property: KMutableProperty2Impl<D, E, R>) : KPropertyImpl.Setter<R>(),
KMutableProperty2.Setter<D, E, R> {
override fun invoke(receiver1: D, receiver2: E, value: R): Unit = property.set(receiver1, receiver2, value) override fun invoke(receiver1: D, receiver2: E, value: R): Unit = property.set(receiver1, receiver2, value)
} }
} }
@@ -33,27 +33,27 @@ import kotlin.reflect.full.IllegalPropertyDelegateAccessException
import kotlin.reflect.jvm.internal.JvmPropertySignature.* import kotlin.reflect.jvm.internal.JvmPropertySignature.*
internal abstract class KPropertyImpl<out R> private constructor( internal abstract class KPropertyImpl<out R> private constructor(
override val container: KDeclarationContainerImpl, override val container: KDeclarationContainerImpl,
override val name: String, override val name: String,
val signature: String, val signature: String,
descriptorInitialValue: PropertyDescriptor?, descriptorInitialValue: PropertyDescriptor?,
val boundReceiver: Any? val boundReceiver: Any?
) : KCallableImpl<R>(), KProperty<R> { ) : KCallableImpl<R>(), KProperty<R> {
constructor(container: KDeclarationContainerImpl, name: String, signature: String, boundReceiver: Any?) : this( constructor(container: KDeclarationContainerImpl, name: String, signature: String, boundReceiver: Any?) : this(
container, name, signature, null, boundReceiver container, name, signature, null, boundReceiver
) )
constructor(container: KDeclarationContainerImpl, descriptor: PropertyDescriptor) : this( constructor(container: KDeclarationContainerImpl, descriptor: PropertyDescriptor) : this(
container, container,
descriptor.name.asString(), descriptor.name.asString(),
RuntimeTypeMapper.mapPropertySignature(descriptor).asString(), RuntimeTypeMapper.mapPropertySignature(descriptor).asString(),
descriptor, descriptor,
CallableReference.NO_RECEIVER CallableReference.NO_RECEIVER
) )
override val isBound: Boolean get() = boundReceiver != CallableReference.NO_RECEIVER override val isBound: Boolean get() = boundReceiver != CallableReference.NO_RECEIVER
private val javaField_ = ReflectProperties.lazySoft { private val _javaField = ReflectProperties.lazySoft {
val jvmSignature = RuntimeTypeMapper.mapPropertySignature(descriptor) val jvmSignature = RuntimeTypeMapper.mapPropertySignature(descriptor)
when (jvmSignature) { when (jvmSignature) {
is KotlinProperty -> { is KotlinProperty -> {
@@ -61,16 +61,14 @@ internal abstract class KPropertyImpl<out R> private constructor(
JvmProtoBufUtil.getJvmFieldSignature(jvmSignature.proto, jvmSignature.nameResolver, jvmSignature.typeTable)?.let { JvmProtoBufUtil.getJvmFieldSignature(jvmSignature.proto, jvmSignature.nameResolver, jvmSignature.typeTable)?.let {
val owner = if (JvmAbi.isCompanionObjectWithBackingFieldsInOuter(descriptor.containingDeclaration)) { val owner = if (JvmAbi.isCompanionObjectWithBackingFieldsInOuter(descriptor.containingDeclaration)) {
container.jClass.enclosingClass container.jClass.enclosingClass
} } else descriptor.containingDeclaration.let { containingDeclaration ->
else descriptor.containingDeclaration.let { containingDeclaration ->
if (containingDeclaration is ClassDescriptor) containingDeclaration.toJavaClass() if (containingDeclaration is ClassDescriptor) containingDeclaration.toJavaClass()
else container.jClass else container.jClass
} }
try { try {
owner?.getDeclaredField(it.name) owner?.getDeclaredField(it.name)
} } catch (e: NoSuchFieldException) {
catch (e: NoSuchFieldException) {
null null
} }
} }
@@ -80,32 +78,33 @@ internal abstract class KPropertyImpl<out R> private constructor(
} }
} }
val javaField: Field? get() = javaField_() val javaField: Field? get() = _javaField()
protected fun computeDelegateField(): Field? = protected fun computeDelegateField(): Field? =
if (@Suppress("DEPRECATION") descriptor.isDelegated) javaField else null if (@Suppress("DEPRECATION") descriptor.isDelegated) javaField else null
protected fun getDelegate(field: Field?, receiver: Any?): Any? = protected fun getDelegate(field: Field?, receiver: Any?): Any? =
try { try {
if (receiver === EXTENSION_PROPERTY_DELEGATE) { if (receiver === EXTENSION_PROPERTY_DELEGATE) {
if (descriptor.extensionReceiverParameter == null) { if (descriptor.extensionReceiverParameter == null) {
throw RuntimeException("'$this' is not an extension property and thus getExtensionDelegate() " + throw RuntimeException(
"is not going to work, use getDelegate() instead") "'$this' is not an extension property and thus getExtensionDelegate() " +
} "is not going to work, use getDelegate() instead"
)
} }
field?.get(receiver)
}
catch (e: IllegalAccessException) {
throw IllegalPropertyDelegateAccessException(e)
} }
field?.get(receiver)
} catch (e: IllegalAccessException) {
throw IllegalPropertyDelegateAccessException(e)
}
override abstract val getter: Getter<R> abstract override val getter: Getter<R>
private val descriptor_ = ReflectProperties.lazySoft(descriptorInitialValue) { private val _descriptor = ReflectProperties.lazySoft(descriptorInitialValue) {
container.findPropertyDescriptor(name, signature) container.findPropertyDescriptor(name, signature)
} }
override val descriptor: PropertyDescriptor get() = descriptor_() override val descriptor: PropertyDescriptor get() = _descriptor()
override val caller: FunctionCaller<*> get() = getter.caller override val caller: FunctionCaller<*> get() = getter.caller
@@ -121,13 +120,13 @@ internal abstract class KPropertyImpl<out R> private constructor(
} }
override fun hashCode(): Int = override fun hashCode(): Int =
(container.hashCode() * 31 + name.hashCode()) * 31 + signature.hashCode() (container.hashCode() * 31 + name.hashCode()) * 31 + signature.hashCode()
override fun toString(): String = override fun toString(): String =
ReflectionObjectRenderer.renderProperty(descriptor) ReflectionObjectRenderer.renderProperty(descriptor)
abstract class Accessor<out PropertyType, out ReturnType> : abstract class Accessor<out PropertyType, out ReturnType> :
KCallableImpl<ReturnType>(), KProperty.Accessor<PropertyType>, KFunction<ReturnType> { KCallableImpl<ReturnType>(), KProperty.Accessor<PropertyType>, KFunction<ReturnType> {
abstract override val property: KPropertyImpl<PropertyType> abstract override val property: KPropertyImpl<PropertyType>
abstract override val descriptor: PropertyAccessorDescriptor abstract override val descriptor: PropertyAccessorDescriptor
@@ -185,14 +184,14 @@ private fun KPropertyImpl.Accessor<*, *>.computeCallerForAccessor(isGetter: Bool
fun isInsideClassCompanionObject(): Boolean { fun isInsideClassCompanionObject(): Boolean {
val possibleCompanionObject = property.descriptor.containingDeclaration val possibleCompanionObject = property.descriptor.containingDeclaration
return DescriptorUtils.isCompanionObject(possibleCompanionObject) && return DescriptorUtils.isCompanionObject(possibleCompanionObject) &&
!DescriptorUtils.isInterface(possibleCompanionObject.containingDeclaration) !DescriptorUtils.isInterface(possibleCompanionObject.containingDeclaration)
} }
fun isJvmStaticProperty() = fun isJvmStaticProperty() =
property.descriptor.annotations.findAnnotation(JVM_STATIC) != null property.descriptor.annotations.findAnnotation(JVM_STATIC) != null
fun isNotNullProperty() = fun isNotNullProperty() =
!TypeUtils.isNullableType(property.descriptor.type) !TypeUtils.isNullableType(property.descriptor.type)
fun computeFieldCaller(field: Field): FunctionCaller<Field> = when { fun computeFieldCaller(field: Field): FunctionCaller<Field> = when {
isInsideClassCompanionObject() -> { isInsideClassCompanionObject() -> {
@@ -235,16 +234,16 @@ private fun KPropertyImpl.Accessor<*, *>.computeCallerForAccessor(isGetter: Bool
val accessor = accessorSignature?.let { signature -> val accessor = accessorSignature?.let { signature ->
property.container.findMethodBySignature( property.container.findMethodBySignature(
jvmSignature.nameResolver.getString(signature.name), jvmSignature.nameResolver.getString(signature.name),
jvmSignature.nameResolver.getString(signature.desc), jvmSignature.nameResolver.getString(signature.desc),
descriptor.isPublicInBytecode descriptor.isPublicInBytecode
) )
} }
when { when {
accessor == null -> computeFieldCaller( accessor == null -> computeFieldCaller(
property.javaField property.javaField
?: throw KotlinReflectionInternalError("No accessors or field is found for property $property") ?: throw KotlinReflectionInternalError("No accessors or field is found for property $property")
) )
!Modifier.isStatic(accessor.modifiers) -> !Modifier.isStatic(accessor.modifiers) ->
if (isBound) FunctionCaller.BoundInstanceMethod(accessor, property.boundReceiver) if (isBound) FunctionCaller.BoundInstanceMethod(accessor, property.boundReceiver)
@@ -262,10 +261,10 @@ private fun KPropertyImpl.Accessor<*, *>.computeCallerForAccessor(isGetter: Bool
} }
is JavaMethodProperty -> { is JavaMethodProperty -> {
val method = val method =
if (isGetter) jvmSignature.getterMethod if (isGetter) jvmSignature.getterMethod
else jvmSignature.setterMethod ?: throw KotlinReflectionInternalError( else jvmSignature.setterMethod ?: throw KotlinReflectionInternalError(
"No source found for setter of Java method property: ${jvmSignature.getterMethod}" "No source found for setter of Java method property: ${jvmSignature.getterMethod}"
) )
if (isBound) FunctionCaller.BoundInstanceMethod(method, property.boundReceiver) if (isBound) FunctionCaller.BoundInstanceMethod(method, property.boundReceiver)
else FunctionCaller.InstanceMethod(method) else FunctionCaller.InstanceMethod(method)
} }
@@ -36,8 +36,8 @@ import kotlin.reflect.jvm.internal.structure.primitiveByWrapper
import kotlin.reflect.jvm.jvmErasure import kotlin.reflect.jvm.jvmErasure
internal class KTypeImpl( internal class KTypeImpl(
val type: KotlinType, val type: KotlinType,
computeJavaType: () -> Type computeJavaType: () -> Type
) : KType { ) : KType {
internal val javaType: Type by ReflectProperties.lazySoft(computeJavaType) internal val javaType: Type by ReflectProperties.lazySoft(computeJavaType)
@@ -52,8 +52,8 @@ internal class KTypeImpl(
// There may be no argument if it's a primitive array (such as IntArray) // There may be no argument if it's a primitive array (such as IntArray)
val argument = type.arguments.singleOrNull()?.type ?: return KClassImpl(jClass) val argument = type.arguments.singleOrNull()?.type ?: return KClassImpl(jClass)
val elementClassifier = val elementClassifier =
convert(argument) convert(argument)
?: throw KotlinReflectionInternalError("Cannot determine classifier for array element type: $this") ?: throw KotlinReflectionInternalError("Cannot determine classifier for array element type: $this")
return KClassImpl(elementClassifier.jvmErasure.java.createArrayType()) return KClassImpl(elementClassifier.jvmErasure.java.createArrayType())
} }
@@ -69,7 +69,7 @@ internal class KTypeImpl(
} }
} }
override val arguments: List<KTypeProjection> by ReflectProperties.lazySoft arguments@ { override val arguments: List<KTypeProjection> by ReflectProperties.lazySoft arguments@{
val typeArguments = type.arguments val typeArguments = type.arguments
if (typeArguments.isEmpty()) return@arguments emptyList<KTypeProjection>() if (typeArguments.isEmpty()) return@arguments emptyList<KTypeProjection>()
@@ -78,8 +78,7 @@ internal class KTypeImpl(
typeArguments.mapIndexed { i, typeProjection -> typeArguments.mapIndexed { i, typeProjection ->
if (typeProjection.isStarProjection) { if (typeProjection.isStarProjection) {
KTypeProjection.STAR KTypeProjection.STAR
} } else {
else {
val type = KTypeImpl(typeProjection.type) { val type = KTypeImpl(typeProjection.type) {
val javaType = javaType val javaType = javaType
when (javaType) { when (javaType) {
@@ -114,11 +113,11 @@ internal class KTypeImpl(
get() = type.isMarkedNullable get() = type.isMarkedNullable
override fun equals(other: Any?) = override fun equals(other: Any?) =
other is KTypeImpl && type == other.type other is KTypeImpl && type == other.type
override fun hashCode() = override fun hashCode() =
type.hashCode() type.hashCode()
override fun toString() = override fun toString() =
ReflectionObjectRenderer.renderType(type) ReflectionObjectRenderer.renderType(type)
} }
@@ -45,11 +45,11 @@ internal class KTypeParameterImpl(override val descriptor: TypeParameterDescript
get() = descriptor.isReified get() = descriptor.isReified
override fun equals(other: Any?) = override fun equals(other: Any?) =
other is KTypeParameterImpl && descriptor == other.descriptor other is KTypeParameterImpl && descriptor == other.descriptor
override fun hashCode() = override fun hashCode() =
descriptor.hashCode() descriptor.hashCode()
override fun toString() = override fun toString() =
ReflectionObjectRenderer.renderTypeParameter(descriptor) ReflectionObjectRenderer.renderTypeParameter(descriptor)
} }
@@ -21,7 +21,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.lang.ref.SoftReference; import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
public class ReflectProperties { public class ReflectProperties {
public static abstract class Val<T> { public static abstract class Val<T> {
@@ -97,33 +96,6 @@ public class ReflectProperties {
} }
} }
// A delegate for a lazy property on a weak reference, whose initializer may be invoked multiple times
// including simultaneously from different threads
public static class LazyWeakVal<T> extends Val<T> {
private final Function0<T> initializer;
private WeakReference<Object> value = null;
public LazyWeakVal(@NotNull Function0<T> initializer) {
this.initializer = initializer;
}
@Override
public T invoke() {
WeakReference<Object> cached = value;
if (cached != null) {
Object result = cached.get();
if (result != null) {
return unescape(result);
}
}
T result = initializer.invoke();
value = new WeakReference<Object>(escape(result));
return result;
}
}
@NotNull @NotNull
public static <T> LazyVal<T> lazy(@NotNull Function0<T> initializer) { public static <T> LazyVal<T> lazy(@NotNull Function0<T> initializer) {
return new LazyVal<T>(initializer); return new LazyVal<T>(initializer);
@@ -138,9 +110,4 @@ public class ReflectProperties {
public static <T> LazySoftVal<T> lazySoft(@NotNull Function0<T> initializer) { public static <T> LazySoftVal<T> lazySoft(@NotNull Function0<T> initializer) {
return lazySoft(null, initializer); return lazySoft(null, initializer);
} }
@NotNull
public static <T> LazyWeakVal<T> lazyWeak(@NotNull Function0<T> initializer) {
return new LazyWeakVal<T>(initializer);
}
} }
@@ -44,7 +44,7 @@ internal object ReflectionObjectRenderer {
if (addParentheses) append(")") if (addParentheses) append(")")
} }
fun renderCallable(descriptor: CallableDescriptor): String { private fun renderCallable(descriptor: CallableDescriptor): String {
return when (descriptor) { return when (descriptor) {
is PropertyDescriptor -> renderProperty(descriptor) is PropertyDescriptor -> renderProperty(descriptor)
is FunctionDescriptor -> renderFunction(descriptor) is FunctionDescriptor -> renderFunction(descriptor)
@@ -108,7 +108,8 @@ internal object ReflectionObjectRenderer {
fun renderTypeParameter(typeParameter: TypeParameterDescriptor): String { fun renderTypeParameter(typeParameter: TypeParameterDescriptor): String {
return buildString { return buildString {
when (typeParameter.variance) { when (typeParameter.variance) {
Variance.INVARIANT -> {} Variance.INVARIANT -> {
}
Variance.IN_VARIANCE -> append("in ") Variance.IN_VARIANCE -> append("in ")
Variance.OUT_VARIANCE -> append("out ") Variance.OUT_VARIANCE -> append("out ")
} }
@@ -76,7 +76,7 @@ internal sealed class JvmFunctionSignature {
class JavaConstructor(val constructor: Constructor<*>) : JvmFunctionSignature() { class JavaConstructor(val constructor: Constructor<*>) : JvmFunctionSignature() {
override fun asString(): String = override fun asString(): String =
constructor.parameterTypes.joinToString(separator = "", prefix = "<init>(", postfix = ")V") { it.desc } constructor.parameterTypes.joinToString(separator = "", prefix = "<init>(", postfix = ")V") { it.desc }
} }
class FakeJavaAnnotationConstructor(val jClass: Class<*>) : JvmFunctionSignature() { class FakeJavaAnnotationConstructor(val jClass: Class<*>) : JvmFunctionSignature() {
@@ -84,7 +84,7 @@ internal sealed class JvmFunctionSignature {
val methods = jClass.declaredMethods.sortedBy { it.name } val methods = jClass.declaredMethods.sortedBy { it.name }
override fun asString(): String = override fun asString(): String =
methods.joinToString(separator = "", prefix = "<init>(", postfix = ")V") { it.returnType.desc } methods.joinToString(separator = "", prefix = "<init>(", postfix = ")V") { it.returnType.desc }
} }
open class BuiltInFunction(private val signature: String) : JvmFunctionSignature() { open class BuiltInFunction(private val signature: String) : JvmFunctionSignature() {
@@ -92,7 +92,7 @@ internal sealed class JvmFunctionSignature {
override fun asString(): String = signature override fun asString(): String = signature
class Predefined(signature: String, private val member: Member): BuiltInFunction(signature) { class Predefined(signature: String, private val member: Member) : BuiltInFunction(signature) {
override fun getMember(container: KDeclarationContainerImpl): Member = member override fun getMember(container: KDeclarationContainerImpl): Member = member
} }
} }
@@ -106,19 +106,18 @@ internal sealed class JvmPropertySignature {
abstract fun asString(): String abstract fun asString(): String
class KotlinProperty( class KotlinProperty(
val descriptor: PropertyDescriptor, val descriptor: PropertyDescriptor,
val proto: ProtoBuf.Property, val proto: ProtoBuf.Property,
val signature: JvmProtoBuf.JvmPropertySignature, val signature: JvmProtoBuf.JvmPropertySignature,
val nameResolver: NameResolver, val nameResolver: NameResolver,
val typeTable: TypeTable val typeTable: TypeTable
) : JvmPropertySignature() { ) : JvmPropertySignature() {
private val string: String = if (signature.hasGetter()) { private val string: String = if (signature.hasGetter()) {
nameResolver.getString(signature.getter.name) + nameResolver.getString(signature.getter.desc) nameResolver.getString(signature.getter.name) + nameResolver.getString(signature.getter.desc)
} } else {
else {
val (name, desc) = val (name, desc) =
JvmProtoBufUtil.getJvmFieldSignature(proto, nameResolver, typeTable) ?: JvmProtoBufUtil.getJvmFieldSignature(proto, nameResolver, typeTable)
throw KotlinReflectionInternalError("No field signature for property: $descriptor") ?: throw KotlinReflectionInternalError("No field signature for property: $descriptor")
JvmAbi.getterName(name) + getManglingSuffix() + "()" + desc JvmAbi.getterName(name) + getManglingSuffix() + "()" + desc
} }
@@ -149,9 +148,7 @@ internal sealed class JvmPropertySignature {
class JavaField(val field: Field) : JvmPropertySignature() { class JavaField(val field: Field) : JvmPropertySignature() {
override fun asString(): String = override fun asString(): String =
JvmAbi.getterName(field.name) + JvmAbi.getterName(field.name) + "()" + field.type.desc
"()" +
field.type.desc
} }
} }
@@ -186,12 +183,13 @@ internal object RuntimeTypeMapper {
} }
} }
// If it's a deserialized function but has no JVM signature, it must be from built-ins // If it's a deserialized function but has no JVM signature, it must be from built-ins
throw KotlinReflectionInternalError("Reflection on built-in Kotlin types is not yet fully supported. " + throw KotlinReflectionInternalError(
"No metadata found for $function") "Reflection on built-in Kotlin types is not yet fully supported. No metadata found for $function"
)
} }
is JavaMethodDescriptor -> { is JavaMethodDescriptor -> {
val method = ((function.source as? JavaSourceElement)?.javaElement as? ReflectJavaMethod)?.member ?: val method = ((function.source as? JavaSourceElement)?.javaElement as? ReflectJavaMethod)?.member
throw KotlinReflectionInternalError("Incorrect resolution sequence for Java method $function") ?: throw KotlinReflectionInternalError("Incorrect resolution sequence for Java method $function")
return JvmFunctionSignature.JavaMethod(method) return JvmFunctionSignature.JavaMethod(method)
} }
@@ -226,8 +224,8 @@ internal object RuntimeTypeMapper {
when (element) { when (element) {
is ReflectJavaField -> JvmPropertySignature.JavaField(element.member) is ReflectJavaField -> JvmPropertySignature.JavaField(element.member)
is ReflectJavaMethod -> JvmPropertySignature.JavaMethodProperty( is ReflectJavaMethod -> JvmPropertySignature.JavaMethodProperty(
element.member, element.member,
((property.setter?.source as? JavaSourceElement)?.javaElement as? ReflectJavaMethod)?.member ((property.setter?.source as? JavaSourceElement)?.javaElement as? ReflectJavaMethod)?.member
) )
else -> throw KotlinReflectionInternalError("Incorrect resolution sequence for Java field $property (source = $element)") else -> throw KotlinReflectionInternalError("Incorrect resolution sequence for Java field $property (source = $element)")
} }
@@ -243,16 +241,22 @@ internal object RuntimeTypeMapper {
when (function.name.asString()) { when (function.name.asString()) {
"equals" -> if (parameters.size == 1 && KotlinBuiltIns.isNullableAny(parameters.single().type)) { "equals" -> if (parameters.size == 1 && KotlinBuiltIns.isNullableAny(parameters.single().type)) {
return JvmFunctionSignature.BuiltInFunction.Predefined("equals(Ljava/lang/Object;)Z", return JvmFunctionSignature.BuiltInFunction.Predefined(
Any::class.java.getDeclaredMethod("equals", Any::class.java)) "equals(Ljava/lang/Object;)Z",
Any::class.java.getDeclaredMethod("equals", Any::class.java)
)
} }
"hashCode" -> if (parameters.isEmpty()) { "hashCode" -> if (parameters.isEmpty()) {
return JvmFunctionSignature.BuiltInFunction.Predefined("hashCode()I", return JvmFunctionSignature.BuiltInFunction.Predefined(
Any::class.java.getDeclaredMethod("hashCode")) "hashCode()I",
Any::class.java.getDeclaredMethod("hashCode")
)
} }
"toString" -> if (parameters.isEmpty()) { "toString" -> if (parameters.isEmpty()) {
return JvmFunctionSignature.BuiltInFunction.Predefined("toString()Ljava/lang/String;", return JvmFunctionSignature.BuiltInFunction.Predefined(
Any::class.java.getDeclaredMethod("toString")) "toString()Ljava/lang/String;",
Any::class.java.getDeclaredMethod("toString")
)
} }
// TODO: generalize and support other functions from built-ins // TODO: generalize and support other functions from built-ins
} }
@@ -36,8 +36,7 @@ internal fun <T : Any> getOrCreateKotlinClass(jClass: Class<T>): KClassImpl<T> {
if (kClass?.jClass == jClass) { if (kClass?.jClass == jClass) {
return kClass return kClass
} }
} } else if (cached != null) {
else if (cached != null) {
// If the cached value is not a weak reference, it's an array of weak references // If the cached value is not a weak reference, it's an array of weak references
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
(cached as Array<WeakReference<KClassImpl<T>>>) (cached as Array<WeakReference<KClassImpl<T>>>)
@@ -35,13 +35,13 @@ private class WeakClassLoaderBox(classLoader: ClassLoader) {
var temporaryStrongRef: ClassLoader? = classLoader var temporaryStrongRef: ClassLoader? = classLoader
override fun equals(other: Any?) = override fun equals(other: Any?) =
other is WeakClassLoaderBox && ref.get() === other.ref.get() other is WeakClassLoaderBox && ref.get() === other.ref.get()
override fun hashCode() = override fun hashCode() =
identityHashCode identityHashCode
override fun toString() = override fun toString() =
ref.get()?.toString() ?: "<null>" ref.get()?.toString() ?: "<null>"
} }
internal fun Class<*>.getOrCreateModule(): RuntimeModuleData { internal fun Class<*>.getOrCreateModule(): RuntimeModuleData {
@@ -58,15 +58,13 @@ internal fun Class<*>.getOrCreateModule(): RuntimeModuleData {
val module = RuntimeModuleData.create(classLoader) val module = RuntimeModuleData.create(classLoader)
try { try {
while (true) { while (true) {
val ref = moduleByClassLoader.putIfAbsent(key, WeakReference(module)) val ref = moduleByClassLoader.putIfAbsent(key, WeakReference(module)) ?: return module
if (ref == null) return module
val result = ref.get() val result = ref.get()
if (result != null) return result if (result != null) return result
moduleByClassLoader.remove(key, ref) moduleByClassLoader.remove(key, ref)
} }
} } finally {
finally {
key.temporaryStrongRef = null key.temporaryStrongRef = null
} }
} }
@@ -91,43 +91,40 @@ internal fun loadClass(classLoader: ClassLoader, packageName: String, className:
} }
internal fun Visibility.toKVisibility(): KVisibility? = internal fun Visibility.toKVisibility(): KVisibility? =
when (this) { when (this) {
Visibilities.PUBLIC -> KVisibility.PUBLIC Visibilities.PUBLIC -> KVisibility.PUBLIC
Visibilities.PROTECTED -> KVisibility.PROTECTED Visibilities.PROTECTED -> KVisibility.PROTECTED
Visibilities.INTERNAL -> KVisibility.INTERNAL Visibilities.INTERNAL -> KVisibility.INTERNAL
Visibilities.PRIVATE, Visibilities.PRIVATE_TO_THIS -> KVisibility.PRIVATE Visibilities.PRIVATE, Visibilities.PRIVATE_TO_THIS -> KVisibility.PRIVATE
else -> null else -> null
} }
internal fun Annotated.computeAnnotations(): List<Annotation> = internal fun Annotated.computeAnnotations(): List<Annotation> =
annotations.mapNotNull { annotations.mapNotNull {
val source = it.source val source = it.source
when (source) { when (source) {
is ReflectAnnotationSource -> source.annotation is ReflectAnnotationSource -> source.annotation
is RuntimeSourceElementFactory.RuntimeSourceElement -> (source.javaElement as? ReflectJavaAnnotation)?.annotation is RuntimeSourceElementFactory.RuntimeSourceElement -> (source.javaElement as? ReflectJavaAnnotation)?.annotation
else -> null else -> null
}
} }
}
// TODO: wrap other exceptions // TODO: wrap other exceptions
internal inline fun <R> reflectionCall(block: () -> R): R = internal inline fun <R> reflectionCall(block: () -> R): R =
try { try {
block() block()
} } catch (e: IllegalAccessException) {
catch (e: IllegalAccessException) { throw IllegalCallableAccessException(e)
throw IllegalCallableAccessException(e) }
}
internal fun Any?.asKFunctionImpl(): KFunctionImpl? = internal fun Any?.asKFunctionImpl(): KFunctionImpl? =
this as? KFunctionImpl ?: this as? KFunctionImpl ?: (this as? FunctionReference)?.compute() as? KFunctionImpl
(this as? FunctionReference)?.compute() as? KFunctionImpl
internal fun Any?.asKPropertyImpl(): KPropertyImpl<*>? = internal fun Any?.asKPropertyImpl(): KPropertyImpl<*>? =
this as? KPropertyImpl<*> ?: this as? KPropertyImpl<*> ?: (this as? PropertyReference)?.compute() as? KPropertyImpl
(this as? PropertyReference)?.compute() as? KPropertyImpl
internal fun Any?.asKCallableImpl(): KCallableImpl<*>? = internal fun Any?.asKCallableImpl(): KCallableImpl<*>? =
this as? KCallableImpl<*> ?: asKFunctionImpl() ?: asKPropertyImpl() this as? KCallableImpl<*> ?: asKFunctionImpl() ?: asKPropertyImpl()
internal val ReflectKotlinClass.packageModuleName: String? internal val ReflectKotlinClass.packageModuleName: String?
get() { get() {
@@ -157,11 +154,11 @@ internal val CallableMemberDescriptor.isPublicInBytecode: Boolean
} }
internal fun <M : MessageLite, D : CallableDescriptor> deserializeToDescriptor( internal fun <M : MessageLite, D : CallableDescriptor> deserializeToDescriptor(
moduleAnchor: Class<*>, moduleAnchor: Class<*>,
proto: M, proto: M,
nameResolver: NameResolver, nameResolver: NameResolver,
typeTable: TypeTable, typeTable: TypeTable,
createDescriptor: MemberDeserializer.(M) -> D createDescriptor: MemberDeserializer.(M) -> D
): D? { ): D? {
val moduleData = moduleAnchor.getOrCreateModule() val moduleData = moduleAnchor.getOrCreateModule()
@@ -172,8 +169,8 @@ internal fun <M : MessageLite, D : CallableDescriptor> deserializeToDescriptor(
} }
val context = DeserializationContext( val context = DeserializationContext(
moduleData.deserialization, nameResolver, moduleData.module, typeTable, VersionRequirementTable.EMPTY, moduleData.deserialization, nameResolver, moduleData.module, typeTable, VersionRequirementTable.EMPTY,
containerSource = null, parentTypeDeserializer = null, typeParameters = typeParameters containerSource = null, parentTypeDeserializer = null, typeParameters = typeParameters
) )
return MemberDeserializer(context).createDescriptor(proto) return MemberDeserializer(context).createDescriptor(proto)
} }
@@ -37,7 +37,7 @@ fun <R> Function<R>.reflect(): KFunction<R>? {
val (nameResolver, proto) = JvmProtoBufUtil.readFunctionDataFrom(data, annotation.d2) val (nameResolver, proto) = JvmProtoBufUtil.readFunctionDataFrom(data, annotation.d2)
val descriptor = deserializeToDescriptor(javaClass, proto, nameResolver, TypeTable(proto.typeTable), MemberDeserializer::loadFunction) val descriptor = deserializeToDescriptor(javaClass, proto, nameResolver, TypeTable(proto.typeTable), MemberDeserializer::loadFunction)
?: return null ?: return null
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
return KFunctionImpl(EmptyContainerForLocal, descriptor) as KFunction<R> return KFunctionImpl(EmptyContainerForLocal, descriptor) as KFunction<R>