[IR] 2/2 Fix false negative KOTLIN_ACTUAL_ANNOTATION_MISSING for Java annotations
Java-to-Kotlin direct actualization: IrProperty in annotations is a
separate case
^KT-71631 Fixed
diff --git a/compiler/ir/ir.actualization/src/main/kotlin/org/jetbrains/kotlin/backend/common/actualizer/checker/IrKotlinActualAnnotationOnJavaKmpChecker.kt b/compiler/ir/ir.actualization/src/main/kotlin/org/jetbrains/kotlin/backend/common/actualizer/checker/IrKotlinActualAnnotationOnJavaKmpChecker.kt
index 7b0fc4c..d270946 100644
--- a/compiler/ir/ir.actualization/src/main/kotlin/org/jetbrains/kotlin/backend/common/actualizer/checker/IrKotlinActualAnnotationOnJavaKmpChecker.kt
+++ b/compiler/ir/ir.actualization/src/main/kotlin/org/jetbrains/kotlin/backend/common/actualizer/checker/IrKotlinActualAnnotationOnJavaKmpChecker.kt
@@ -16,6 +16,7 @@
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin.Companion.ENUM_CLASS_SPECIAL_MEMBER
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrPackageFragment
+import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.util.classId
import org.jetbrains.kotlin.ir.util.hasAnnotation
@@ -42,7 +43,9 @@
diagnosticsReporter: IrDiagnosticReporter,
topLevelExpect: IrClassSymbol
) {
- val hasAnnotation = actual.hasAnnotation(StandardClassIds.Annotations.KotlinActual)
+ val hasAnnotation = actual.hasAnnotation(StandardClassIds.Annotations.KotlinActual) ||
+ actual is IrProperty && (actual.parent as? IrClass)?.isAnnotationClass == true &&
+ actual.getter?.hasAnnotation(StandardClassIds.Annotations.KotlinActual) == true
val expect = expectActualMap.actualToDirectExpect[actual.symbol]
if (hasAnnotation && expect == null) {
diagnosticsReporter.reportJavaDirectActualWithoutExpect(actual, reportOn = topLevelExpect)
@@ -54,7 +57,7 @@
}
if (actual is IrClass) {
for (member in actual.declarations) {
- if (!member.isFakeOverride && (member is IrFunction || member is IrClass) &&
+ if (!member.isFakeOverride && (member is IrFunction || member is IrClass || member is IrProperty) &&
!member.isInterfaceConstructor(actual) // In Java, annotations are interfaces, and they can't have constructors.
) {
checkAnnotationRecursive(member, expectActualMap, diagnosticsReporter, topLevelExpect)
diff --git a/compiler/testData/diagnostics/tests/multiplatform/directJavaActualization/directJavaActualization_annotationPropertyMissingKotlinActualAnnotation.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/directJavaActualization/directJavaActualization_annotationPropertyMissingKotlinActualAnnotation.fir.kt
index 3d5cb36..130d2d7 100644
--- a/compiler/testData/diagnostics/tests/multiplatform/directJavaActualization/directJavaActualization_annotationPropertyMissingKotlinActualAnnotation.fir.kt
+++ b/compiler/testData/diagnostics/tests/multiplatform/directJavaActualization/directJavaActualization_annotationPropertyMissingKotlinActualAnnotation.fir.kt
@@ -4,7 +4,7 @@
// MODULE: m1-common
// FILE: common.kt
-expect annotation class Foo(val foo: Int)
+expect annotation class Foo(val <!KOTLIN_ACTUAL_ANNOTATION_MISSING{JVM}!>foo<!>: Int)
// MODULE: m2-jvm()()(m1-common)
// FILE: Foo.java
diff --git a/compiler/testData/diagnostics/tests/multiplatform/directJavaActualization/directJavaActualization_annotationPropertyMissingKotlinActualAnnotation.ll.kt b/compiler/testData/diagnostics/tests/multiplatform/directJavaActualization/directJavaActualization_annotationPropertyMissingKotlinActualAnnotation.ll.kt
new file mode 100644
index 0000000..3d5cb36
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/multiplatform/directJavaActualization/directJavaActualization_annotationPropertyMissingKotlinActualAnnotation.ll.kt
@@ -0,0 +1,13 @@
+// WITH_KOTLIN_JVM_ANNOTATIONS
+// LANGUAGE:+DirectJavaActualization
+// WITH_STDLIB
+
+// MODULE: m1-common
+// FILE: common.kt
+expect annotation class Foo(val foo: Int)
+
+// MODULE: m2-jvm()()(m1-common)
+// FILE: Foo.java
+@kotlin.annotations.jvm.KotlinActual public @interface Foo {
+ int foo();
+}