diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index 92647342ed1..d89740ec26e 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -1260,6 +1260,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/annotations/JavaAnnotationConstructors.kt"); } + @Test + @TestMetadata("javaAnnotationWithClassArray.kt") + public void testJavaAnnotationWithClassArray() throws Exception { + runTest("compiler/testData/diagnostics/tests/annotations/javaAnnotationWithClassArray.kt"); + } + @Test @TestMetadata("kt1860-negative.kt") public void testKt1860_negative() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index 048c25e52b6..68d83febb1e 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -1260,6 +1260,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/annotations/JavaAnnotationConstructors.kt"); } + @Test + @TestMetadata("javaAnnotationWithClassArray.kt") + public void testJavaAnnotationWithClassArray() throws Exception { + runTest("compiler/testData/diagnostics/tests/annotations/javaAnnotationWithClassArray.kt"); + } + @Test @TestMetadata("kt1860-negative.kt") public void testKt1860_negative() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index 2da60ec95cf..ac63169aa3f 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -1260,6 +1260,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/annotations/JavaAnnotationConstructors.kt"); } + @Test + @TestMetadata("javaAnnotationWithClassArray.kt") + public void testJavaAnnotationWithClassArray() throws Exception { + runTest("compiler/testData/diagnostics/tests/annotations/javaAnnotationWithClassArray.kt"); + } + @Test @TestMetadata("kt1860-negative.kt") public void testKt1860_negative() throws Exception { diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaTypeConversion.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaTypeConversion.kt index 00ae213b3f3..86422f2b74c 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaTypeConversion.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaTypeConversion.kt @@ -99,7 +99,7 @@ private fun JavaType?.toConeTypeProjection( is JavaClassifierType -> { val lowerBound = toConeKotlinTypeForFlexibleBound(session, javaTypeParameterStack, mode, attributes) if (mode == FirJavaTypeConversionMode.ANNOTATION_MEMBER) { - return lowerBound // TODO: `KClass` is wrong for raw `Class` + return lowerBound } val upperBound = toConeKotlinTypeForFlexibleBound(session, javaTypeParameterStack, mode, attributes, lowerBound) if (isRaw) ConeRawType(lowerBound, upperBound) else ConeFlexibleType(lowerBound, upperBound) @@ -171,8 +171,11 @@ private fun JavaClassifierType.toConeKotlinTypeForFlexibleBound( lookupTag.takeIf { lowerBound == null && mode != FirJavaTypeConversionMode.TYPE_PARAMETER_BOUND } ?.toFirRegularClassSymbol(session)?.typeParameterSymbols // Given `C`, `C` -> `C..C<*>?`. - typeParameterSymbols?.eraseToUpperBounds(session) - ?: Array(classifier.typeParameters.size) { ConeStarProjection } + when (mode) { + FirJavaTypeConversionMode.ANNOTATION_MEMBER -> Array(classifier.typeParameters.size) { ConeStarProjection } + else -> typeParameterSymbols?.eraseToUpperBounds(session) + ?: Array(classifier.typeParameters.size) { ConeStarProjection } + } } lookupTag != lowerBound?.lookupTag && typeArguments.isNotEmpty() -> { val typeParameterSymbols = diff --git a/compiler/testData/diagnostics/tests/annotations/javaAnnotationWithClassArray.kt b/compiler/testData/diagnostics/tests/annotations/javaAnnotationWithClassArray.kt new file mode 100644 index 00000000000..e9aac903fea --- /dev/null +++ b/compiler/testData/diagnostics/tests/annotations/javaAnnotationWithClassArray.kt @@ -0,0 +1,28 @@ +// FIR_IDENTICAL +// WITH_STDLIB +// FILE: AnnRaw.java +public @interface AnnRaw { + Class value(); +} + +// FILE: Ann.java +public @interface Ann { + Class value(); +} + +// FILE: Utils.java +public class Utils { + public static void foo(Class value) {} + public static void fooRaw(Class value) {} +} + +// FILE: main.kt + +class X + +@Ann(X::class) +@AnnRaw(X::class) +fun test() { + Utils.foo(X::class.java) + Utils.fooRaw(X::class.java) +} diff --git a/compiler/testData/diagnostics/tests/annotations/javaAnnotationWithClassArray.txt b/compiler/testData/diagnostics/tests/annotations/javaAnnotationWithClassArray.txt new file mode 100644 index 00000000000..c8622264324 --- /dev/null +++ b/compiler/testData/diagnostics/tests/annotations/javaAnnotationWithClassArray.txt @@ -0,0 +1,38 @@ +package + +@Ann(value = X::class) @AnnRaw(value = X::class) public fun test(): kotlin.Unit + +public final annotation class Ann : kotlin.Annotation { + public constructor Ann(/*0*/ value: kotlin.reflect.KClass<*>) + public final val value: kotlin.reflect.KClass<*> + 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 +} + +public final annotation class AnnRaw : kotlin.Annotation { + public constructor AnnRaw(/*0*/ value: kotlin.reflect.KClass<(raw) kotlin.Any>) + public final val value: kotlin.reflect.KClass<(raw) kotlin.Any> + 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 +} + +public open class Utils { + public constructor Utils() + 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 + + // Static members + public open fun foo(/*0*/ value: java.lang.Class<(raw) kotlin.Any!>!): kotlin.Unit + public open fun fooRaw(/*0*/ value: java.lang.Class<*>!): kotlin.Unit +} + +public final class X { + public constructor X() + 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 +} + diff --git a/compiler/testData/loadJava/compiledJava/annotations/ClassObjectInParamRaw.fir.txt b/compiler/testData/loadJava/compiledJava/annotations/ClassObjectInParamRaw.fir.txt index f5e756345e9..641a83e3488 100644 --- a/compiler/testData/loadJava/compiledJava/annotations/ClassObjectInParamRaw.fir.txt +++ b/compiler/testData/loadJava/compiledJava/annotations/ClassObjectInParamRaw.fir.txt @@ -2,7 +2,7 @@ public open class ClassObjectInParamRaw : R|kotlin/Any| { public constructor(): R|test/ClassObjectInParamRaw| public final annotation class Anno : R|kotlin/Annotation| { - public constructor(value: R|kotlin/reflect/KClass|, arg: R|kotlin/Array>|): R|test/ClassObjectInParamRaw.Anno| + public constructor(value: R|kotlin/reflect/KClass<*>|, arg: R|kotlin/Array>|): R|test/ClassObjectInParamRaw.Anno| } @R|test/ClassObjectInParamRaw.Anno|(value = ((R|ft|)), arg = ()) public open class Nested : R|kotlin/Any| { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 62465ee32b3..17620929ee0 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -1266,6 +1266,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/annotations/JavaAnnotationConstructors.kt"); } + @Test + @TestMetadata("javaAnnotationWithClassArray.kt") + public void testJavaAnnotationWithClassArray() throws Exception { + runTest("compiler/testData/diagnostics/tests/annotations/javaAnnotationWithClassArray.kt"); + } + @Test @TestMetadata("kt1860-negative.kt") public void testKt1860_negative() throws Exception {