diff --git a/compiler/testData/codegen/box/reflection/classes/starProjectedType.kt b/compiler/testData/codegen/box/reflection/classes/starProjectedType.kt new file mode 100644 index 00000000000..d872635aaad --- /dev/null +++ b/compiler/testData/codegen/box/reflection/classes/starProjectedType.kt @@ -0,0 +1,23 @@ +// WITH_REFLECT + +import kotlin.reflect.KTypeProjection +import kotlin.reflect.createType +import kotlin.reflect.starProjectedType +import kotlin.test.assertEquals + +class Foo + +fun box(): String { + val foo = Foo::class.starProjectedType + assertEquals(Foo::class, foo.classifier) + assertEquals(listOf(KTypeProjection.Star, KTypeProjection.Star), foo.arguments) + assertEquals(foo, Foo::class.createType(listOf(KTypeProjection.Star, KTypeProjection.Star))) + + assertEquals(String::class, String::class.starProjectedType.classifier) + assertEquals(listOf(), String::class.starProjectedType.arguments) + + val tp = Foo::class.typeParameters.first() + assertEquals(tp.createType(), tp.starProjectedType) + + return "OK" +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 90a6afeda00..feabd24c36f 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -11933,6 +11933,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/classes/qualifiedName.kt"); doTest(fileName); } + + @TestMetadata("starProjectedType.kt") + public void testStarProjectedType() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/classes/starProjectedType.kt"); + doTest(fileName); + } } @TestMetadata("compiler/testData/codegen/box/reflection/constructors") diff --git a/core/reflection.jvm/src/kotlin/reflect/KClassifiers.kt b/core/reflection.jvm/src/kotlin/reflect/KClassifiers.kt index 69e5516e591..453475a412a 100644 --- a/core/reflection.jvm/src/kotlin/reflect/KClassifiers.kt +++ b/core/reflection.jvm/src/kotlin/reflect/KClassifiers.kt @@ -19,10 +19,8 @@ package kotlin.reflect import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.types.* -import kotlin.reflect.jvm.internal.KClassImpl import kotlin.reflect.jvm.internal.KClassifierImpl import kotlin.reflect.jvm.internal.KTypeImpl -import kotlin.reflect.jvm.internal.KTypeParameterImpl /** * Creates a [KType] instance with the given classifier, type arguments, nullability and annotations. @@ -76,3 +74,20 @@ private fun createKotlinType( } }, nullable) } + +/** + * Creates an instance of [KType] with the given classifier, substituting all its type parameters with star projections. + * The resulting type is not marked as nullable and does not have any annotations. + * + * @see [KClassifier.createType] + */ +val KClassifier.starProjectedType: KType + get() { + val descriptor = (this as? KClassifierImpl)?.descriptor + ?: return createType() + + val typeParameters = descriptor.typeConstructor.parameters + if (typeParameters.isEmpty()) return createType() // TODO: optimize, get defaultType from ClassDescriptor + + return createType(typeParameters.map { KTypeProjection.Star }) + }