Support KPackage.members, functions and properties
This commit is contained in:
+23
@@ -0,0 +1,23 @@
|
||||
import kotlin.reflect.*
|
||||
import kotlin.reflect.jvm.*
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
fun foo() {}
|
||||
fun Int.bar() {}
|
||||
val baz = 42
|
||||
val Int.quux: Int get() = this
|
||||
|
||||
fun box(): String {
|
||||
fun check(actual: Collection<KCallable<*>>, expected: Set<String>) {
|
||||
assertEquals(expected, actual.map { it.name }.toSet())
|
||||
}
|
||||
|
||||
val kp = Class.forName("_DefaultPackage").kotlinPackage ?: return "Fail: package class not found"
|
||||
|
||||
check(kp.members, setOf("bar", "baz", "foo", "box", "quux"))
|
||||
check(kp.functions, setOf("bar", "foo", "box"))
|
||||
check(kp.properties, setOf("baz"))
|
||||
check(kp.extensionProperties, setOf("quux"))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+15
@@ -3214,6 +3214,21 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection/packages")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Packages extends AbstractBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInPackages() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithStdlib/reflection/packages"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("simpleGetMembers.kt")
|
||||
public void testSimpleGetMembers() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/packages/simpleGetMembers.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection/parameters")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -42,7 +42,7 @@ public interface KClass<T> : KDeclarationContainer {
|
||||
* All functions and properties accessible in this class, including those declared in this class
|
||||
* and all of its superclasses. Does not include constructors.
|
||||
*/
|
||||
public val members: Collection<KCallable<*>>
|
||||
override val members: Collection<KCallable<*>>
|
||||
|
||||
/**
|
||||
* All constructors declared in this class.
|
||||
|
||||
@@ -20,4 +20,9 @@ package kotlin.reflect
|
||||
* Represents an entity which may contain declarations of any other entities,
|
||||
* such as a class or a package.
|
||||
*/
|
||||
public interface KDeclarationContainer
|
||||
public interface KDeclarationContainer {
|
||||
/**
|
||||
* All functions and properties accessible in this container.
|
||||
*/
|
||||
public val members: Collection<KCallable<*>>
|
||||
}
|
||||
|
||||
@@ -18,17 +18,6 @@ package kotlin.reflect
|
||||
|
||||
import kotlin.reflect.jvm.internal.KClassImpl
|
||||
|
||||
/**
|
||||
* Returns all functions declared in this class and all of its superclasses.
|
||||
* If this is a Java class, it includes all non-static methods declared in the class and the superclasses,
|
||||
* as well as static methods declared in the class.
|
||||
*/
|
||||
public val <T> KClass<T>.functions: Collection<KFunction<*>>
|
||||
get() = (this as KClassImpl<T>)
|
||||
.getMembers(declaredOnly = false, nonExtensions = true, extensions = true)
|
||||
.filterIsInstance<KFunction<*>>()
|
||||
.toList()
|
||||
|
||||
/**
|
||||
* Returns all functions declared in this class.
|
||||
* If this is a Java class, it includes both non-static and static methods.
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import kotlin.reflect.jvm.internal.KCallableContainerImpl
|
||||
|
||||
/**
|
||||
* Returns all functions declared in this container.
|
||||
* If this container is a Java class, it includes all non-static methods declared in the class
|
||||
* and the superclasses, as well as static methods declared in the class.
|
||||
*/
|
||||
public val KDeclarationContainer.functions: Collection<KFunction<*>>
|
||||
get() = (this as KCallableContainerImpl)
|
||||
.getMembers(declaredOnly = false, nonExtensions = true, extensions = true)
|
||||
.filterIsInstance<KFunction<*>>()
|
||||
.toList()
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import kotlin.reflect.jvm.internal.KPackageImpl
|
||||
|
||||
/**
|
||||
* Returns all non-extension properties declared in this package.
|
||||
*/
|
||||
public val KPackage.properties: Collection<KProperty0<*>>
|
||||
get() = (this as KPackageImpl)
|
||||
.getMembers(declaredOnly = false, nonExtensions = true, extensions = false)
|
||||
.filterIsInstance<KProperty0<*>>()
|
||||
.toList()
|
||||
|
||||
/**
|
||||
* Returns all extension properties declared in this package.
|
||||
*/
|
||||
public val KPackage.extensionProperties: Collection<KProperty1<*, *>>
|
||||
get() = (this as KPackageImpl)
|
||||
.getMembers(declaredOnly = false, nonExtensions = false, extensions = true)
|
||||
.filterIsInstance<KProperty1<*, *>>()
|
||||
.toList()
|
||||
@@ -16,9 +16,8 @@
|
||||
|
||||
package kotlin.reflect.jvm.internal
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies
|
||||
import org.jetbrains.kotlin.load.java.structure.reflect.classId
|
||||
import org.jetbrains.kotlin.load.java.structure.reflect.classLoader
|
||||
import org.jetbrains.kotlin.load.java.structure.reflect.createArrayType
|
||||
@@ -31,6 +30,7 @@ import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.JvmType.PrimitiveType.*
|
||||
import java.lang.reflect.Field
|
||||
import java.lang.reflect.Method
|
||||
import kotlin.reflect.KCallable
|
||||
import kotlin.reflect.KDeclarationContainer
|
||||
import kotlin.reflect.KotlinReflectionInternalError
|
||||
|
||||
@@ -46,6 +46,64 @@ abstract class KCallableContainerImpl : KDeclarationContainer {
|
||||
|
||||
abstract val constructorDescriptors: Collection<ConstructorDescriptor>
|
||||
|
||||
override val members: Collection<KCallable<*>>
|
||||
get() = getMembers(declaredOnly = false, nonExtensions = true, extensions = true).toList()
|
||||
|
||||
fun getMembers(declaredOnly: Boolean, nonExtensions: Boolean, extensions: Boolean): Sequence<KCallable<*>> {
|
||||
val visitor = object : DeclarationDescriptorVisitorEmptyBodies<KCallable<*>?, Unit>() {
|
||||
private fun skipCallable(descriptor: CallableMemberDescriptor): Boolean {
|
||||
if (declaredOnly && !descriptor.getKind().isReal()) return true
|
||||
|
||||
val isExtension = descriptor.getExtensionReceiverParameter() != null
|
||||
if (isExtension && !extensions) return true
|
||||
if (!isExtension && !nonExtensions) return true
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, data: Unit): KCallable<*>? {
|
||||
return if (skipCallable(descriptor)) null else createProperty(descriptor)
|
||||
}
|
||||
|
||||
override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, data: Unit): KCallable<*>? {
|
||||
return if (skipCallable(descriptor)) null else KFunctionImpl(this@KCallableContainerImpl, descriptor)
|
||||
}
|
||||
|
||||
override fun visitConstructorDescriptor(descriptor: ConstructorDescriptor, data: Unit): KCallable<*>? {
|
||||
throw IllegalStateException("No constructors should appear in this scope: $descriptor")
|
||||
}
|
||||
}
|
||||
|
||||
return scope.getAllDescriptors().asSequence()
|
||||
.filter { descriptor ->
|
||||
descriptor !is MemberDescriptor || descriptor.getVisibility() != Visibilities.INVISIBLE_FAKE
|
||||
}
|
||||
.map { descriptor ->
|
||||
descriptor.accept(visitor, Unit)
|
||||
}
|
||||
.filterNotNull()
|
||||
}
|
||||
|
||||
private fun createProperty(descriptor: PropertyDescriptor): KPropertyImpl<*> {
|
||||
val receiverCount = (descriptor.dispatchReceiverParameter?.let { 1 } ?: 0) +
|
||||
(descriptor.extensionReceiverParameter?.let { 1 } ?: 0)
|
||||
|
||||
when {
|
||||
descriptor.isVar -> when (receiverCount) {
|
||||
0 -> return KMutableProperty0Impl<Any?>(this, descriptor)
|
||||
1 -> return KMutableProperty1Impl<Any?, Any?>(this, descriptor)
|
||||
2 -> return KMutableProperty2Impl<Any?, Any?, Any?>(this, descriptor)
|
||||
}
|
||||
else -> when (receiverCount) {
|
||||
0 -> return KProperty0Impl<Any?>(this, descriptor)
|
||||
1 -> return KProperty1Impl<Any?, Any?>(this, descriptor)
|
||||
2 -> return KProperty2Impl<Any?, Any?, Any?>(this, descriptor)
|
||||
}
|
||||
}
|
||||
|
||||
throw KotlinReflectionInternalError("Unsupported property: $descriptor")
|
||||
}
|
||||
|
||||
fun findPropertyDescriptor(name: String, signature: String): PropertyDescriptor {
|
||||
val properties = scope
|
||||
.getProperties(Name.guess(name))
|
||||
|
||||
@@ -16,13 +16,12 @@
|
||||
|
||||
package kotlin.reflect.jvm.internal
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
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.KCallable
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KFunction
|
||||
import kotlin.reflect.KotlinReflectionInternalError
|
||||
@@ -84,61 +83,12 @@ class KClassImpl<T>(override val jClass: Class<T>) : KCallableContainerImpl(), K
|
||||
}
|
||||
}
|
||||
|
||||
override val members: Collection<KCallable<*>>
|
||||
get() = getMembers(declaredOnly = false, nonExtensions = true, extensions = true).toList()
|
||||
|
||||
@suppress("UNCHECKED_CAST")
|
||||
override val constructors: Collection<KFunction<T>>
|
||||
get() = constructorDescriptors.map {
|
||||
KFunctionImpl(this, it) as KFunction<T>
|
||||
}
|
||||
|
||||
fun getMembers(declaredOnly: Boolean, nonExtensions: Boolean, extensions: Boolean): Sequence<KCallable<*>> {
|
||||
val visitor = object : DeclarationDescriptorVisitorEmptyBodies<KCallable<*>?, Nothing>() {
|
||||
private fun skipCallable(descriptor: CallableMemberDescriptor): Boolean {
|
||||
if (declaredOnly && !descriptor.getKind().isReal()) return true
|
||||
|
||||
val isExtension = descriptor.getExtensionReceiverParameter() != null
|
||||
if (isExtension && !extensions) return true
|
||||
if (!isExtension && !nonExtensions) return true
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, data: Nothing?): KCallable<*>? {
|
||||
if (skipCallable(descriptor)) return null
|
||||
|
||||
return if (descriptor.getExtensionReceiverParameter() == null) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, data: Nothing?): KCallable<*>? {
|
||||
if (skipCallable(descriptor)) return null
|
||||
|
||||
return KFunctionImpl(this@KClassImpl, descriptor)
|
||||
}
|
||||
|
||||
override fun visitConstructorDescriptor(descriptor: ConstructorDescriptor, data: Nothing?): KCallable<*>? {
|
||||
throw IllegalStateException("No constructors should appear in this scope: $descriptor")
|
||||
}
|
||||
}
|
||||
|
||||
return scope.getAllDescriptors().asSequence()
|
||||
.filter { descriptor ->
|
||||
descriptor !is MemberDescriptor || descriptor.getVisibility() != Visibilities.INVISIBLE_FAKE
|
||||
}
|
||||
.map { descriptor ->
|
||||
descriptor.accept(visitor, null)
|
||||
}
|
||||
.filterNotNull()
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean =
|
||||
other is KClassImpl<*> && jClass == other.jClass
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package kotlin.reflect.jvm.internal
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import java.lang.reflect.Method
|
||||
import kotlin.jvm.internal.MutablePropertyReference0
|
||||
import kotlin.jvm.internal.PropertyReference0
|
||||
@@ -24,6 +25,8 @@ import kotlin.reflect.KMutableProperty0
|
||||
import kotlin.reflect.KProperty0
|
||||
|
||||
open class KProperty0Impl<out R> : DescriptorBasedProperty<R>, KProperty0<R>, KPropertyImpl<R> {
|
||||
constructor(container: KCallableContainerImpl, descriptor: PropertyDescriptor) : super(container, descriptor)
|
||||
|
||||
constructor(container: KCallableContainerImpl, name: String, signature: String) : super(container, name, signature)
|
||||
|
||||
override val name: String get() = descriptor.getName().asString()
|
||||
@@ -48,6 +51,8 @@ open class KProperty0Impl<out R> : DescriptorBasedProperty<R>, KProperty0<R>, KP
|
||||
}
|
||||
|
||||
open class KMutableProperty0Impl<R> : KProperty0Impl<R>, KMutableProperty0<R>, KMutablePropertyImpl<R> {
|
||||
constructor(container: KCallableContainerImpl, descriptor: PropertyDescriptor) : super(container, descriptor)
|
||||
|
||||
constructor(container: KCallableContainerImpl, name: String, signature: String) : super(container, name, signature)
|
||||
|
||||
override val setter by ReflectProperties.lazy { Setter(this) }
|
||||
|
||||
@@ -24,9 +24,9 @@ import kotlin.reflect.KMutableProperty2
|
||||
import kotlin.reflect.KProperty2
|
||||
|
||||
open class KProperty2Impl<D, E, out R> : DescriptorBasedProperty<R>, KProperty2<D, E, R>, KPropertyImpl<R> {
|
||||
constructor(container: KClassImpl<D>, name: String, signature: String) : super(container, name, signature)
|
||||
constructor(container: KCallableContainerImpl, name: String, signature: String) : super(container, name, signature)
|
||||
|
||||
constructor(container: KClassImpl<D>, descriptor: PropertyDescriptor) : super(container, descriptor)
|
||||
constructor(container: KCallableContainerImpl, descriptor: PropertyDescriptor) : super(container, descriptor)
|
||||
|
||||
override val name: String get() = descriptor.getName().asString()
|
||||
|
||||
@@ -53,9 +53,9 @@ open class KProperty2Impl<D, E, out R> : DescriptorBasedProperty<R>, KProperty2<
|
||||
|
||||
|
||||
class KMutableProperty2Impl<D, E, R> : KProperty2Impl<D, E, R>, KMutableProperty2<D, E, R>, KMutablePropertyImpl<R> {
|
||||
constructor(container: KClassImpl<D>, name: String, signature: String) : super(container, name, signature)
|
||||
constructor(container: KCallableContainerImpl, name: String, signature: String) : super(container, name, signature)
|
||||
|
||||
constructor(container: KClassImpl<D>, descriptor: PropertyDescriptor) : super(container, descriptor)
|
||||
constructor(container: KCallableContainerImpl, descriptor: PropertyDescriptor) : super(container, descriptor)
|
||||
|
||||
override val setter by ReflectProperties.lazy { Setter(this) }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user