Support mapping of KType to j.l.reflect.Type
This commit is contained in:
+11
@@ -0,0 +1,11 @@
|
||||
public class J {
|
||||
private final int param;
|
||||
|
||||
public J(int param) {
|
||||
this.param = param;
|
||||
}
|
||||
|
||||
public String foo(int[] arr, Object[] arr2, Integer y) {
|
||||
return "" + param + arr[0] + arr2[0] + y;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import kotlin.reflect.jvm.*
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
fun box(): String {
|
||||
val f = J::foo
|
||||
assertEquals(
|
||||
listOf(javaClass<J>(), javaClass<IntArray>(), javaClass<Array<Any>>(), javaClass<Integer>()),
|
||||
f.parameters.map { it.type.javaType }
|
||||
)
|
||||
assertEquals(javaClass<String>(), f.returnType.javaType)
|
||||
|
||||
assertEquals("01A2", f.call(J(0), intArrayOf(1), arrayOf("A"), 2))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
public class J {
|
||||
public static String foo(int x, int[] arr, Object[] arr2) {
|
||||
return "" + x + arr[0] + arr2[0];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import kotlin.reflect.jvm.*
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
fun box(): String {
|
||||
val f = J::foo
|
||||
assertEquals(listOf(Integer.TYPE, javaClass<IntArray>(), javaClass<Array<Any>>()), f.parameters.map { it.type.javaType })
|
||||
assertEquals(javaClass<String>(), f.returnType.javaType)
|
||||
|
||||
assertEquals("01A", f.call(0, intArrayOf(1), arrayOf("A")))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// FULL_JDK
|
||||
|
||||
import java.lang.reflect.GenericArrayType
|
||||
import java.lang.reflect.TypeVariable
|
||||
import java.lang.reflect.ParameterizedType
|
||||
import kotlin.reflect.jvm.*
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
fun foo(strings: Array<String>, integers: Array<Int>, objectArrays: Array<Array<Any>>) {}
|
||||
|
||||
fun bar(): Array<List<String>> = null!!
|
||||
class A<T> {
|
||||
fun baz(): Array<T> = null!!
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(javaClass<Array<String>>(), ::foo.parameters[0].type.javaType)
|
||||
assertEquals(javaClass<Array<Int>>(), ::foo.parameters[1].type.javaType)
|
||||
assertEquals(javaClass<Array<Array<Any>>>(), ::foo.parameters[2].type.javaType)
|
||||
|
||||
val g = ::bar.returnType.javaType
|
||||
if (g !is GenericArrayType || g.genericComponentType !is ParameterizedType)
|
||||
return "Fail: should be array of parameterized type, but was $g (${g.javaClass})"
|
||||
|
||||
val h = A<String>::baz.returnType.javaType
|
||||
if (h !is GenericArrayType || h.genericComponentType !is TypeVariable<*>)
|
||||
return "Fail: should be array of type variable, but was $h (${h.javaClass})"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
import kotlin.reflect.*
|
||||
import kotlin.reflect.jvm.*
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class A(d: Double, s: String, parent: A?) {
|
||||
class Nested(a: A)
|
||||
inner class Inner(nested: Nested)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(listOf(java.lang.Double.TYPE, javaClass<String>(), javaClass<A>()), ::A.parameters.map { it.type.javaType })
|
||||
assertEquals(listOf(javaClass<A>()), A::Nested.parameters.map { it.type.javaType })
|
||||
assertEquals(listOf(javaClass<A>(), javaClass<A.Nested>()), A::Inner.parameters.map { it.type.javaType })
|
||||
|
||||
assertEquals(javaClass<A>(), ::A.returnType.javaType)
|
||||
assertEquals(javaClass<A.Nested>(), A::Nested.returnType.javaType)
|
||||
assertEquals(javaClass<A.Inner>(), A::Inner.returnType.javaType)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
import kotlin.platform.platformStatic as static
|
||||
import kotlin.reflect.jvm.javaType
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class A {
|
||||
fun foo(t: Long?): Long = t!!
|
||||
}
|
||||
|
||||
object O {
|
||||
static fun bar(a: A): String = ""
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(listOf(javaClass<A>(), javaClass<java.lang.Long>()), A::foo.parameters.map { it.type.javaType })
|
||||
assertEquals(listOf(javaClass<O>(), javaClass<A>()), O::bar.parameters.map { it.type.javaType })
|
||||
|
||||
assertEquals(java.lang.Long.TYPE, A::foo.returnType.javaType)
|
||||
assertEquals(javaClass<String>(), O::bar.returnType.javaType)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Vendored
+23
@@ -0,0 +1,23 @@
|
||||
import kotlin.reflect.jvm.*
|
||||
import kotlin.test.*
|
||||
|
||||
interface I {
|
||||
fun foo(): Any
|
||||
}
|
||||
|
||||
class A : I {
|
||||
override fun foo(): Int = 0
|
||||
fun bar(x: Long): Int = x.toInt()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(javaClass<Integer>(), A::foo.returnType.javaType)
|
||||
assertNotEquals(Integer.TYPE, A::foo.returnType.javaType)
|
||||
|
||||
assertNotEquals(javaClass<Integer>(), A::bar.returnType.javaType)
|
||||
assertEquals(Integer.TYPE, A::bar.returnType.javaType)
|
||||
|
||||
assertEquals(java.lang.Long.TYPE, A::bar.parameters.last().type.javaType)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
// FULL_JDK
|
||||
|
||||
import java.lang.reflect.ParameterizedType
|
||||
import kotlin.platform.platformStatic as static
|
||||
import kotlin.reflect.*
|
||||
import kotlin.reflect.jvm.javaType
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class A(private var foo: List<String>)
|
||||
|
||||
object O {
|
||||
private static var bar: List<String> = listOf()
|
||||
}
|
||||
|
||||
fun topLevel(): List<String> = listOf()
|
||||
fun Any.extension(): List<String> = listOf()
|
||||
|
||||
fun assertGenericType(type: KType) {
|
||||
val javaType = type.javaType
|
||||
if (javaType !is ParameterizedType) {
|
||||
throw AssertionError("Type should be a parameterized type, but was $javaType (${javaType.javaClass})")
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val foo = A::class.members.single { it.name == "foo" } as KMutableProperty<*>
|
||||
assertGenericType(foo.returnType)
|
||||
assertGenericType(foo.getter.returnType)
|
||||
assertGenericType(foo.setter.parameters.last().type)
|
||||
|
||||
val bar = O::class.members.single { it.name == "bar" } as KMutableProperty<*>
|
||||
assertGenericType(bar.returnType)
|
||||
assertGenericType(bar.getter.returnType)
|
||||
assertGenericType(bar.setter.parameters.last().type)
|
||||
|
||||
assertGenericType(::topLevel.returnType)
|
||||
assertGenericType(Any::extension.returnType)
|
||||
assertGenericType(::A.parameters.single().type)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
import kotlin.platform.platformStatic as static
|
||||
import kotlin.reflect.KMutableProperty
|
||||
import kotlin.reflect.jvm.javaType
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class A(private var foo: String)
|
||||
|
||||
object O {
|
||||
private static var bar: String = ""
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val foo = A::class.members.single { it.name == "foo" } as KMutableProperty<*>
|
||||
assertEquals(listOf(javaClass<A>()), foo.parameters.map { it.type.javaType })
|
||||
assertEquals(listOf(javaClass<A>()), foo.getter.parameters.map { it.type.javaType })
|
||||
assertEquals(listOf(javaClass<A>(), javaClass<String>()), foo.setter.parameters.map { it.type.javaType })
|
||||
|
||||
val bar = O::class.members.single { it.name == "bar" } as KMutableProperty<*>
|
||||
assertEquals(listOf(javaClass<O>()), bar.parameters.map { it.type.javaType })
|
||||
assertEquals(listOf(javaClass<O>()), bar.getter.parameters.map { it.type.javaType })
|
||||
assertEquals(listOf(javaClass<O>(), javaClass<String>()), bar.setter.parameters.map { it.type.javaType })
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
import kotlin.reflect.jvm.*
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
fun free(s: String): Int = s.length()
|
||||
|
||||
fun Any.extension() {}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(java.lang.Integer.TYPE, ::free.returnType.javaType)
|
||||
assertEquals(javaClass<String>(), ::free.parameters.single().type.javaType)
|
||||
|
||||
assertEquals(javaClass<Any>(), Any::extension.parameters.single().type.javaType)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
// FULL_JDK
|
||||
|
||||
import java.lang.reflect.TypeVariable
|
||||
import kotlin.reflect.jvm.*
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class A<T> {
|
||||
fun foo(t: T) {}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val f = A<String>::foo
|
||||
val t = f.parameters.last().type.javaType
|
||||
if (t !is TypeVariable<*>) return "Fail, t should be a type variable: $t"
|
||||
|
||||
assertEquals("T", t.name)
|
||||
assertEquals("A", (t.genericDeclaration as Class<*>).name)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import kotlin.reflect.jvm.*
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
fun foo(unitParam: Unit, nullableUnitParam: Unit?): Unit {}
|
||||
|
||||
var bar: Unit = Unit
|
||||
|
||||
fun box(): String {
|
||||
assert(javaClass<Unit>() != java.lang.Void.TYPE)
|
||||
|
||||
assertEquals(javaClass<Unit>(), ::foo.parameters[0].type.javaType)
|
||||
assertEquals(javaClass<Unit>(), ::foo.parameters[1].type.javaType)
|
||||
assertEquals(java.lang.Void.TYPE, ::foo.returnType.javaType)
|
||||
|
||||
assertEquals(javaClass<Unit>(), ::bar.returnType.javaType)
|
||||
assertEquals(javaClass<Unit>(), ::bar.getter.returnType.javaType)
|
||||
assertEquals(javaClass<Unit>(), ::bar.setter.parameters.single().type.javaType)
|
||||
assertEquals(java.lang.Void.TYPE, ::bar.setter.returnType.javaType)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+12
@@ -267,6 +267,18 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithJava/reflection"), Pattern.compile("^([^\\.]+)$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("callInstanceJavaMethod")
|
||||
public void testCallInstanceJavaMethod() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/reflection/callInstanceJavaMethod/");
|
||||
doTestWithJava(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("callStaticJavaMethod")
|
||||
public void testCallStaticJavaMethod() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/reflection/callStaticJavaMethod/");
|
||||
doTestWithJava(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("functionReferenceErasedToKFunction")
|
||||
public void testFunctionReferenceErasedToKFunction() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/reflection/functionReferenceErasedToKFunction/");
|
||||
|
||||
+63
@@ -3359,6 +3359,69 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/mapping/topLevelProperty.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection/mapping/types")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Types extends AbstractBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInTypes() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithStdlib/reflection/mapping/types"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("array.kt")
|
||||
public void testArray() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/mapping/types/array.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("constructors.kt")
|
||||
public void testConstructors() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/mapping/types/constructors.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("memberFunctions.kt")
|
||||
public void testMemberFunctions() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/mapping/types/memberFunctions.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("overrideAnyWithPrimitive.kt")
|
||||
public void testOverrideAnyWithPrimitive() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/mapping/types/overrideAnyWithPrimitive.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("parameterizedTypes.kt")
|
||||
public void testParameterizedTypes() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/mapping/types/parameterizedTypes.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("propertyAccessors.kt")
|
||||
public void testPropertyAccessors() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/mapping/types/propertyAccessors.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("topLevelFunctions.kt")
|
||||
public void testTopLevelFunctions() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/mapping/types/topLevelFunctions.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("typeParameters.kt")
|
||||
public void testTypeParameters() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/mapping/types/typeParameters.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("unit.kt")
|
||||
public void testUnit() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/mapping/types/unit.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny")
|
||||
|
||||
@@ -17,20 +17,23 @@
|
||||
package kotlin.reflect.jvm.internal
|
||||
|
||||
import java.lang.reflect.Member
|
||||
import java.lang.reflect.Modifier
|
||||
import java.lang.reflect.Type
|
||||
import java.lang.reflect.Constructor as ReflectConstructor
|
||||
import java.lang.reflect.Field as ReflectField
|
||||
import java.lang.reflect.Method as ReflectMethod
|
||||
|
||||
internal sealed class FunctionCaller(
|
||||
private val expectedArgumentNumber: Int
|
||||
) {
|
||||
internal abstract class FunctionCaller {
|
||||
abstract val member: Member
|
||||
|
||||
abstract val returnType: Type
|
||||
abstract val parameterTypes: List<Type>
|
||||
|
||||
abstract fun call(args: Array<*>): Any?
|
||||
|
||||
protected open fun checkArguments(args: Array<*>) {
|
||||
if (expectedArgumentNumber != args.size()) {
|
||||
throw IllegalArgumentException("Callable expects $expectedArgumentNumber arguments, but ${args.size()} were provided.")
|
||||
if (parameterTypes.size() != args.size()) {
|
||||
throw IllegalArgumentException("Callable expects ${parameterTypes.size()} arguments, but ${args.size()} were provided.")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,9 +43,16 @@ internal sealed class FunctionCaller(
|
||||
}
|
||||
}
|
||||
|
||||
class Constructor(val constructor: ReflectConstructor<*>) : FunctionCaller(constructor.parameterTypes.size()) {
|
||||
class Constructor(val constructor: ReflectConstructor<*>) : FunctionCaller() {
|
||||
override val member: Member get() = constructor
|
||||
|
||||
override val returnType = constructor.declaringClass
|
||||
|
||||
override val parameterTypes =
|
||||
if (returnType.declaringClass == null || Modifier.isStatic(returnType.modifiers))
|
||||
constructor.genericParameterTypes.toList()
|
||||
else listOf(returnType.declaringClass, *constructor.genericParameterTypes)
|
||||
|
||||
override fun call(args: Array<*>): Any? {
|
||||
checkArguments(args)
|
||||
return constructor.newInstance(*args)
|
||||
@@ -51,10 +61,17 @@ internal sealed class FunctionCaller(
|
||||
|
||||
abstract class Method(
|
||||
val method: ReflectMethod,
|
||||
requiresInstance: Boolean
|
||||
) : FunctionCaller(method.parameterTypes.size() + (if (requiresInstance) 1 else 0)) {
|
||||
private val requiresInstance: Boolean
|
||||
) : FunctionCaller() {
|
||||
override val member: Member get() = method
|
||||
private val isVoidMethod = method.returnType == Void.TYPE
|
||||
|
||||
override val returnType = method.genericReturnType
|
||||
|
||||
override val parameterTypes =
|
||||
if (requiresInstance) listOf(method.declaringClass, *method.genericParameterTypes)
|
||||
else method.genericParameterTypes.toList()
|
||||
|
||||
private val isVoidMethod = returnType == Void.TYPE
|
||||
|
||||
protected fun callMethod(instance: Any?, args: Array<*>): Any? {
|
||||
val result = method.invoke(instance, *args)
|
||||
@@ -86,14 +103,19 @@ internal sealed class FunctionCaller(
|
||||
}
|
||||
}
|
||||
|
||||
abstract class FieldAccessor(val field: ReflectField, expectedArgumentNumber: Int) : FunctionCaller(expectedArgumentNumber) {
|
||||
abstract class FieldAccessor(val field: ReflectField) : FunctionCaller() {
|
||||
override val member: Member get() = field
|
||||
}
|
||||
|
||||
abstract class FieldGetter(
|
||||
field: ReflectField,
|
||||
private val requiresInstance: Boolean
|
||||
) : FieldAccessor(field, if (requiresInstance) 1 else 0) {
|
||||
) : FieldAccessor(field) {
|
||||
override val returnType = field.genericType
|
||||
|
||||
override val parameterTypes =
|
||||
if (requiresInstance) listOf(field.declaringClass) else listOf()
|
||||
|
||||
override fun call(args: Array<*>): Any? {
|
||||
checkArguments(args)
|
||||
return field.get(if (requiresInstance) args.first() else null)
|
||||
@@ -104,7 +126,13 @@ internal sealed class FunctionCaller(
|
||||
field: ReflectField,
|
||||
private val notNull: Boolean,
|
||||
private val requiresInstance: Boolean
|
||||
) : FieldAccessor(field, if (requiresInstance) 2 else 1) {
|
||||
) : FieldAccessor(field) {
|
||||
override val returnType: Type get() = Void.TYPE
|
||||
|
||||
override val parameterTypes =
|
||||
if (requiresInstance) listOf(field.declaringClass, field.genericType)
|
||||
else listOf(field.genericType)
|
||||
|
||||
override fun checkArguments(args: Array<*>) {
|
||||
super.checkArguments(args)
|
||||
if (notNull && args.last() == null) {
|
||||
|
||||
@@ -36,15 +36,15 @@ interface KCallableImpl<out R> : KCallable<R>, KAnnotatedElementImpl {
|
||||
var index = 0
|
||||
|
||||
if (descriptor.dispatchReceiverParameter != null) {
|
||||
result.add(KParameterImpl(index++) { descriptor.dispatchReceiverParameter!! })
|
||||
result.add(KParameterImpl(this, index++) { descriptor.dispatchReceiverParameter!! })
|
||||
}
|
||||
|
||||
if (descriptor.extensionReceiverParameter != null) {
|
||||
result.add(KParameterImpl(index++) { descriptor.extensionReceiverParameter!! })
|
||||
result.add(KParameterImpl(this, index++) { descriptor.extensionReceiverParameter!! })
|
||||
}
|
||||
|
||||
for (i in descriptor.valueParameters.indices) {
|
||||
result.add(KParameterImpl(index++) { descriptor.valueParameters[i] })
|
||||
result.add(KParameterImpl(this, index++) { descriptor.valueParameters[i] })
|
||||
}
|
||||
|
||||
result.trimToSize()
|
||||
@@ -52,7 +52,7 @@ interface KCallableImpl<out R> : KCallable<R>, KAnnotatedElementImpl {
|
||||
}
|
||||
|
||||
override val returnType: KType
|
||||
get() = KTypeImpl(descriptor.returnType!!)
|
||||
get() = KTypeImpl(descriptor.returnType!!) { caller.returnType }
|
||||
|
||||
@suppress("UNCHECKED_CAST")
|
||||
override fun call(vararg args: Any?): R = reflectionCall {
|
||||
|
||||
@@ -23,8 +23,9 @@ import kotlin.reflect.KParameter
|
||||
import kotlin.reflect.KType
|
||||
|
||||
class KParameterImpl(
|
||||
val callable: KCallableImpl<*>,
|
||||
override val index: Int,
|
||||
private val computeDescriptor: () -> ParameterDescriptor
|
||||
computeDescriptor: () -> ParameterDescriptor
|
||||
) : KParameter, KAnnotatedElementImpl {
|
||||
private val descriptor: ParameterDescriptor by ReflectProperties.lazySoft(computeDescriptor)
|
||||
|
||||
@@ -38,5 +39,5 @@ class KParameterImpl(
|
||||
}
|
||||
|
||||
override val type: KType
|
||||
get() = KTypeImpl(descriptor.getType())
|
||||
get() = KTypeImpl(descriptor.type) { callable.caller.parameterTypes[index] }
|
||||
}
|
||||
|
||||
@@ -17,9 +17,15 @@
|
||||
package kotlin.reflect.jvm.internal
|
||||
|
||||
import org.jetbrains.kotlin.types.JetType
|
||||
import java.lang.reflect.Type
|
||||
import kotlin.reflect.KType
|
||||
|
||||
class KTypeImpl(val type: JetType) : KType {
|
||||
class KTypeImpl(
|
||||
val type: JetType,
|
||||
computeJavaType: () -> Type
|
||||
) : KType {
|
||||
internal val javaType: Type by ReflectProperties.lazySoft(computeJavaType)
|
||||
|
||||
override val isMarkedNullable: Boolean
|
||||
get() = type.isMarkedNullable
|
||||
}
|
||||
|
||||
@@ -16,10 +16,7 @@
|
||||
|
||||
package kotlin.reflect.jvm
|
||||
|
||||
import java.lang.reflect.Constructor
|
||||
import java.lang.reflect.Field
|
||||
import java.lang.reflect.Method
|
||||
import java.lang.reflect.Modifier
|
||||
import java.lang.reflect.*
|
||||
import kotlin.jvm.internal.Intrinsic
|
||||
import kotlin.reflect.*
|
||||
import kotlin.reflect.jvm.internal.*
|
||||
@@ -87,6 +84,15 @@ public val <T> KFunction<T>.javaConstructor: Constructor<T>?
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a Java [Type] instance corresponding to the given Kotlin type.
|
||||
* Note that one Kotlin type may correspond to different JVM types depending on where it appears. For example, [Unit] corresponds to
|
||||
* the JVM class [Unit] when it's the type of a parameter, or to `void` when it's the return type of a function.
|
||||
*/
|
||||
public val KType.javaType: Type
|
||||
get() = (this as KTypeImpl).javaType
|
||||
|
||||
|
||||
|
||||
// Java reflection -> Kotlin reflection
|
||||
|
||||
|
||||
Reference in New Issue
Block a user