Load new proto messages for functions and properties

This commit is contained in:
Alexander Udalov
2015-10-04 23:58:13 +03:00
parent a58a7727d1
commit 9bf0502a31
25 changed files with 365 additions and 275 deletions
@@ -157,7 +157,6 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
// TODO: check resulting method's return type
fun findMethodBySignature(
@Suppress("UNUSED_PARAMETER") proto: ProtoBuf.Callable,
signature: JvmProtoBuf.JvmMethodSignature,
nameResolver: NameResolver,
declared: Boolean
@@ -270,7 +269,7 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
// TODO: check resulting field's type
fun findFieldBySignature(
proto: ProtoBuf.Callable,
proto: ProtoBuf.Property,
signature: JvmProtoBuf.JvmFieldSignature,
nameResolver: NameResolver
): Field? {
@@ -293,12 +292,12 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
// Returns the JVM class which contains this callable. This class may be different from the one represented by descriptors
// in case of top level functions (their bodies are in package parts), methods with implementations in interfaces, etc.
private fun implClassForCallable(nameResolver: NameResolver, proto: ProtoBuf.Callable): Class<*>? {
if (!proto.hasExtension(JvmProtoBuf.oldImplClassName)) return null
private fun implClassForCallable(nameResolver: NameResolver, proto: ProtoBuf.Property): Class<*>? {
if (!proto.hasExtension(JvmProtoBuf.propertyImplClassName)) return null
val implClassName = nameResolver.getName(proto.getExtension(JvmProtoBuf.oldImplClassName))
val implClassName = nameResolver.getName(proto.getExtension(JvmProtoBuf.propertyImplClassName))
// TODO: store fq name of impl class name in jvm_descriptors.proto
val classId = ClassId(jClass.classId.getPackageFqName(), implClassName)
val classId = ClassId(jClass.classId.packageFqName, implClassName)
return jClass.safeClassLoader.loadClass(classId.asSingleFqName().asString())
}
@@ -25,10 +25,7 @@ import java.lang.reflect.Method
import java.lang.reflect.Modifier
import kotlin.jvm.internal.FunctionImpl
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
import kotlin.reflect.jvm.internal.JvmFunctionSignature.*
internal open class KFunctionImpl protected constructor(
private val container: KDeclarationContainerImpl,
@@ -54,9 +51,8 @@ internal open class KFunctionImpl protected constructor(
override val caller: FunctionCaller<*> by ReflectProperties.lazySoft {
val jvmSignature = RuntimeTypeMapper.mapSignature(descriptor)
val member: Member? = when (jvmSignature) {
is KotlinFunction ->
if (name == "<init>") container.findConstructorBySignature(jvmSignature.signature, jvmSignature.nameResolver, isDeclared())
else container.findMethodBySignature(jvmSignature.proto, jvmSignature.signature, jvmSignature.nameResolver, isDeclared())
is KotlinConstructor -> container.findConstructorBySignature(jvmSignature.signature, jvmSignature.nameResolver, isDeclared())
is KotlinFunction -> container.findMethodBySignature(jvmSignature.signature, jvmSignature.nameResolver, isDeclared())
is JavaMethod -> jvmSignature.method
is JavaConstructor -> jvmSignature.constructor
is BuiltInFunction -> jvmSignature.getMember(container)
@@ -80,13 +76,11 @@ internal open class KFunctionImpl protected constructor(
val jvmSignature = RuntimeTypeMapper.mapSignature(descriptor)
val member: Member? = when (jvmSignature) {
is KotlinFunction -> {
if (name == "<init>") {
container.findDefaultConstructor(jvmSignature.signature, jvmSignature.nameResolver, isDeclared())
}
else {
val isMember = !Modifier.isStatic(caller.member.modifiers)
container.findDefaultMethod(jvmSignature.signature, jvmSignature.nameResolver, isMember, isDeclared())
}
container.findDefaultMethod(jvmSignature.signature, jvmSignature.nameResolver,
!Modifier.isStatic(caller.member.modifiers), isDeclared())
}
is KotlinConstructor -> {
container.findDefaultConstructor(jvmSignature.signature, jvmSignature.nameResolver, isDeclared())
}
else -> {
// Java methods, Java constructors and built-ins don't have $default methods
@@ -116,9 +116,7 @@ private fun KPropertyImpl.Accessor<*>.computeCallerForAccessor(isGetter: Boolean
}
val accessor = accessorSignature?.let { signature ->
property.container.findMethodBySignature(
jvmSignature.proto, signature, jvmSignature.nameResolver, Visibilities.isPrivate(descriptor.visibility)
)
property.container.findMethodBySignature(signature, jvmSignature.nameResolver, Visibilities.isPrivate(descriptor.visibility))
}
when {
@@ -46,7 +46,16 @@ internal sealed class JvmFunctionSignature {
abstract fun asString(): String
class KotlinFunction(
val proto: ProtoBuf.Callable,
val proto: ProtoBuf.Function,
val signature: JvmProtoBuf.JvmMethodSignature,
val nameResolver: NameResolver
) : JvmFunctionSignature() {
override fun asString(): String =
nameResolver.getString(signature.name) + nameResolver.getString(signature.desc)
}
class KotlinConstructor(
val proto: ProtoBuf.Constructor,
val signature: JvmProtoBuf.JvmMethodSignature,
val nameResolver: NameResolver
) : JvmFunctionSignature() {
@@ -87,7 +96,7 @@ internal sealed class JvmPropertySignature {
abstract fun asString(): String
class KotlinProperty(
val proto: ProtoBuf.Callable,
val proto: ProtoBuf.Property,
val signature: JvmProtoBuf.JvmPropertySignature,
val nameResolver: NameResolver
) : JvmPropertySignature() {
@@ -124,10 +133,14 @@ internal object RuntimeTypeMapper {
when (function) {
is DeserializedCallableMemberDescriptor -> {
val proto = function.proto
if (proto.hasExtension(JvmProtoBuf.oldMethodSignature)) {
val signature = proto.getExtension(JvmProtoBuf.oldMethodSignature)
if (proto is ProtoBuf.Function && proto.hasExtension(JvmProtoBuf.methodSignature)) {
val signature = proto.getExtension(JvmProtoBuf.methodSignature)
return JvmFunctionSignature.KotlinFunction(proto, signature, function.nameResolver)
}
if (proto is ProtoBuf.Constructor && proto.hasExtension(JvmProtoBuf.constructorSignature)) {
val signature = proto.getExtension(JvmProtoBuf.constructorSignature)
return JvmFunctionSignature.KotlinConstructor(proto, signature, function.nameResolver)
}
// If it's a deserialized function but has no JVM signature, it must be from built-ins
return mapIntrinsicFunctionSignature(function) ?:
throw KotlinReflectionInternalError("Reflection on built-in Kotlin types is not yet fully supported. " +
@@ -153,10 +166,10 @@ internal object RuntimeTypeMapper {
val property = DescriptorUtils.unwrapFakeOverride(possiblyOverriddenProperty)
if (property is DeserializedPropertyDescriptor) {
val proto = property.proto
if (!proto.hasExtension(JvmProtoBuf.oldPropertySignature)) {
if (!proto.hasExtension(JvmProtoBuf.propertySignature)) {
throw KotlinReflectionInternalError("No metadata found for $property")
}
return JvmPropertySignature.KotlinProperty(proto, proto.getExtension(JvmProtoBuf.oldPropertySignature), property.nameResolver)
return JvmPropertySignature.KotlinProperty(proto, proto.getExtension(JvmProtoBuf.propertySignature), property.nameResolver)
}
else if (property is JavaPropertyDescriptor) {
val field = ((property.source as? JavaSourceElement)?.javaElement as? ReflectJavaField)?.member ?:
@@ -16,7 +16,6 @@
package kotlin.reflect.jvm
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.load.kotlin.JvmNameResolver
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.DeserializationContext
@@ -42,11 +41,11 @@ public fun <R> Function<R>.reflect(): KFunction<R>? {
JvmProtoBuf.StringTableTypes.parseDelimitedFrom(input, JvmProtoBufUtil.EXTENSION_REGISTRY),
callable.strings
)
val proto = ProtoBuf.Callable.parseFrom(input, JvmProtoBufUtil.EXTENSION_REGISTRY)
val proto = ProtoBuf.Function.parseFrom(input, JvmProtoBufUtil.EXTENSION_REGISTRY)
val moduleData = javaClass.getOrCreateModule()
val context = DeserializationContext(moduleData.deserialization, nameResolver, moduleData.module,
parentTypeDeserializer = null, typeParameters = listOf())
val descriptor = MemberDeserializer(context).loadCallable(proto) as FunctionDescriptor
val descriptor = MemberDeserializer(context).loadFunction(proto)
@Suppress("UNCHECKED_CAST")
return KFunctionImpl(EmptyContainerForLocal, descriptor) as KFunction<R>
}