Refactor KFunctionImpl internals, get rid of unwrapFakeOverride
This commit is contained in:
@@ -19,23 +19,20 @@ package kotlin.reflect.jvm.internal
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
|
|
||||||
import org.jetbrains.kotlin.load.java.structure.reflect.ReflectJavaConstructor
|
|
||||||
import org.jetbrains.kotlin.load.java.structure.reflect.ReflectJavaMethod
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
|
||||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
|
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
|
|
||||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
|
|
||||||
import java.lang.reflect.Constructor
|
import java.lang.reflect.Constructor
|
||||||
|
import java.lang.reflect.Member
|
||||||
import java.lang.reflect.Method
|
import java.lang.reflect.Method
|
||||||
import java.lang.reflect.Modifier
|
import java.lang.reflect.Modifier
|
||||||
import kotlin.jvm.internal.FunctionImpl
|
import kotlin.jvm.internal.FunctionImpl
|
||||||
import kotlin.reflect.*
|
import kotlin.reflect.*
|
||||||
|
import kotlin.reflect.jvm.internal.JvmFunctionSignature.BuiltInFunction
|
||||||
|
import kotlin.reflect.jvm.internal.JvmFunctionSignature.JavaConstructor
|
||||||
|
import kotlin.reflect.jvm.internal.JvmFunctionSignature.JavaMethod
|
||||||
|
import kotlin.reflect.jvm.internal.JvmFunctionSignature.KotlinFunction
|
||||||
|
|
||||||
open class KFunctionImpl protected constructor(
|
open class KFunctionImpl protected constructor(
|
||||||
container: KCallableContainerImpl,
|
private val container: KCallableContainerImpl,
|
||||||
name: String,
|
name: String,
|
||||||
signature: String,
|
signature: String,
|
||||||
descriptorInitialValue: FunctionDescriptor?
|
descriptorInitialValue: FunctionDescriptor?
|
||||||
@@ -47,80 +44,42 @@ open class KFunctionImpl protected constructor(
|
|||||||
container, descriptor.name.asString(), RuntimeTypeMapper.mapSignature(descriptor).asString(), descriptor
|
container, descriptor.name.asString(), RuntimeTypeMapper.mapSignature(descriptor).asString(), descriptor
|
||||||
)
|
)
|
||||||
|
|
||||||
private data class FunctionProtoData(
|
|
||||||
val proto: ProtoBuf.Callable,
|
|
||||||
val nameResolver: NameResolver,
|
|
||||||
val signature: JvmProtoBuf.JvmMethodSignature
|
|
||||||
)
|
|
||||||
|
|
||||||
override val descriptor: FunctionDescriptor by ReflectProperties.lazySoft<FunctionDescriptor>(descriptorInitialValue) {
|
override val descriptor: FunctionDescriptor by ReflectProperties.lazySoft<FunctionDescriptor>(descriptorInitialValue) {
|
||||||
container.findFunctionDescriptor(name, signature)
|
container.findFunctionDescriptor(name, signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
// null if this is a function declared in a foreign (Java) class
|
override val name: String get() = descriptor.name.asString()
|
||||||
private val protoData: FunctionProtoData? by ReflectProperties.lazyWeak {
|
|
||||||
val function = DescriptorUtils.unwrapFakeOverride(descriptor) as? DeserializedCallableMemberDescriptor
|
internal val caller: FunctionCaller by ReflectProperties.lazySoft {
|
||||||
if (function != null) {
|
val jvmSignature = RuntimeTypeMapper.mapSignature(descriptor)
|
||||||
val proto = function.proto
|
val member: Member? = when (jvmSignature) {
|
||||||
if (proto.hasExtension(JvmProtoBuf.methodSignature)) {
|
is KotlinFunction ->
|
||||||
return@lazyWeak FunctionProtoData(proto, function.nameResolver, proto.getExtension(JvmProtoBuf.methodSignature))
|
if (name == "<init>") container.findConstructorBySignature(jvmSignature.signature, jvmSignature.nameResolver,
|
||||||
}
|
Visibilities.isPrivate(descriptor.visibility))
|
||||||
|
else container.findMethodBySignature(jvmSignature.proto, jvmSignature.signature, jvmSignature.nameResolver,
|
||||||
|
Visibilities.isPrivate(descriptor.visibility))
|
||||||
|
is JavaMethod -> jvmSignature.method
|
||||||
|
is JavaConstructor -> jvmSignature.constructor
|
||||||
|
is BuiltInFunction -> throw KotlinReflectionInternalError("Built-in functions are not fully supported yet: $descriptor")
|
||||||
}
|
}
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
internal val javaMethod: Method? by ReflectProperties.lazySoft {
|
when (member) {
|
||||||
if (!isConstructor) {
|
is Constructor<*> -> FunctionCaller.Constructor(member)
|
||||||
val proto = protoData
|
is Method -> when {
|
||||||
if (proto != null) {
|
!Modifier.isStatic(member.modifiers) -> FunctionCaller.InstanceMethod(member)
|
||||||
container.findMethodBySignature(proto.proto, proto.signature, proto.nameResolver,
|
descriptor.annotations.findAnnotation(PLATFORM_STATIC) != null -> FunctionCaller.PlatformStaticInObject(member)
|
||||||
Visibilities.isPrivate(descriptor.getVisibility()))
|
else -> FunctionCaller.StaticMethod(member)
|
||||||
}
|
|
||||||
else {
|
|
||||||
((descriptor.getOriginal().getSource() as? JavaSourceElement)?.javaElement as? ReflectJavaMethod)?.member
|
|
||||||
}
|
}
|
||||||
|
else -> throw KotlinReflectionInternalError("Call is not yet supported for this function: $descriptor")
|
||||||
}
|
}
|
||||||
else null
|
|
||||||
}
|
|
||||||
|
|
||||||
internal val javaConstructor: Constructor<*>? by ReflectProperties.lazySoft {
|
|
||||||
if (isConstructor) {
|
|
||||||
val proto = protoData
|
|
||||||
if (proto != null) {
|
|
||||||
return@lazySoft container.findConstructorBySignature(
|
|
||||||
proto.signature, proto.nameResolver, Visibilities.isPrivate(descriptor.getVisibility())
|
|
||||||
)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
((descriptor.getOriginal().getSource() as? JavaSourceElement)?.javaElement as? ReflectJavaConstructor)?.member
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else null
|
|
||||||
}
|
|
||||||
|
|
||||||
override val name: String get() = descriptor.getName().asString()
|
|
||||||
|
|
||||||
private val caller: FunctionCaller by ReflectProperties.lazySoft {
|
|
||||||
javaConstructor?.let { FunctionCaller.Constructor(it) } ?:
|
|
||||||
javaMethod?.let { method ->
|
|
||||||
when {
|
|
||||||
!Modifier.isStatic(method.modifiers) -> FunctionCaller.InstanceMethod(method)
|
|
||||||
descriptor.annotations.findAnnotation(PLATFORM_STATIC) != null -> FunctionCaller.PlatformStaticInObject(method)
|
|
||||||
else -> FunctionCaller.StaticMethod(method)
|
|
||||||
}
|
|
||||||
} ?:
|
|
||||||
throw KotlinReflectionInternalError("Call is not yet supported for this function: $descriptor")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun call(vararg args: Any?): Any? = caller.call(args)
|
override fun call(vararg args: Any?): Any? = caller.call(args)
|
||||||
|
|
||||||
private val isConstructor: Boolean get() = name == "<init>"
|
|
||||||
|
|
||||||
override fun getArity(): Int {
|
override fun getArity(): Int {
|
||||||
// TODO: test?
|
return descriptor.valueParameters.size() +
|
||||||
return descriptor.getValueParameters().size() +
|
(if (descriptor.dispatchReceiverParameter != null) 1 else 0) +
|
||||||
(if (descriptor.getDispatchReceiverParameter() != null) 1 else 0) +
|
(if (descriptor.extensionReceiverParameter != null) 1 else 0)
|
||||||
(if (descriptor.getExtensionReceiverParameter() != null) 1 else 0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean =
|
override fun equals(other: Any?): Boolean =
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.name.ClassId
|
|||||||
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
|
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
||||||
|
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
|
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
|
||||||
@@ -40,32 +41,33 @@ import java.lang.reflect.Field
|
|||||||
import java.lang.reflect.Method
|
import java.lang.reflect.Method
|
||||||
import kotlin.reflect.KotlinReflectionInternalError
|
import kotlin.reflect.KotlinReflectionInternalError
|
||||||
|
|
||||||
interface JvmFunctionSignature {
|
sealed class JvmFunctionSignature {
|
||||||
fun asString(): String
|
abstract fun asString(): String
|
||||||
|
|
||||||
class KotlinFunction(
|
class KotlinFunction(
|
||||||
private val signature: JvmProtoBuf.JvmMethodSignature,
|
val proto: ProtoBuf.Callable,
|
||||||
private val nameResolver: NameResolver
|
val signature: JvmProtoBuf.JvmMethodSignature,
|
||||||
) : JvmFunctionSignature {
|
val nameResolver: NameResolver
|
||||||
|
) : JvmFunctionSignature() {
|
||||||
override fun asString(): String =
|
override fun asString(): String =
|
||||||
SignatureDeserializer(nameResolver).methodSignatureString(signature)
|
SignatureDeserializer(nameResolver).methodSignatureString(signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
class JavaMethod(private val method: Method) : JvmFunctionSignature {
|
class JavaMethod(val method: Method) : JvmFunctionSignature() {
|
||||||
override fun asString(): String =
|
override fun asString(): String =
|
||||||
method.name +
|
method.name +
|
||||||
method.parameterTypes.joinToString(separator = "", prefix = "(", postfix = ")") { it.desc } +
|
method.parameterTypes.joinToString(separator = "", prefix = "(", postfix = ")") { it.desc } +
|
||||||
method.returnType.desc
|
method.returnType.desc
|
||||||
}
|
}
|
||||||
|
|
||||||
class JavaConstructor(private val constructor: Constructor<*>) : JvmFunctionSignature {
|
class JavaConstructor(val constructor: Constructor<*>) : JvmFunctionSignature() {
|
||||||
override fun asString(): String =
|
override fun asString(): String =
|
||||||
"<init>" +
|
"<init>" +
|
||||||
constructor.parameterTypes.joinToString(separator = "", prefix = "(", postfix = ")") { it.desc } +
|
constructor.parameterTypes.joinToString(separator = "", prefix = "(", postfix = ")") { it.desc } +
|
||||||
"V"
|
"V"
|
||||||
}
|
}
|
||||||
|
|
||||||
class BuiltInFunction(private val signature: String) : JvmFunctionSignature {
|
class BuiltInFunction(private val signature: String) : JvmFunctionSignature() {
|
||||||
override fun asString(): String = signature
|
override fun asString(): String = signature
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -85,7 +87,7 @@ interface JvmPropertySignature {
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
if (signature.hasGetter()) {
|
if (signature.hasGetter()) {
|
||||||
string = JvmFunctionSignature.KotlinFunction(signature.getter, nameResolver).asString()
|
string = SignatureDeserializer(nameResolver).methodSignatureString(signature.getter)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
string = JvmAbi.getterName(nameResolver.getString(signature.field.name)) +
|
string = JvmAbi.getterName(nameResolver.getString(signature.field.name)) +
|
||||||
@@ -114,7 +116,7 @@ object RuntimeTypeMapper {
|
|||||||
val proto = function.proto
|
val proto = function.proto
|
||||||
if (proto.hasExtension(JvmProtoBuf.methodSignature)) {
|
if (proto.hasExtension(JvmProtoBuf.methodSignature)) {
|
||||||
val signature = proto.getExtension(JvmProtoBuf.methodSignature)
|
val signature = proto.getExtension(JvmProtoBuf.methodSignature)
|
||||||
return JvmFunctionSignature.KotlinFunction(signature, function.nameResolver)
|
return JvmFunctionSignature.KotlinFunction(proto, signature, function.nameResolver)
|
||||||
}
|
}
|
||||||
// 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
|
||||||
return mapIntrinsicFunctionSignature(function) ?:
|
return mapIntrinsicFunctionSignature(function) ?:
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public val KMutableProperty<*>.javaSetter: Method?
|
|||||||
* or `null` if this function is a constructor or cannot be represented by a Java [Method].
|
* or `null` if this function is a constructor or cannot be represented by a Java [Method].
|
||||||
*/
|
*/
|
||||||
public val KFunction<*>.javaMethod: Method?
|
public val KFunction<*>.javaMethod: Method?
|
||||||
get() = (this as? KFunctionImpl)?.javaMethod
|
get() = ((this as? KFunctionImpl)?.caller as? FunctionCaller.Method)?.method
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a Java [Constructor] instance corresponding to the given Kotlin function,
|
* Returns a Java [Constructor] instance corresponding to the given Kotlin function,
|
||||||
@@ -76,7 +76,7 @@ public val KFunction<*>.javaMethod: Method?
|
|||||||
*/
|
*/
|
||||||
@suppress("UNCHECKED_CAST")
|
@suppress("UNCHECKED_CAST")
|
||||||
public val <T> KFunction<T>.javaConstructor: Constructor<T>?
|
public val <T> KFunction<T>.javaConstructor: Constructor<T>?
|
||||||
get() = (this as? KFunctionImpl)?.javaConstructor as Constructor<T>?
|
get() = ((this as? KFunctionImpl)?.caller as? FunctionCaller.Constructor)?.constructor as? Constructor<T>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user