Introduce KClass.members, make properties/extensionProperties extensions

To avoid significant growth of KClass and KPackage interfaces
This commit is contained in:
Alexander Udalov
2015-07-08 03:13:40 +03:00
parent 2492977274
commit 50dbda1e1a
19 changed files with 80 additions and 54 deletions
@@ -4,6 +4,8 @@ fun box(): String {
val f = J::x val f = J::x
assertEquals("x", f.name) assertEquals("x", f.name)
assertEquals(f, J::class.members.single { it.name == "x" })
f.set("OK") f.set("OK")
assertEquals("OK", J.x) assertEquals("OK", J.x)
assertEquals("OK", f.getter()) assertEquals("OK", f.getter())
@@ -1,4 +1,5 @@
import kotlin.reflect.jvm.kotlin import kotlin.reflect.jvm.kotlin
import kotlin.reflect.*
class A { class A {
var String.id: String var String.id: String
@@ -1,4 +1,4 @@
import kotlin.reflect.KMutableProperty2 import kotlin.reflect.*
import kotlin.test.assertEquals import kotlin.test.assertEquals
class C(var state: String) { class C(var state: String) {
@@ -1,10 +1,10 @@
import kotlin.reflect.KProperty1 import kotlin.reflect.*
class A<T> { class A<T> {
val result = "OK" val result = "OK"
} }
fun box(): String { fun box(): String {
val k : KProperty1<A<*>, *> = A::class.properties.single() val k: KProperty1<A<*>, *> = A::class.properties.single()
return k.get(A<String>()) as String return k.get(A<String>()) as String
} }
@@ -1,5 +1,5 @@
import kotlin.reflect.jvm.kotlin import kotlin.reflect.jvm.kotlin
import kotlin.reflect.KMutableProperty2 import kotlin.reflect.*
var storage = "before" var storage = "before"
@@ -1,5 +1,5 @@
import kotlin.reflect.jvm.kotlin import kotlin.reflect.jvm.kotlin
import kotlin.reflect.KMutableProperty1 import kotlin.reflect.*
class A(val readonly: String) { class A(val readonly: String) {
var mutable: String = "before" var mutable: String = "before"
@@ -1,6 +1,5 @@
import kotlin.reflect.jvm.kotlin import kotlin.reflect.jvm.kotlin
import kotlin.reflect.KProperty1 import kotlin.reflect.*
import kotlin.reflect.KProperty2
class A { class A {
val foo: String = "member" val foo: String = "member"
@@ -1,5 +1,4 @@
import kotlin.reflect.IllegalPropertyAccessException import kotlin.reflect.*
import kotlin.reflect.KProperty1
import kotlin.reflect.jvm.accessible import kotlin.reflect.jvm.accessible
class Result { class Result {
@@ -1,5 +1,4 @@
import kotlin.reflect.IllegalPropertyAccessException import kotlin.reflect.*
import kotlin.reflect.KMutableProperty1
import kotlin.reflect.jvm.accessible import kotlin.reflect.jvm.accessible
class A { class A {
@@ -1,3 +1,5 @@
import kotlin.reflect.*
open class A(private val p: Int) open class A(private val p: Int)
class B : A(42) class B : A(42)
@@ -1,6 +1,5 @@
import kotlin.reflect.IllegalPropertyAccessException import kotlin.reflect.*
import kotlin.reflect.jvm.accessible import kotlin.reflect.jvm.accessible
import kotlin.reflect.KMutableProperty1
class A(param: String) { class A(param: String) {
protected var v: String = param protected var v: String = param
@@ -1,3 +1,4 @@
import kotlin.reflect.*
import kotlin.reflect.jvm.kotlin import kotlin.reflect.jvm.kotlin
class A(param: String) { class A(param: String) {
@@ -1,6 +1,6 @@
package test package test
import kotlin.reflect.KClass import kotlin.reflect.*
import kotlin.test.* import kotlin.test.*
class K(val p: String) class K(val p: String)
@@ -17,5 +17,6 @@ fun n10() = (Foo::func).invoke(Foo(""))
fun n11() = (Foo::func)(Foo("")) fun n11() = (Foo::func)(Foo(""))
fun y01() = Foo::prop.<!NO_REFLECTION_IN_CLASS_PATH!>getter<!> fun y01() = Foo::prop.<!NO_REFLECTION_IN_CLASS_PATH!>getter<!>
fun y02() = Foo::class.<!NO_REFLECTION_IN_CLASS_PATH!>properties<!> fun y02() = Foo::class.<!NO_REFLECTION_IN_CLASS_PATH!>members<!>
fun y03() = Foo::class.<!NO_REFLECTION_IN_CLASS_PATH!>simpleName<!> fun y03() = Foo::class.<!NO_REFLECTION_IN_CLASS_PATH!>simpleName<!>
fun y04() = Foo::class.<!UNRESOLVED_REFERENCE!>properties<!>
@@ -12,8 +12,9 @@ internal fun n09(/*0*/ p: kotlin.reflect.KProperty2<kotlin.String, kotlin.String
internal fun n10(): kotlin.Unit internal fun n10(): kotlin.Unit
internal fun n11(): kotlin.Unit internal fun n11(): kotlin.Unit
internal fun y01(): kotlin.reflect.KProperty1.Getter<Foo, kotlin.Any> internal fun y01(): kotlin.reflect.KProperty1.Getter<Foo, kotlin.Any>
internal fun y02(): kotlin.Collection<kotlin.reflect.KProperty1<Foo, *>> internal fun y02(): kotlin.Collection<kotlin.reflect.KCallable<*>>
internal fun y03(): kotlin.String? internal fun y03(): kotlin.String?
internal fun y04(): [ERROR : Error function type]
internal final class Foo { internal final class Foo {
public constructor Foo(/*0*/ prop: kotlin.Any) public constructor Foo(/*0*/ prop: kotlin.Any)
+3 -7
View File
@@ -39,12 +39,8 @@ public interface KClass<T> : KDeclarationContainer {
public val qualifiedName: String? public val qualifiedName: String?
/** /**
* Returns non-extension properties declared in this class and all of its superclasses. * All elements accessible in this class, including functions and properties
* declared in this class and all of its superclasses.
*/ */
public val properties: Collection<KProperty1<T, *>> public val members: Collection<KCallable<*>>
/**
* Returns extension properties declared in this class and all of its superclasses.
*/
public val extensionProperties: Collection<KProperty2<T, *, *>>
} }
@@ -18,14 +18,38 @@ package kotlin.reflect
import kotlin.reflect.jvm.internal.KClassImpl import kotlin.reflect.jvm.internal.KClassImpl
/**
* Returns non-extension properties declared in this class and all of its superclasses.
*/
public val <T> KClass<T>.properties: Collection<KProperty1<T, *>>
get() = (this as KClassImpl<T>)
.getMembers(declaredOnly = false, nonExtensions = true, extensions = false)
.filterIsInstance<KProperty1<T, *>>()
.toList()
/**
* Returns extension properties declared in this class and all of its superclasses.
*/
public val <T> KClass<T>.extensionProperties: Collection<KProperty2<T, *, *>>
get() = (this as KClassImpl<T>)
.getMembers(declaredOnly = false, nonExtensions = false, extensions = true)
.filterIsInstance<KProperty2<T, *, *>>()
.toList()
/** /**
* Returns non-extension properties declared in this class. * Returns non-extension properties declared in this class.
*/ */
public val <T> KClass<T>.declaredProperties: Collection<KProperty1<T, *>> public val <T> KClass<T>.declaredProperties: Collection<KProperty1<T, *>>
get() = (this as KClassImpl<T>).getProperties(declared = true) get() = (this as KClassImpl<T>)
.getMembers(declaredOnly = true, nonExtensions = true, extensions = false)
.filterIsInstance<KProperty1<T, *>>()
.toList()
/** /**
* Returns extension properties declared in this class. * Returns extension properties declared in this class.
*/ */
public val <T> KClass<T>.declaredExtensionProperties: Collection<KProperty2<T, *, *>> public val <T> KClass<T>.declaredExtensionProperties: Collection<KProperty2<T, *, *>>
get() = (this as KClassImpl<T>).getExtensionProperties(declared = true) get() = (this as KClassImpl<T>)
.getMembers(declaredOnly = true, nonExtensions = false, extensions = true)
.filterIsInstance<KProperty2<T, *, *>>()
.toList()
@@ -16,13 +16,17 @@
package kotlin.reflect.jvm.internal package kotlin.reflect.jvm.internal
import org.jetbrains.kotlin.descriptors.MemberDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.resolve.scopes.ChainedScope import org.jetbrains.kotlin.resolve.scopes.ChainedScope
import org.jetbrains.kotlin.resolve.scopes.JetScope import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.serialization.deserialization.findClassAcrossModuleDependencies import org.jetbrains.kotlin.serialization.deserialization.findClassAcrossModuleDependencies
import kotlin.reflect.* import kotlin.reflect.KCallable
import kotlin.reflect.KClass
import kotlin.reflect.KotlinReflectionInternalError
class KClassImpl<T>(override val jClass: Class<T>) : KCallableContainerImpl(), KClass<T> { class KClassImpl<T>(override val jClass: Class<T>) : KCallableContainerImpl(), KClass<T> {
val descriptor by ReflectProperties.lazySoft { val descriptor by ReflectProperties.lazySoft {
@@ -72,34 +76,35 @@ class KClassImpl<T>(override val jClass: Class<T>) : KCallableContainerImpl(), K
} }
} }
override val properties: Collection<KProperty1<T, *>> override val members: Collection<KCallable<*>>
get() = getProperties(declared = false) get() = getMembers(declaredOnly = false, nonExtensions = true, extensions = true).toList()
override val extensionProperties: Collection<KProperty2<T, *, *>> fun getMembers(declaredOnly: Boolean, nonExtensions: Boolean, extensions: Boolean): Sequence<KCallable<*>> =
get() = getExtensionProperties(declared = false)
fun getProperties(declared: Boolean): Collection<KProperty1<T, *>> =
getProperties(extension = false, declared = declared) { descriptor ->
if (descriptor.isVar()) KMutableProperty1Impl<T, Any?>(this, descriptor)
else KProperty1Impl<T, Any?>(this, descriptor)
}
fun getExtensionProperties(declared: Boolean): Collection<KProperty2<T, *, *>> =
getProperties(extension = true, declared = declared) { descriptor ->
if (descriptor.isVar()) KMutableProperty2Impl<T, Any?, Any?>(this, descriptor)
else KProperty2Impl<T, Any?, Any?>(this, descriptor)
}
private fun <P : KProperty<*>> getProperties(extension: Boolean, declared: Boolean, create: (PropertyDescriptor) -> P): Collection<P> =
scope.getAllDescriptors().asSequence() scope.getAllDescriptors().asSequence()
.filterIsInstance<PropertyDescriptor>()
.filter { descriptor -> .filter { descriptor ->
(descriptor.getExtensionReceiverParameter() != null) == extension && descriptor !is MemberDescriptor || descriptor.getVisibility() != Visibilities.INVISIBLE_FAKE
(descriptor.getKind().isReal() || !declared) &&
descriptor.getVisibility() != Visibilities.INVISIBLE_FAKE
} }
.map(create) .map { descriptor ->
.toList() descriptor.accept(object : DeclarationDescriptorVisitorEmptyBodies<KCallable<*>?, Nothing>() {
override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, data: Nothing?): KCallable<*>? {
if (declaredOnly && !descriptor.getKind().isReal()) return null
val isExtension = descriptor.getExtensionReceiverParameter() != null
if (isExtension && !extensions) return null
if (!isExtension && !nonExtensions) return null
return if (!isExtension) {
if (descriptor.isVar()) KMutableProperty1Impl<T, Any?>(this@KClassImpl, descriptor)
else KProperty1Impl<T, Any?>(this@KClassImpl, descriptor)
}
else {
if (descriptor.isVar()) KMutableProperty2Impl<T, Any?, Any?>(this@KClassImpl, descriptor)
else KProperty2Impl<T, Any?, Any?>(this@KClassImpl, descriptor)
}
}
}, null)
}
.filterNotNull()
override fun equals(other: Any?): Boolean = override fun equals(other: Any?): Boolean =
other is KClassImpl<*> && jClass == other.jClass other is KClassImpl<*> && jClass == other.jClass
@@ -18,10 +18,7 @@ package kotlin.reflect.jvm
import java.lang.reflect.Field import java.lang.reflect.Field
import java.lang.reflect.Method import java.lang.reflect.Method
import kotlin.reflect.KClass import kotlin.reflect.*
import kotlin.reflect.KMutableProperty
import kotlin.reflect.KPackage
import kotlin.reflect.KProperty
import kotlin.reflect.jvm.internal.KClassImpl import kotlin.reflect.jvm.internal.KClassImpl
import kotlin.reflect.jvm.internal.KMutablePropertyImpl import kotlin.reflect.jvm.internal.KMutablePropertyImpl
import kotlin.reflect.jvm.internal.KPackageImpl import kotlin.reflect.jvm.internal.KPackageImpl