Remove KForeignMemberProperty and KClassOrigin, use KMemberPropertyImpl instead

This commit is contained in:
Alexander Udalov
2015-02-20 19:22:30 +03:00
parent ff0044f66a
commit fdfd808d80
8 changed files with 69 additions and 128 deletions
@@ -24,44 +24,48 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
import java.lang.reflect.Field
import java.lang.reflect.Method
import kotlin.reflect.KotlinReflectionInternalError
abstract class DescriptorBasedProperty(computeDescriptor: () -> PropertyDescriptor) {
protected abstract val container: KCallableContainerImpl
data class PropertyProtoData(
protected abstract val name: String
private data class PropertyProtoData(
val proto: ProtoBuf.Callable,
val nameResolver: NameResolver,
val signature: JvmProtoBuf.JvmPropertySignature
)
protected val descriptor: PropertyDescriptor by ReflectProperties.lazySoft { computeDescriptor() }
protected val descriptor: PropertyDescriptor by ReflectProperties.lazySoft(computeDescriptor)
protected val protoData: PropertyProtoData by ReflectProperties.lazyWeak {
// null if this is a property declared in a foreign (Java) class
private val protoData: PropertyProtoData? by ReflectProperties.lazyWeak @p {(): PropertyProtoData? ->
val property = DescriptorUtils.unwrapFakeOverride(descriptor) as? DeserializedPropertyDescriptor
?: throw KotlinReflectionInternalError("Member property resolved incorrectly: $descriptor")
val proto = property.proto
if (!proto.hasExtension(JvmProtoBuf.propertySignature)) {
throw KotlinReflectionInternalError("Member property lacks JVM signature: $descriptor")
if (property != null) {
val proto = property.proto
if (proto.hasExtension(JvmProtoBuf.propertySignature)) {
return@p PropertyProtoData(proto, property.nameResolver, proto.getExtension(JvmProtoBuf.propertySignature))
}
}
PropertyProtoData(proto, property.nameResolver, proto.getExtension(JvmProtoBuf.propertySignature))
null
}
val field: Field? by ReflectProperties.lazySoft {
open val field: Field? by ReflectProperties.lazySoft {
val proto = protoData
if (!proto.signature.hasField()) null
if (proto == null) container.jClass.getField(name)
else if (!proto.signature.hasField()) null
else container.findFieldBySignature(proto.proto, proto.signature.getField(), proto.nameResolver)
}
open val getter: Method? by ReflectProperties.lazySoft {
val proto = protoData
if (!proto.signature.hasGetter()) null
if (proto == null || !proto.signature.hasGetter()) null
else container.findMethodBySignature(proto.signature.getGetter(), proto.nameResolver)
}
open val setter: Method? by ReflectProperties.lazySoft {
val proto = protoData
if (!proto.signature.hasSetter()) null
if (proto == null || !proto.signature.hasSetter()) null
else container.findMethodBySignature(proto.signature.getSetter(), proto.nameResolver)
}
}
@@ -16,26 +16,18 @@
package kotlin.reflect.jvm.internal
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.serialization.deserialization.findClassAcrossModuleDependencies
import kotlin.jvm.internal.KotlinClass
import kotlin.reflect.KClass
import kotlin.reflect.KMemberProperty
import kotlin.reflect.KMutableMemberProperty
import kotlin.reflect.KotlinReflectionInternalError
enum class KClassOrigin {
BUILT_IN
KOTLIN
FOREIGN
}
class KClassImpl<T>(override val jClass: Class<T>) : KCallableContainerImpl(), KClass<T> {
// Don't use kotlin.properties.Delegates here because it's a Kotlin class which will invoke KClassImpl() in <clinit>,
// resulting in infinite recursion
val descriptor by ReflectProperties.lazySoft {(): ClassDescriptor ->
val descriptor by ReflectProperties.lazySoft {
val moduleData = jClass.getOrCreateModule()
val classId = RuntimeTypeMapper.mapJvmClassToKotlinClassId(jClass)
@@ -48,36 +40,12 @@ class KClassImpl<T>(override val jClass: Class<T>) : KCallableContainerImpl(), K
override val scope: JetScope get() = descriptor.getDefaultType().getMemberScope()
private val origin by ReflectProperties.lazy {(): KClassOrigin ->
if (jClass.isAnnotationPresent(javaClass<KotlinClass>())) {
KClassOrigin.KOTLIN
}
else {
KClassOrigin.FOREIGN
// TODO: built-in classes
}
}
fun memberProperty(name: String): KMemberProperty<T, *> {
val computeDescriptor = findPropertyDescriptor(name)
if (origin === KClassOrigin.KOTLIN) {
return KMemberPropertyImpl<T, Any>(this, computeDescriptor)
}
else {
return KForeignMemberProperty<T, Any>(name, this)
}
return KMemberPropertyImpl<T, Any>(this, findPropertyDescriptor(name))
}
fun mutableMemberProperty(name: String): KMutableMemberProperty<T, *> {
val computeDescriptor = findPropertyDescriptor(name)
if (origin === KClassOrigin.KOTLIN) {
return KMutableMemberPropertyImpl<T, Any>(this, computeDescriptor)
}
else {
return KMutableForeignMemberProperty<T, Any>(name, this)
}
return KMutableMemberPropertyImpl<T, Any>(this, findPropertyDescriptor(name))
}
override fun equals(other: Any?): Boolean =
@@ -1,72 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package kotlin.reflect.jvm.internal
import java.lang.reflect.*
import kotlin.reflect.*
open class KForeignMemberProperty<T : Any, out R>(
override val name: String,
protected val owner: KClassImpl<T>
) : KMemberProperty<T, R>, KPropertyImpl<R> {
override val field: Field = try {
owner.jClass.getField(name)
}
catch (e: NoSuchFieldException) {
throw NoSuchPropertyException(e)
}
override val getter: Method? get() = null
override fun get(receiver: T): R {
try {
return field.get(receiver) as R
}
catch (e: IllegalAccessException) {
throw IllegalPropertyAccessException(e)
}
}
override fun equals(other: Any?): Boolean =
other is KForeignMemberProperty<*, *> && name == other.name && owner == other.owner
override fun hashCode(): Int =
name.hashCode() * 31 + owner.hashCode()
// TODO: include visibility, return type
override fun toString(): String =
"val ${owner.jClass.getName()}.$name"
}
class KMutableForeignMemberProperty<T : Any, R>(
name: String,
owner: KClassImpl<T>
) : KMutableMemberProperty<T, R>, KMutablePropertyImpl<R>, KForeignMemberProperty<T, R>(name, owner) {
override val setter: Method? get() = null
override fun set(receiver: T, value: R) {
try {
field.set(receiver, value)
}
catch (e: IllegalAccessException) {
throw IllegalPropertyAccessException(e)
}
}
override fun toString(): String =
"var ${owner.jClass.getName()}.$name"
}
@@ -16,8 +16,9 @@
package kotlin.reflect.jvm
import kotlin.reflect.*
import kotlin.reflect.jvm.internal.*
import kotlin.reflect.KProperty
import kotlin.reflect.jvm.internal.KMemberPropertyImpl
import kotlin.reflect.jvm.internal.KMutableMemberPropertyImpl
public var <R> KProperty<R>.accessible: Boolean
get() {
@@ -29,7 +30,6 @@ public var <R> KProperty<R>.accessible: Boolean
is KMemberPropertyImpl<*, R> ->
field?.isAccessible() ?: true &&
getter?.isAccessible() ?: true
is KForeignMemberProperty<*, R> -> field.isAccessible()
else -> {
// Non-member properties always have public visibility on JVM, thus accessible has no effect on them
true
@@ -47,8 +47,5 @@ public var <R> KProperty<R>.accessible: Boolean
field?.setAccessible(value)
getter?.setAccessible(value)
}
is KForeignMemberProperty<*, R> -> {
field.setAccessible(value)
}
}
}