Support non-reified type parameters in typeOf in JVM and JVM_IR
#KT-30279 Fixed
This commit is contained in:
committed by
Alexander Udalov
parent
6fb40878c4
commit
0ce16b9d8c
+21
@@ -0,0 +1,21 @@
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.typeOf
|
||||
import kotlin.reflect.KTypeParameter
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class Container<T>
|
||||
|
||||
fun <X> test() = typeOf<Container<X>>()
|
||||
|
||||
fun box(): String {
|
||||
val type = test<Any>()
|
||||
val x = type.arguments.single().type!!.classifier as KTypeParameter
|
||||
assertEquals("java.lang.Object? (Kotlin reflection is not available)", x.upperBounds.joinToString())
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.typeOf
|
||||
import kotlin.reflect.KTypeParameter
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotEquals
|
||||
|
||||
class Container<T>
|
||||
|
||||
class C<X, Y> {
|
||||
val x1 = createX()
|
||||
val x2 = createXFromOtherFunction()
|
||||
val xFun = createIrrelevantX<Any>()
|
||||
val y = createY()
|
||||
|
||||
fun createX(): KTypeParameter =
|
||||
typeOf<Container<X>>().arguments.single().type!!.classifier as KTypeParameter
|
||||
|
||||
fun createXFromOtherFunction(): KTypeParameter =
|
||||
typeOf<Container<X>>().arguments.single().type!!.classifier as KTypeParameter
|
||||
|
||||
fun <X> createIrrelevantX(): KTypeParameter =
|
||||
typeOf<Container<X>>().arguments.single().type!!.classifier as KTypeParameter
|
||||
|
||||
fun createY(): KTypeParameter =
|
||||
typeOf<Container<Y>>().arguments.single().type!!.classifier as KTypeParameter
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val c = C<Any, Any>()
|
||||
assertEquals(c.x1, c.x2)
|
||||
assertEquals(c.x1.hashCode(), c.x2.hashCode())
|
||||
|
||||
assertNotEquals(c.x1, c.xFun)
|
||||
assertNotEquals(c.x1, c.y)
|
||||
return "OK"
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.typeOf
|
||||
import kotlin.reflect.KTypeParameter
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotEquals
|
||||
|
||||
class Container<T>
|
||||
|
||||
fun <X> createX(): KTypeParameter =
|
||||
typeOf<Container<X>>().arguments.single().type!!.classifier as KTypeParameter
|
||||
|
||||
fun <X> createOtherX(): KTypeParameter =
|
||||
typeOf<Container<X>>().arguments.single().type!!.classifier as KTypeParameter
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(createX<Any>(), createX<Any>())
|
||||
assertEquals(createX<Any>().hashCode(), createX<Any>().hashCode())
|
||||
|
||||
assertNotEquals(createX<Any>(), createOtherX<Any>())
|
||||
return "OK"
|
||||
}
|
||||
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.KTypeParameter
|
||||
import kotlin.reflect.typeOf
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class Container<T>
|
||||
|
||||
class C<X> {
|
||||
inner class D<Y : X> {
|
||||
fun <Z : Y> createZ(): KTypeParameter =
|
||||
typeOf<Container<Z>>().arguments.single().type!!.classifier as KTypeParameter
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val z = C<Any>().D<Any>().createZ<Any>()
|
||||
assertEquals("Y (Kotlin reflection is not available)", z.upperBounds.joinToString())
|
||||
val y = z.upperBounds.single().classifier as KTypeParameter
|
||||
assertEquals("X (Kotlin reflection is not available)", y.upperBounds.joinToString())
|
||||
return "OK"
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.typeOf
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class Container<T>
|
||||
|
||||
class C<X> {
|
||||
fun notNull() = typeOf<Container<X>>()
|
||||
fun nullable() = typeOf<Container<X?>>()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals("test.Container<X> (Kotlin reflection is not available)", C<Any>().notNull().toString())
|
||||
assertEquals("test.Container<X?> (Kotlin reflection is not available)", C<Any>().nullable().toString())
|
||||
return "OK"
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.typeOf
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class Container<T>
|
||||
|
||||
fun <X1> notNull() = typeOf<Container<X1>>()
|
||||
fun <X2> nullable() = typeOf<Container<X2?>>()
|
||||
|
||||
fun box(): String {
|
||||
assertEquals("test.Container<X1> (Kotlin reflection is not available)", notNull<Any>().toString())
|
||||
assertEquals("test.Container<X2?> (Kotlin reflection is not available)", nullable<Any>().toString())
|
||||
return "OK"
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.typeOf
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class Container<T>
|
||||
|
||||
val <X1> X1.notNull get() = typeOf<Container<X1>>()
|
||||
val <X2> X2.nullable get() = typeOf<Container<X2?>>()
|
||||
|
||||
fun box(): String {
|
||||
assertEquals("test.Container<X1> (Kotlin reflection is not available)", "".notNull.toString())
|
||||
assertEquals("test.Container<X2?> (Kotlin reflection is not available)", "".nullable.toString())
|
||||
return "OK"
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.*
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class Container<T>
|
||||
|
||||
class C<INV, in IN, out OUT> {
|
||||
fun getInv() = typeOf<Container<INV>>().arguments.single().type!!.classifier as KTypeParameter
|
||||
fun getIn() = typeOf<Container<IN>>().arguments.single().type!!.classifier as KTypeParameter
|
||||
fun getOut() = typeOf<Container<OUT>>().arguments.single().type!!.classifier as KTypeParameter
|
||||
}
|
||||
|
||||
inline fun <reified X, Y : X> getY() = typeOf<Container<Y>>().arguments.single().type!!.classifier as KTypeParameter
|
||||
|
||||
fun box(): String {
|
||||
val c = C<Any, Any, Any>()
|
||||
assertEquals(KVariance.INVARIANT, c.getInv().variance)
|
||||
assertEquals(KVariance.IN, c.getIn().variance)
|
||||
assertEquals(KVariance.OUT, c.getOut().variance)
|
||||
assertEquals(false, c.getInv().isReified)
|
||||
|
||||
val y = getY<Any, Any>()
|
||||
assertEquals(false, y.isReified)
|
||||
val x = y.upperBounds.single().classifier as KTypeParameter
|
||||
assertEquals(true, x.isReified)
|
||||
assertEquals(KVariance.INVARIANT, x.variance)
|
||||
|
||||
assertEquals("INV", c.getInv().toString())
|
||||
assertEquals("in IN", c.getIn().toString())
|
||||
assertEquals("out OUT", c.getOut().toString())
|
||||
assertEquals("X", x.toString())
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.typeOf
|
||||
import kotlin.reflect.KTypeParameter
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class Container<T>
|
||||
|
||||
class B<W>
|
||||
|
||||
class C<X> {
|
||||
val <Y> B<Y>.createY: KTypeParameter where Y : X
|
||||
get() = typeOf<Container<Y>>().arguments.single().type!!.classifier as KTypeParameter
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
with(C<Any>()) {
|
||||
val y = B<Any>().createY
|
||||
assertEquals("X (Kotlin reflection is not available)", y.upperBounds.joinToString())
|
||||
}
|
||||
return "OK"
|
||||
}
|
||||
Vendored
+30
@@ -0,0 +1,30 @@
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.typeOf
|
||||
import kotlin.reflect.KTypeParameter
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class Container<T>
|
||||
|
||||
fun <X, Y, Z> test() where X : Y?, Y : List<Z>, Z : Set<String>
|
||||
= typeOf<Container<X>>()
|
||||
|
||||
fun box(): String {
|
||||
val type = test<MutableList<Set<String>>?, MutableList<Set<String>>, Set<String>>()
|
||||
assertEquals("test.Container<X> (Kotlin reflection is not available)", type.toString())
|
||||
|
||||
val x = type.arguments.single().type!!.classifier as KTypeParameter
|
||||
assertEquals("Y? (Kotlin reflection is not available)", x.upperBounds.joinToString())
|
||||
|
||||
val y = x.upperBounds.single().classifier as KTypeParameter
|
||||
assertEquals("java.util.List<Z> (Kotlin reflection is not available)", y.upperBounds.joinToString())
|
||||
|
||||
val z = y.upperBounds.single().arguments.single().type!!.classifier as KTypeParameter
|
||||
assertEquals("java.util.Set<java.lang.String> (Kotlin reflection is not available)", z.upperBounds.joinToString())
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// IGNORE_BACKEND: JS, JS_IR, NATIVE
|
||||
// WITH_REFLECT
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.typeOf
|
||||
import kotlin.reflect.KTypeParameter
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class Container<T>
|
||||
|
||||
fun <X> test() = typeOf<Container<X>>()
|
||||
|
||||
fun box(): String {
|
||||
val type = test<Any>()
|
||||
val x = type.arguments.single().type!!.classifier as KTypeParameter
|
||||
assertEquals("kotlin.Any?", x.upperBounds.joinToString())
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Vendored
+41
@@ -0,0 +1,41 @@
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// IGNORE_BACKEND: JS, JS_IR, NATIVE
|
||||
// WITH_REFLECT
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.typeOf
|
||||
import kotlin.reflect.KTypeParameter
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotEquals
|
||||
|
||||
class Container<T>
|
||||
|
||||
class C<X, Y> {
|
||||
val x1 = createX()
|
||||
val x2 = createXFromOtherFunction()
|
||||
val xFun = createIrrelevantX<Any>()
|
||||
val y = createY()
|
||||
|
||||
fun createX(): KTypeParameter =
|
||||
typeOf<Container<X>>().arguments.single().type!!.classifier as KTypeParameter
|
||||
|
||||
fun createXFromOtherFunction(): KTypeParameter =
|
||||
typeOf<Container<X>>().arguments.single().type!!.classifier as KTypeParameter
|
||||
|
||||
fun <X> createIrrelevantX(): KTypeParameter =
|
||||
typeOf<Container<X>>().arguments.single().type!!.classifier as KTypeParameter
|
||||
|
||||
fun createY(): KTypeParameter =
|
||||
typeOf<Container<Y>>().arguments.single().type!!.classifier as KTypeParameter
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val c = C<Any, Any>()
|
||||
assertEquals(c.x1, c.x2)
|
||||
assertEquals(c.x1.hashCode(), c.x2.hashCode())
|
||||
|
||||
assertNotEquals(c.x1, c.xFun)
|
||||
assertNotEquals(c.x1, c.y)
|
||||
return "OK"
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_REFLECT
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.typeOf
|
||||
import kotlin.reflect.KTypeParameter
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotEquals
|
||||
|
||||
class Container<T>
|
||||
|
||||
class C<X, Y> {
|
||||
fun createX(): KTypeParameter =
|
||||
typeOf<Container<X>>().arguments.single().type!!.classifier as KTypeParameter
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val tp = C::class.typeParameters
|
||||
val c = C<Any, Any>()
|
||||
assertEquals(tp[0], c.createX())
|
||||
assertNotEquals(tp[1], c.createX())
|
||||
return "OK"
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// IGNORE_BACKEND: JS, JS_IR, NATIVE
|
||||
// WITH_REFLECT
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.typeOf
|
||||
import kotlin.reflect.KTypeParameter
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotEquals
|
||||
|
||||
class Container<T>
|
||||
|
||||
fun <X> createX(): KTypeParameter =
|
||||
typeOf<Container<X>>().arguments.single().type!!.classifier as KTypeParameter
|
||||
|
||||
fun <X> createOtherX(): KTypeParameter =
|
||||
typeOf<Container<X>>().arguments.single().type!!.classifier as KTypeParameter
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(createX<Any>(), createX<Any>())
|
||||
assertEquals(createX<Any>().hashCode(), createX<Any>().hashCode())
|
||||
|
||||
assertNotEquals(createX<Any>(), createOtherX<Any>())
|
||||
return "OK"
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// IGNORE_BACKEND: JS, JS_IR, NATIVE
|
||||
// WITH_REFLECT
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.KTypeParameter
|
||||
import kotlin.reflect.typeOf
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class Container<T>
|
||||
|
||||
class C<X> {
|
||||
inner class D<Y : X> {
|
||||
fun <Z : Y> createZ(): KTypeParameter =
|
||||
typeOf<Container<Z>>().arguments.single().type!!.classifier as KTypeParameter
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val z = C<Any>().D<Any>().createZ<Any>()
|
||||
assertEquals("Y", z.upperBounds.joinToString())
|
||||
val y = z.upperBounds.single().classifier as KTypeParameter
|
||||
assertEquals("X", y.upperBounds.joinToString())
|
||||
return "OK"
|
||||
}
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// IGNORE_BACKEND: JS, JS_IR, NATIVE
|
||||
// WITH_REFLECT
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.typeOf
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class Container<T>
|
||||
|
||||
class C<X> {
|
||||
fun notNull() = typeOf<Container<X>>()
|
||||
fun nullable() = typeOf<Container<X?>>()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals("test.Container<X>", C<Any>().notNull().toString())
|
||||
assertEquals("test.Container<X?>", C<Any>().nullable().toString())
|
||||
return "OK"
|
||||
}
|
||||
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// IGNORE_BACKEND: JS, JS_IR, NATIVE
|
||||
// WITH_REFLECT
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.typeOf
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class Container<T>
|
||||
|
||||
fun <X1> notNull() = typeOf<Container<X1>>()
|
||||
fun <X2> nullable() = typeOf<Container<X2?>>()
|
||||
|
||||
fun box(): String {
|
||||
assertEquals("test.Container<X1>", notNull<Any>().toString())
|
||||
assertEquals("test.Container<X2?>", nullable<Any>().toString())
|
||||
return "OK"
|
||||
}
|
||||
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// IGNORE_BACKEND: JS, JS_IR, NATIVE
|
||||
// WITH_REFLECT
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.typeOf
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class Container<T>
|
||||
|
||||
val <X1> X1.notNull get() = typeOf<Container<X1>>()
|
||||
val <X2> X2.nullable get() = typeOf<Container<X2?>>()
|
||||
|
||||
fun box(): String {
|
||||
assertEquals("test.Container<X1>", "".notNull.toString())
|
||||
assertEquals("test.Container<X2?>", "".nullable.toString())
|
||||
return "OK"
|
||||
}
|
||||
Vendored
+39
@@ -0,0 +1,39 @@
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// IGNORE_BACKEND: JS, JS_IR, NATIVE
|
||||
// WITH_REFLECT
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.*
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class Container<T>
|
||||
|
||||
class C<INV, in IN, out OUT> {
|
||||
fun getInv() = typeOf<Container<INV>>().arguments.single().type!!.classifier as KTypeParameter
|
||||
fun getIn() = typeOf<Container<IN>>().arguments.single().type!!.classifier as KTypeParameter
|
||||
fun getOut() = typeOf<Container<OUT>>().arguments.single().type!!.classifier as KTypeParameter
|
||||
}
|
||||
|
||||
inline fun <reified X, Y : X> getY() = typeOf<Container<Y>>().arguments.single().type!!.classifier as KTypeParameter
|
||||
|
||||
fun box(): String {
|
||||
val c = C<Any, Any, Any>()
|
||||
assertEquals(KVariance.INVARIANT, c.getInv().variance)
|
||||
assertEquals(KVariance.IN, c.getIn().variance)
|
||||
assertEquals(KVariance.OUT, c.getOut().variance)
|
||||
assertEquals(false, c.getInv().isReified)
|
||||
|
||||
val y = getY<Any, Any>()
|
||||
assertEquals(false, y.isReified)
|
||||
val x = y.upperBounds.single().classifier as KTypeParameter
|
||||
assertEquals(true, x.isReified)
|
||||
assertEquals(KVariance.INVARIANT, x.variance)
|
||||
|
||||
assertEquals("INV", c.getInv().toString())
|
||||
assertEquals("in IN", c.getIn().toString())
|
||||
assertEquals("out OUT", c.getOut().toString())
|
||||
assertEquals("X", x.toString())
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// IGNORE_BACKEND: JS, JS_IR, NATIVE
|
||||
// WITH_REFLECT
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.typeOf
|
||||
import kotlin.reflect.KTypeParameter
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class Container<T>
|
||||
|
||||
class B<W>
|
||||
|
||||
class C<X> {
|
||||
val <Y> B<Y>.createY: KTypeParameter where Y : X
|
||||
get() = typeOf<Container<Y>>().arguments.single().type!!.classifier as KTypeParameter
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
with(C<Any>()) {
|
||||
val y = B<Any>().createY
|
||||
assertEquals("X", y.upperBounds.joinToString())
|
||||
}
|
||||
return "OK"
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// IGNORE_BACKEND: JS, JS_IR, NATIVE
|
||||
// WITH_REFLECT
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.typeOf
|
||||
import kotlin.reflect.KTypeParameter
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class Container<T>
|
||||
|
||||
fun <X, Y, Z> test() where X : Y?, Y : List<Z>, Z : Set<String>
|
||||
= typeOf<Container<X>>()
|
||||
|
||||
fun box(): String {
|
||||
val type = test<MutableList<Set<String>>?, MutableList<Set<String>>, Set<String>>()
|
||||
assertEquals("test.Container<X>", type.toString())
|
||||
|
||||
val x = type.arguments.single().type!!.classifier as KTypeParameter
|
||||
assertEquals("Y?", x.upperBounds.joinToString())
|
||||
|
||||
val y = x.upperBounds.single().classifier as KTypeParameter
|
||||
assertEquals("kotlin.collections.List<Z>", y.upperBounds.joinToString())
|
||||
|
||||
val z = y.upperBounds.single().arguments.single().type!!.classifier as KTypeParameter
|
||||
assertEquals("kotlin.collections.Set<kotlin.String>", z.upperBounds.joinToString())
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -14,15 +14,17 @@ inline fun <reified T> T.causeBug() {
|
||||
x is T
|
||||
x as T
|
||||
T::class
|
||||
typeOf<T>()
|
||||
Array<T>(1) { x }
|
||||
|
||||
// Non-reified type parameters with recursive bounds are not yet supported
|
||||
// typeOf<T>()
|
||||
}
|
||||
|
||||
interface SomeToImplement<SELF_TVAR>
|
||||
|
||||
class Y : SomeToImplement<Y>
|
||||
|
||||
class Something<T> where T: SomeToImplement<T> {
|
||||
class Something<Z> where Z : SomeToImplement<Z> {
|
||||
fun op() = causeBug()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user