Improve implementation of callable reference superclasses
Previously to use reflection on them, you had to wrap an already created object with a "Reflection.function" or "Reflection.propertyN" call, which the JVM back-end was doing. This was not optimal in several senses and current solution fixes that
This commit is contained in:
@@ -22,7 +22,7 @@ import kotlin.reflect.KCallable
|
||||
import kotlin.reflect.KFunction
|
||||
import kotlin.reflect.KMutableProperty
|
||||
import kotlin.reflect.KProperty
|
||||
import kotlin.reflect.jvm.internal.KCallableImpl
|
||||
import kotlin.reflect.jvm.internal.asKCallableImpl
|
||||
|
||||
/**
|
||||
* Provides a way to suppress JVM access checks for a callable.
|
||||
@@ -53,7 +53,7 @@ public var KCallable<*>.isAccessible: Boolean
|
||||
javaMethod?.isAccessible ?: true
|
||||
is KFunction ->
|
||||
javaMethod?.isAccessible ?: true &&
|
||||
((this as? KCallableImpl<*>)?.defaultCaller?.member as? AccessibleObject)?.isAccessible ?: true &&
|
||||
(this.asKCallableImpl()?.defaultCaller?.member as? AccessibleObject)?.isAccessible ?: true &&
|
||||
this.javaConstructor?.isAccessible ?: true
|
||||
else -> throw UnsupportedOperationException("Unknown callable: $this ($javaClass)")
|
||||
}
|
||||
@@ -79,7 +79,7 @@ public var KCallable<*>.isAccessible: Boolean
|
||||
}
|
||||
is KFunction -> {
|
||||
javaMethod?.isAccessible = value
|
||||
((this as? KCallableImpl<*>)?.defaultCaller?.member as? AccessibleObject)?.isAccessible = true
|
||||
(this.asKCallableImpl()?.defaultCaller?.member as? AccessibleObject)?.isAccessible = true
|
||||
this.javaConstructor?.isAccessible = value
|
||||
}
|
||||
else -> throw UnsupportedOperationException("Unknown callable: $this ($javaClass)")
|
||||
|
||||
@@ -23,8 +23,9 @@ import kotlin.jvm.internal.KotlinFileFacade
|
||||
import kotlin.jvm.internal.Reflection
|
||||
import kotlin.reflect.*
|
||||
import kotlin.reflect.jvm.internal.KCallableImpl
|
||||
import kotlin.reflect.jvm.internal.KPropertyImpl
|
||||
import kotlin.reflect.jvm.internal.KTypeImpl
|
||||
import kotlin.reflect.jvm.internal.asKCallableImpl
|
||||
import kotlin.reflect.jvm.internal.asKPropertyImpl
|
||||
|
||||
// Kotlin reflection -> Java reflection
|
||||
|
||||
@@ -33,7 +34,7 @@ import kotlin.reflect.jvm.internal.KTypeImpl
|
||||
* or `null` if the property has no backing field.
|
||||
*/
|
||||
public val KProperty<*>.javaField: Field?
|
||||
get() = (this as? KPropertyImpl<*>)?.javaField
|
||||
get() = this.asKPropertyImpl()?.javaField
|
||||
|
||||
/**
|
||||
* Returns a Java [Method] instance corresponding to the getter of the given property,
|
||||
@@ -55,7 +56,7 @@ public val KMutableProperty<*>.javaSetter: Method?
|
||||
* or `null` if this function is a constructor or cannot be represented by a Java [Method].
|
||||
*/
|
||||
public val KFunction<*>.javaMethod: Method?
|
||||
get() = (this as? KCallableImpl<*>)?.caller?.member as? Method
|
||||
get() = this.asKCallableImpl()?.caller?.member as? Method
|
||||
|
||||
/**
|
||||
* Returns a Java [Constructor] instance corresponding to the given Kotlin function,
|
||||
@@ -63,7 +64,7 @@ public val KFunction<*>.javaMethod: Method?
|
||||
*/
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
public val <T> KFunction<T>.javaConstructor: Constructor<T>?
|
||||
get() = (this as? KCallableImpl<T>)?.caller?.member as? Constructor<T>
|
||||
get() = this.asKCallableImpl()?.caller?.member as? Constructor<T>
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,13 +19,14 @@ package kotlin.reflect.jvm.internal
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
|
||||
import java.lang.reflect.Field
|
||||
import kotlin.reflect.KProperty
|
||||
import kotlin.reflect.jvm.internal.JvmPropertySignature.JavaField
|
||||
import kotlin.reflect.jvm.internal.JvmPropertySignature.KotlinProperty
|
||||
|
||||
internal abstract class DescriptorBasedProperty<out R> protected constructor(
|
||||
val container: KDeclarationContainerImpl,
|
||||
name: String,
|
||||
signature: String,
|
||||
val signature: String,
|
||||
descriptorInitialValue: PropertyDescriptor?
|
||||
) : KCallableImpl<R> {
|
||||
constructor(container: KDeclarationContainerImpl, name: String, signature: String) : this(
|
||||
@@ -55,11 +56,13 @@ internal abstract class DescriptorBasedProperty<out R> protected constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean =
|
||||
other is DescriptorBasedProperty<*> && descriptor == other.descriptor
|
||||
override fun equals(other: Any?): Boolean {
|
||||
val that = other.asKPropertyImpl() ?: return false
|
||||
return container == that.container && name == that.name && signature == that.signature
|
||||
}
|
||||
|
||||
override fun hashCode(): Int =
|
||||
descriptor.hashCode()
|
||||
(container.hashCode() * 31 + name.hashCode()) * 31 + signature.hashCode()
|
||||
|
||||
override fun toString(): String =
|
||||
ReflectionObjectRenderer.renderProperty(descriptor)
|
||||
|
||||
@@ -30,7 +30,7 @@ import kotlin.reflect.jvm.internal.JvmFunctionSignature.*
|
||||
internal open class KFunctionImpl protected constructor(
|
||||
private val container: KDeclarationContainerImpl,
|
||||
name: String,
|
||||
signature: String,
|
||||
private val signature: String,
|
||||
descriptorInitialValue: FunctionDescriptor?
|
||||
) : KFunction<Any?>, KCallableImpl<Any?>, FunctionImpl() {
|
||||
constructor(container: KDeclarationContainerImpl, name: String, signature: String) : this(container, name, signature, null)
|
||||
@@ -104,11 +104,13 @@ internal open class KFunctionImpl protected constructor(
|
||||
(if (descriptor.extensionReceiverParameter != null) 1 else 0)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean =
|
||||
other is KFunctionImpl && descriptor == other.descriptor
|
||||
override fun equals(other: Any?): Boolean {
|
||||
val that = other.asKFunctionImpl() ?: return false
|
||||
return container == that.container && name == that.name && signature == that.signature
|
||||
}
|
||||
|
||||
override fun hashCode(): Int =
|
||||
descriptor.hashCode()
|
||||
(container.hashCode() * 31 + name.hashCode()) * 31 + signature.hashCode()
|
||||
|
||||
override fun toString(): String =
|
||||
ReflectionObjectRenderer.renderFunction(descriptor)
|
||||
|
||||
@@ -33,6 +33,8 @@ internal interface KPropertyImpl<out R> : KProperty<R>, KCallableImpl<R> {
|
||||
|
||||
val container: KDeclarationContainerImpl
|
||||
|
||||
val signature: String
|
||||
|
||||
override val getter: Getter<R>
|
||||
|
||||
override val descriptor: PropertyDescriptor
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package kotlin.reflect.jvm.internal
|
||||
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import kotlin.jvm.internal.FunctionReference
|
||||
import kotlin.jvm.internal.PropertyReference
|
||||
import kotlin.reflect.IllegalCallableAccessException
|
||||
|
||||
internal val JVM_STATIC = FqName("kotlin.jvm.JvmStatic")
|
||||
@@ -29,3 +31,14 @@ internal inline fun <R> reflectionCall(block: () -> R): R =
|
||||
catch (e: IllegalAccessException) {
|
||||
throw IllegalCallableAccessException(e)
|
||||
}
|
||||
|
||||
internal fun Any?.asKFunctionImpl(): KFunctionImpl? =
|
||||
this as? KFunctionImpl ?:
|
||||
(this as? FunctionReference)?.compute() as? KFunctionImpl //
|
||||
|
||||
internal fun Any?.asKPropertyImpl(): KPropertyImpl<*>? =
|
||||
this as? KPropertyImpl<*> ?:
|
||||
(this as? PropertyReference)?.compute() as? KPropertyImpl
|
||||
|
||||
internal fun Any?.asKCallableImpl(): KCallableImpl<*>? =
|
||||
this as? KCallableImpl<*> ?: asKFunctionImpl() ?: asKPropertyImpl()
|
||||
|
||||
Reference in New Issue
Block a user