diff --git a/compiler/testData/codegen/boxWithJava/reflection/javaStaticField/K.kt b/compiler/testData/codegen/boxWithJava/reflection/javaStaticField/K.kt index 869e71619f0..9055ef9c1a1 100644 --- a/compiler/testData/codegen/boxWithJava/reflection/javaStaticField/K.kt +++ b/compiler/testData/codegen/boxWithJava/reflection/javaStaticField/K.kt @@ -4,6 +4,8 @@ fun box(): String { val f = J::x assertEquals("x", f.name) + assertEquals(f, J::class.members.single { it.name == "x" }) + f.set("OK") assertEquals("OK", J.x) assertEquals("OK", f.getter()) diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/memberExtensionToString.kt b/compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/memberExtensionToString.kt index 4ea9ba0ddfc..a5df279344b 100644 --- a/compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/memberExtensionToString.kt +++ b/compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/memberExtensionToString.kt @@ -1,4 +1,5 @@ import kotlin.reflect.jvm.kotlin +import kotlin.reflect.* class A { var String.id: String diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/properties/accessors/memberExtensions.kt b/compiler/testData/codegen/boxWithStdlib/reflection/properties/accessors/memberExtensions.kt index fcd53d24ef5..86d459b9192 100644 --- a/compiler/testData/codegen/boxWithStdlib/reflection/properties/accessors/memberExtensions.kt +++ b/compiler/testData/codegen/boxWithStdlib/reflection/properties/accessors/memberExtensions.kt @@ -1,4 +1,4 @@ -import kotlin.reflect.KMutableProperty2 +import kotlin.reflect.* import kotlin.test.assertEquals class C(var state: String) { diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/properties/genericClassLiteralPropertyReceiverIsStar.kt b/compiler/testData/codegen/boxWithStdlib/reflection/properties/genericClassLiteralPropertyReceiverIsStar.kt index e97248ae99b..471038730e4 100644 --- a/compiler/testData/codegen/boxWithStdlib/reflection/properties/genericClassLiteralPropertyReceiverIsStar.kt +++ b/compiler/testData/codegen/boxWithStdlib/reflection/properties/genericClassLiteralPropertyReceiverIsStar.kt @@ -1,10 +1,10 @@ -import kotlin.reflect.KProperty1 +import kotlin.reflect.* class A { val result = "OK" } fun box(): String { - val k : KProperty1, *> = A::class.properties.single() + val k: KProperty1, *> = A::class.properties.single() return k.get(A()) as String } diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/properties/getExtensionPropertiesMutableVsReadonly.kt b/compiler/testData/codegen/boxWithStdlib/reflection/properties/getExtensionPropertiesMutableVsReadonly.kt index 2ebf098af3c..6e48a9e9a63 100644 --- a/compiler/testData/codegen/boxWithStdlib/reflection/properties/getExtensionPropertiesMutableVsReadonly.kt +++ b/compiler/testData/codegen/boxWithStdlib/reflection/properties/getExtensionPropertiesMutableVsReadonly.kt @@ -1,5 +1,5 @@ import kotlin.reflect.jvm.kotlin -import kotlin.reflect.KMutableProperty2 +import kotlin.reflect.* var storage = "before" diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/properties/getPropertiesMutableVsReadonly.kt b/compiler/testData/codegen/boxWithStdlib/reflection/properties/getPropertiesMutableVsReadonly.kt index fb764361b30..44fcc55c210 100644 --- a/compiler/testData/codegen/boxWithStdlib/reflection/properties/getPropertiesMutableVsReadonly.kt +++ b/compiler/testData/codegen/boxWithStdlib/reflection/properties/getPropertiesMutableVsReadonly.kt @@ -1,5 +1,5 @@ import kotlin.reflect.jvm.kotlin -import kotlin.reflect.KMutableProperty1 +import kotlin.reflect.* class A(val readonly: String) { var mutable: String = "before" diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/properties/memberAndMemberExtensionWithSameName.kt b/compiler/testData/codegen/boxWithStdlib/reflection/properties/memberAndMemberExtensionWithSameName.kt index a60072738bd..c888f6f8d80 100644 --- a/compiler/testData/codegen/boxWithStdlib/reflection/properties/memberAndMemberExtensionWithSameName.kt +++ b/compiler/testData/codegen/boxWithStdlib/reflection/properties/memberAndMemberExtensionWithSameName.kt @@ -1,6 +1,5 @@ import kotlin.reflect.jvm.kotlin -import kotlin.reflect.KProperty1 -import kotlin.reflect.KProperty2 +import kotlin.reflect.* class A { val foo: String = "member" diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/properties/privateClassVal.kt b/compiler/testData/codegen/boxWithStdlib/reflection/properties/privateClassVal.kt index 6a0d84da88d..59d307a73be 100644 --- a/compiler/testData/codegen/boxWithStdlib/reflection/properties/privateClassVal.kt +++ b/compiler/testData/codegen/boxWithStdlib/reflection/properties/privateClassVal.kt @@ -1,5 +1,4 @@ -import kotlin.reflect.IllegalPropertyAccessException -import kotlin.reflect.KProperty1 +import kotlin.reflect.* import kotlin.reflect.jvm.accessible class Result { diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/properties/privateClassVar.kt b/compiler/testData/codegen/boxWithStdlib/reflection/properties/privateClassVar.kt index 81f336e698f..accd3c6f4cd 100644 --- a/compiler/testData/codegen/boxWithStdlib/reflection/properties/privateClassVar.kt +++ b/compiler/testData/codegen/boxWithStdlib/reflection/properties/privateClassVar.kt @@ -1,5 +1,4 @@ -import kotlin.reflect.IllegalPropertyAccessException -import kotlin.reflect.KMutableProperty1 +import kotlin.reflect.* import kotlin.reflect.jvm.accessible class A { diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/properties/privateFakeOverrideFromSuperclass.kt b/compiler/testData/codegen/boxWithStdlib/reflection/properties/privateFakeOverrideFromSuperclass.kt index 718470fbfbd..a0319b42cf3 100644 --- a/compiler/testData/codegen/boxWithStdlib/reflection/properties/privateFakeOverrideFromSuperclass.kt +++ b/compiler/testData/codegen/boxWithStdlib/reflection/properties/privateFakeOverrideFromSuperclass.kt @@ -1,3 +1,5 @@ +import kotlin.reflect.* + open class A(private val p: Int) class B : A(42) diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/properties/protectedClassVar.kt b/compiler/testData/codegen/boxWithStdlib/reflection/properties/protectedClassVar.kt index 578b45f3e2e..486b5c9f8b5 100644 --- a/compiler/testData/codegen/boxWithStdlib/reflection/properties/protectedClassVar.kt +++ b/compiler/testData/codegen/boxWithStdlib/reflection/properties/protectedClassVar.kt @@ -1,6 +1,5 @@ -import kotlin.reflect.IllegalPropertyAccessException +import kotlin.reflect.* import kotlin.reflect.jvm.accessible -import kotlin.reflect.KMutableProperty1 class A(param: String) { protected var v: String = param diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/properties/simpleGetProperties.kt b/compiler/testData/codegen/boxWithStdlib/reflection/properties/simpleGetProperties.kt index a03f90a6c86..86d25740c52 100644 --- a/compiler/testData/codegen/boxWithStdlib/reflection/properties/simpleGetProperties.kt +++ b/compiler/testData/codegen/boxWithStdlib/reflection/properties/simpleGetProperties.kt @@ -1,3 +1,4 @@ +import kotlin.reflect.* import kotlin.reflect.jvm.kotlin class A(param: String) { diff --git a/compiler/testData/codegen/reflection/classLoaders/differentClassLoaders.kt b/compiler/testData/codegen/reflection/classLoaders/differentClassLoaders.kt index 6e2081d84d8..83e8f285ded 100644 --- a/compiler/testData/codegen/reflection/classLoaders/differentClassLoaders.kt +++ b/compiler/testData/codegen/reflection/classLoaders/differentClassLoaders.kt @@ -1,6 +1,6 @@ package test -import kotlin.reflect.KClass +import kotlin.reflect.* import kotlin.test.* class K(val p: String) diff --git a/compiler/testData/diagnostics/tests/reflection/noReflectionInClassPath.kt b/compiler/testData/diagnostics/tests/reflection/noReflectionInClassPath.kt index 2e37aa21352..df9f659e917 100644 --- a/compiler/testData/diagnostics/tests/reflection/noReflectionInClassPath.kt +++ b/compiler/testData/diagnostics/tests/reflection/noReflectionInClassPath.kt @@ -17,5 +17,6 @@ fun n10() = (Foo::func).invoke(Foo("")) fun n11() = (Foo::func)(Foo("")) fun y01() = Foo::prop.getter -fun y02() = Foo::class.properties +fun y02() = Foo::class.members fun y03() = Foo::class.simpleName +fun y04() = Foo::class.properties diff --git a/compiler/testData/diagnostics/tests/reflection/noReflectionInClassPath.txt b/compiler/testData/diagnostics/tests/reflection/noReflectionInClassPath.txt index 6b6d957333b..d5dd59a4105 100644 --- a/compiler/testData/diagnostics/tests/reflection/noReflectionInClassPath.txt +++ b/compiler/testData/diagnostics/tests/reflection/noReflectionInClassPath.txt @@ -12,8 +12,9 @@ internal fun n09(/*0*/ p: kotlin.reflect.KProperty2 -internal fun y02(): kotlin.Collection> +internal fun y02(): kotlin.Collection> internal fun y03(): kotlin.String? +internal fun y04(): [ERROR : Error function type] internal final class Foo { public constructor Foo(/*0*/ prop: kotlin.Any) diff --git a/core/builtins/src/kotlin/reflect/KClass.kt b/core/builtins/src/kotlin/reflect/KClass.kt index 965a5470f47..0e6512c1499 100644 --- a/core/builtins/src/kotlin/reflect/KClass.kt +++ b/core/builtins/src/kotlin/reflect/KClass.kt @@ -39,12 +39,8 @@ public interface KClass : KDeclarationContainer { 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> - - /** - * Returns extension properties declared in this class and all of its superclasses. - */ - public val extensionProperties: Collection> + public val members: Collection> } diff --git a/core/reflection.jvm/src/kotlin/reflect/KClassExtensions.kt b/core/reflection.jvm/src/kotlin/reflect/KClassExtensions.kt index ddddc04a511..6e8b6c00cde 100644 --- a/core/reflection.jvm/src/kotlin/reflect/KClassExtensions.kt +++ b/core/reflection.jvm/src/kotlin/reflect/KClassExtensions.kt @@ -18,14 +18,38 @@ package kotlin.reflect import kotlin.reflect.jvm.internal.KClassImpl +/** + * Returns non-extension properties declared in this class and all of its superclasses. + */ +public val KClass.properties: Collection> + get() = (this as KClassImpl) + .getMembers(declaredOnly = false, nonExtensions = true, extensions = false) + .filterIsInstance>() + .toList() + +/** + * Returns extension properties declared in this class and all of its superclasses. + */ +public val KClass.extensionProperties: Collection> + get() = (this as KClassImpl) + .getMembers(declaredOnly = false, nonExtensions = false, extensions = true) + .filterIsInstance>() + .toList() + /** * Returns non-extension properties declared in this class. */ public val KClass.declaredProperties: Collection> - get() = (this as KClassImpl).getProperties(declared = true) + get() = (this as KClassImpl) + .getMembers(declaredOnly = true, nonExtensions = true, extensions = false) + .filterIsInstance>() + .toList() /** * Returns extension properties declared in this class. */ public val KClass.declaredExtensionProperties: Collection> - get() = (this as KClassImpl).getExtensionProperties(declared = true) + get() = (this as KClassImpl) + .getMembers(declaredOnly = true, nonExtensions = false, extensions = true) + .filterIsInstance>() + .toList() diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KClassImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KClassImpl.kt index a7f8f1cc912..74b8b6fc8ba 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KClassImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KClassImpl.kt @@ -16,13 +16,17 @@ package kotlin.reflect.jvm.internal +import org.jetbrains.kotlin.descriptors.MemberDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.Visibilities +import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.resolve.scopes.ChainedScope import org.jetbrains.kotlin.resolve.scopes.JetScope import org.jetbrains.kotlin.serialization.deserialization.findClassAcrossModuleDependencies -import kotlin.reflect.* +import kotlin.reflect.KCallable +import kotlin.reflect.KClass +import kotlin.reflect.KotlinReflectionInternalError class KClassImpl(override val jClass: Class) : KCallableContainerImpl(), KClass { val descriptor by ReflectProperties.lazySoft { @@ -72,34 +76,35 @@ class KClassImpl(override val jClass: Class) : KCallableContainerImpl(), K } } - override val properties: Collection> - get() = getProperties(declared = false) + override val members: Collection> + get() = getMembers(declaredOnly = false, nonExtensions = true, extensions = true).toList() - override val extensionProperties: Collection> - get() = getExtensionProperties(declared = false) - - fun getProperties(declared: Boolean): Collection> = - getProperties(extension = false, declared = declared) { descriptor -> - if (descriptor.isVar()) KMutableProperty1Impl(this, descriptor) - else KProperty1Impl(this, descriptor) - } - - fun getExtensionProperties(declared: Boolean): Collection> = - getProperties(extension = true, declared = declared) { descriptor -> - if (descriptor.isVar()) KMutableProperty2Impl(this, descriptor) - else KProperty2Impl(this, descriptor) - } - - private fun

> getProperties(extension: Boolean, declared: Boolean, create: (PropertyDescriptor) -> P): Collection

= + fun getMembers(declaredOnly: Boolean, nonExtensions: Boolean, extensions: Boolean): Sequence> = scope.getAllDescriptors().asSequence() - .filterIsInstance() .filter { descriptor -> - (descriptor.getExtensionReceiverParameter() != null) == extension && - (descriptor.getKind().isReal() || !declared) && - descriptor.getVisibility() != Visibilities.INVISIBLE_FAKE + descriptor !is MemberDescriptor || descriptor.getVisibility() != Visibilities.INVISIBLE_FAKE } - .map(create) - .toList() + .map { descriptor -> + descriptor.accept(object : DeclarationDescriptorVisitorEmptyBodies?, 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(this@KClassImpl, descriptor) + else KProperty1Impl(this@KClassImpl, descriptor) + } + else { + if (descriptor.isVar()) KMutableProperty2Impl(this@KClassImpl, descriptor) + else KProperty2Impl(this@KClassImpl, descriptor) + } + } + }, null) + } + .filterNotNull() override fun equals(other: Any?): Boolean = other is KClassImpl<*> && jClass == other.jClass diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/mapping.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/mapping.kt index 7bb9dd39767..da985344e3e 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/mapping.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/mapping.kt @@ -18,10 +18,7 @@ package kotlin.reflect.jvm import java.lang.reflect.Field import java.lang.reflect.Method -import kotlin.reflect.KClass -import kotlin.reflect.KMutableProperty -import kotlin.reflect.KPackage -import kotlin.reflect.KProperty +import kotlin.reflect.* import kotlin.reflect.jvm.internal.KClassImpl import kotlin.reflect.jvm.internal.KMutablePropertyImpl import kotlin.reflect.jvm.internal.KPackageImpl