Reflection: add KClass.typeParameters, KCallable.typeParameters

Inheritance from KCallable is removed in kt9078.kt because it was irrelevant to
the test and because it gets in the way of modification of KCallable
This commit is contained in:
Alexander Udalov
2016-07-12 16:50:12 +03:00
parent f69cc01f8e
commit 127e7ab5b7
11 changed files with 89 additions and 21 deletions
@@ -0,0 +1,36 @@
// WITH_REFLECT
import kotlin.reflect.KClass
import kotlin.test.assertEquals
class F {
fun <A> foo() {}
val <B> B.bar: B get() = this
}
class C<D> {
fun baz() {}
fun <E, G> quux() {}
}
fun get(klass: KClass<*>, memberName: String? = null): List<String> =
(if (memberName != null)
klass.members.single { it.name == memberName }.typeParameters
else
klass.typeParameters)
.map { it.name }
fun box(): String {
assertEquals(listOf(), get(F::class))
assertEquals(listOf("A"), get(F::class, "foo"))
assertEquals(listOf("B"), get(F::class, "bar"))
assertEquals(listOf("D"), get(C::class))
assertEquals(listOf(), get(C::class, "baz"))
assertEquals(listOf("E", "G"), get(C::class, "quux"))
assertEquals(listOf("T"), get(Comparable::class))
assertEquals(listOf(), get(String::class))
return "OK"
}
+2 -2
View File
@@ -1,5 +1,5 @@
// KT-9078 (NPE in control flow analysis); EA-71535
abstract class KFunctionKt9005WorkAround<out R: Any?>(private val _functionInstance: Function<R>): kotlin.reflect.KCallable<R> {
abstract class KFunctionKt9005WorkAround<out R: Any?>(private val _functionInstance: Function<R>) {
private val _reflectedFunction: kotlin.reflect.KFunction<R> = _functionInstance.<!UNRESOLVED_REFERENCE!>reflect<!>() ?: throw IllegalStateException("")
private val _parameters: List<kotlin.reflect.KParameter> = run {
@@ -9,4 +9,4 @@ abstract class KFunctionKt9005WorkAround<out R: Any?>(private val _functionInsta
}
}
}
}
}
+1 -7
View File
@@ -1,16 +1,10 @@
package
public abstract class KFunctionKt9005WorkAround</*0*/ out R> : kotlin.reflect.KCallable<R> {
public abstract class KFunctionKt9005WorkAround</*0*/ out R> {
public constructor KFunctionKt9005WorkAround</*0*/ out R>(/*0*/ _functionInstance: kotlin.Function<R>)
private final val _functionInstance: kotlin.Function<R>
private final val _parameters: kotlin.collections.List<kotlin.reflect.KParameter>
private final val _reflectedFunction: kotlin.reflect.KFunction<R>
public abstract override /*1*/ /*fake_override*/ val annotations: kotlin.collections.List<kotlin.Annotation>
public abstract override /*1*/ /*fake_override*/ val name: kotlin.String
public abstract override /*1*/ /*fake_override*/ val parameters: kotlin.collections.List<kotlin.reflect.KParameter>
public abstract override /*1*/ /*fake_override*/ val returnType: kotlin.reflect.KType
public abstract override /*1*/ /*fake_override*/ fun call(/*0*/ vararg args: kotlin.Any? /*kotlin.Array<out kotlin.Any?>*/): R
public abstract override /*1*/ /*fake_override*/ fun callBy(/*0*/ args: kotlin.collections.Map<kotlin.reflect.KParameter, kotlin.Any?>): R
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
@@ -12943,6 +12943,21 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
}
}
@TestMetadata("compiler/testData/codegen/box/reflection/typeParameters")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class TypeParameters extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInTypeParameters() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/reflection/typeParameters"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("typeParametersAndNames.kt")
public void testTypeParametersAndNames() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/typeParameters/typeParametersAndNames.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/codegen/box/reflection/types")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -44,6 +44,11 @@ public interface KCallable<out R> : KAnnotatedElement {
*/
public val returnType: KType
/**
* The list of type parameters of this callable.
*/
public val typeParameters: List<KTypeParameter>
/**
* Calls this callable with the specified list of arguments and returns the result.
* Throws an exception if the number of specified arguments is not equal to the size of [parameters],
@@ -58,6 +58,11 @@ public interface KClass<T : Any> : KDeclarationContainer, KAnnotatedElement, KCl
*/
public val objectInstance: T?
/**
* The list of type parameters of this class. This list does *not* include type parameters of outer classes.
*/
public val typeParameters: List<KTypeParameter>
/**
* Returns `true` if [other] is a [KClass] instance representing the same class on a given platform.
*
@@ -20,10 +20,7 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotated
import java.lang.reflect.Type
import java.util.*
import kotlin.reflect.KCallable
import kotlin.reflect.KParameter
import kotlin.reflect.KType
import kotlin.reflect.KotlinReflectionInternalError
import kotlin.reflect.*
import kotlin.reflect.jvm.javaType
internal interface KCallableImpl<out R> : KCallable<R>, KAnnotatedElementImpl {
@@ -62,6 +59,9 @@ internal interface KCallableImpl<out R> : KCallable<R>, KAnnotatedElementImpl {
override val returnType: KType
get() = KTypeImpl(descriptor.returnType!!) { caller.returnType }
override val typeParameters: List<KTypeParameter>
get() = descriptor.typeParameters.map(::KTypeParameterImpl)
@Suppress("UNCHECKED_CAST")
override fun call(vararg args: Any?): R = reflectionCall {
return caller.call(args) as R
@@ -27,10 +27,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.serialization.deserialization.findClassAcrossModuleDependencies
import kotlin.reflect.KCallable
import kotlin.reflect.KClass
import kotlin.reflect.KFunction
import kotlin.reflect.KotlinReflectionInternalError
import kotlin.reflect.*
internal class KClassImpl<T : Any>(override val jClass: Class<T>) :
KDeclarationContainerImpl(), KClass<T>, KClassifierImpl, KAnnotatedElementImpl {
@@ -139,6 +136,9 @@ internal class KClassImpl<T : Any>(override val jClass: Class<T>) :
override val objectInstance: T?
get() = objectInstance_()
override val typeParameters: List<KTypeParameter>
get() = descriptor.declaredTypeParameters.map(::KTypeParameterImpl)
override fun equals(other: Any?): Boolean =
other is KClassImpl<*> && jClass == other.jClass
@@ -83,6 +83,12 @@ public abstract class CallableReference implements KCallable {
return getReflected().getAnnotations();
}
@NotNull
@Override
public List<KTypeParameter> getTypeParameters() {
return getReflected().getTypeParameters();
}
@Override
public Object call(@NotNull Object... args) {
return getReflected().call(args);
@@ -19,6 +19,7 @@ package kotlin.jvm.internal
import kotlin.reflect.KCallable
import kotlin.reflect.KClass
import kotlin.reflect.KFunction
import kotlin.reflect.KTypeParameter
class ClassReference(override val jClass: Class<*>) : KClass<Any>, ClassBasedDeclarationContainer {
override val simpleName: String?
@@ -42,6 +43,9 @@ class ClassReference(override val jClass: Class<*>) : KClass<Any>, ClassBasedDec
override val objectInstance: Any?
get() = error()
override val typeParameters: List<KTypeParameter>
get() = error()
private fun error(): Nothing = throw KotlinReflectionNotSupportedError()
override fun equals(other: Any?) =
@@ -17,10 +17,7 @@
package kotlin.jvm.internal;
import kotlin.jvm.KotlinReflectionNotSupportedError;
import kotlin.reflect.KDeclarationContainer;
import kotlin.reflect.KFunction;
import kotlin.reflect.KParameter;
import kotlin.reflect.KType;
import kotlin.reflect.*;
import org.jetbrains.annotations.NotNull;
import java.lang.annotation.Annotation;
@@ -71,6 +68,12 @@ public class FunctionReference extends FunctionImpl implements KFunction {
return getReflected().getAnnotations();
}
@NotNull
@Override
public List<KTypeParameter> getTypeParameters() {
return getReflected().getTypeParameters();
}
@Override
public Object call(@NotNull Object... args) {
return getReflected().call(args);