[IR] Implement IR checker for expect actual annotations matching

^KT-58551
This commit is contained in:
Roman Efremov
2023-06-22 12:30:52 +02:00
committed by Space Team
parent b6cae1adcc
commit 2980179bd7
26 changed files with 324 additions and 44 deletions
@@ -87,8 +87,8 @@ package test
@ClassArgAnn(ClassForReference::class)
actual fun getClassExpression() {}
@ClassArgAnn(ClassForReference::class)
actual fun differentClassesWithSameName() {}
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@ClassArgAnn(ClassForReference::class)
actual fun differentClassesWithSameName() {}<!>
@StringArgAnn("1.9")
actual fun stringConstant() {}
@@ -114,8 +114,8 @@ actual fun varargInAnnotationWithArraySpread() {}
@ArrayArgAnn(arrayOf("foo", "bar"))
actual fun arrayInAnnotation() {}
@ArrayArgAnn(["foo"])
actual fun arrayInAnnotationNotMatch() {}
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@ArrayArgAnn(["foo"])
actual fun arrayInAnnotationNotMatch() {}<!>
@NestedAnnArg(
text = "root",
@@ -127,7 +127,7 @@ actual fun arrayInAnnotationNotMatch() {}
)
actual fun complexNestedAnnotations() {}
@NestedAnnArg(
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@NestedAnnArg(
text = "root",
NestedAnnArg("1"),
NestedAnnArg("2",
@@ -135,4 +135,4 @@ actual fun complexNestedAnnotations() {}
NestedAnnArg("DIFFERENT")
)
)
actual fun complexNestedAnnotationsNotMatch() {}
actual fun complexNestedAnnotationsNotMatch() {}<!>
@@ -0,0 +1,11 @@
// MODULE: m1-common
// FILE: common.kt
annotation class Ann(val p: String = "")
@Ann("")
expect fun explicitDefaultArgument()
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
// No special handling for this case
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@Ann
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>explicitDefaultArgument<!>() {}<!>
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// MODULE: m1-common
// FILE: common.kt
annotation class Ann(val p: String = "")
@@ -62,26 +62,26 @@ expect fun explicitVsInfered()
@Ann<A>
actual fun sameTypeParam() {}
@Ann<A>
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT, ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>differentTypeParam<!>() {}
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@Ann<A>
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>differentTypeParam<!>() {}<!>
@Ann<A>
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT, ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>differentWithSameName<!>() {}
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@Ann<A>
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>differentWithSameName<!>() {}<!>
@Ann<A>
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT, ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>nonNullvsNull<!>() {}
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@Ann<A>
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>nonNullvsNull<!>() {}<!>
@Ann<Ann<out A>>
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT, ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>differentVariance<!>() {}
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@Ann<Ann<out A>>
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>differentVariance<!>() {}<!>
@Ann<Ann<A>>
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT, ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>varianceVsNoVariance<!>() {}
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@Ann<Ann<A>>
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>varianceVsNoVariance<!>() {}<!>
@Ann<Ann<in A>>
actual fun sameVariance() {}
@Ann<Ann<Any>>
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT, ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>startProjection<!>() {}
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@Ann<Ann<Any>>
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>startProjection<!>() {}<!>
@ComplexNested<A>(
ComplexNested<A>(),
@@ -89,11 +89,11 @@ actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT, ACTUAL_ANNOTATIONS_NOT_MATCH_E
)
actual fun complexSame() {}
@ComplexNested<A>(
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@ComplexNested<A>(
ComplexNested<A>(),
ComplexNested<A>(),
)
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>complexDiffer<!>() {}
actual fun complexDiffer() {}<!>
@NestedWithSameTypeArgument<A>(
NestedWithSameTypeArgument<A>()
@@ -0,0 +1,41 @@
// MODULE: m1-common
// FILE: common.kt
annotation class Ann
@Ann
expect class AnnotationMatching
@Ann
expect class AnnotationOnExpectOnly
expect class AnnotationOnActualOnly
expect class AnnotationInside {
@Ann
fun matches()
@Ann
fun onlyOnExpect()
fun onlyOnActual()
}
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
@Ann
actual class AnnotationMatching
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual class <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>AnnotationOnExpectOnly<!><!>
@Ann
actual class AnnotationOnActualOnly
actual class AnnotationInside {
@Ann
actual fun matches() {}
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>onlyOnExpect<!>() {}<!>
@Ann
actual fun onlyOnActual() {}
}
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// MODULE: m1-common
// FILE: common.kt
annotation class Ann
@@ -1,17 +1,17 @@
// -- Module: <m1-common> --
// -- Module: <m1-jvm> --
/jvm.kt:24:14: warning: all annotations from `expect` must be presented with same arguments on `actual`, otherwise they have no effect.
/jvm.kt:23:14: warning: all annotations from `expect` must be presented with same arguments on `actual`, otherwise they have no effect.
Expected: @Ann public final expect class OnClass defined in root package in file common.kt
Actual: public final actual class OnClass defined in root package in file jvm.kt
actual class OnClass
^
/jvm.kt:27:16: warning: all annotations from `expect` must be presented with same arguments on `actual`, otherwise they have no effect.
/jvm.kt:26:16: warning: all annotations from `expect` must be presented with same arguments on `actual`, otherwise they have no effect.
Expected: @Ann public final expect fun onMember(): Unit defined in OnMember
Actual: public final actual fun onMember(): Unit defined in OnMember
actual fun onMember() {}
^
/jvm.kt:34:18: warning: all annotations from `expect` must be presented with same arguments on `actual`, otherwise they have no effect.
/jvm.kt:33:18: warning: all annotations from `expect` must be presented with same arguments on `actual`, otherwise they have no effect.
Expected: @Ann public final expect class ViaTypealias defined in root package in file common.kt
Actual: public final class ViaTypealiasImpl defined in root package in file jvm.kt
actual typealias ViaTypealias = ViaTypealiasImpl
@@ -1,11 +1,11 @@
/jvm.kt:(83,90): warning: All annotations from `expect` must be presented with same arguments on `actual`, otherwise they have no effect.
/jvm.kt:(82,89): warning: All annotations from `expect` must be presented with same arguments on `actual`, otherwise they have no effect.
Expected: @Ann() public final expect class OnClass : Any
Actual: public final actual class OnClass : Any
/jvm.kt:(131,139): warning: All annotations from `expect` must be presented with same arguments on `actual`, otherwise they have no effect.
/jvm.kt:(130,138): warning: All annotations from `expect` must be presented with same arguments on `actual`, otherwise they have no effect.
Expected: @Ann() public final expect fun onMember(): Unit
Actual: public final actual fun onMember(): Unit
/jvm.kt:(210,222): warning: All annotations from `expect` must be presented with same arguments on `actual`, otherwise they have no effect.
/jvm.kt:(209,221): warning: All annotations from `expect` must be presented with same arguments on `actual`, otherwise they have no effect.
Expected: @Ann() public final expect class ViaTypealias : Any
Actual: public final class ViaTypealiasImpl : Any
@@ -0,0 +1,33 @@
// RENDER_DIAGNOSTICS_FULL_TEXT
// MODULE: m1-common
// FILE: common.kt
annotation class Ann
@Ann
expect class OnClass
expect class OnMember {
@Ann
fun onMember()
}
@Ann
expect class ViaTypealias {
@Ann
fun foo()
}
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual class <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>OnClass<!><!>
actual class OnMember {
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>onMember<!>() {}<!>
}
class ViaTypealiasImpl {
fun foo() {}
}
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT, ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>ViaTypealias<!> = ViaTypealiasImpl<!>
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// RENDER_DIAGNOSTICS_FULL_TEXT
// MODULE: m1-common
// FILE: common.kt
@@ -0,0 +1,18 @@
// MODULE: m1-common
// FILE: common.kt
annotation class Ann
expect class CompatibleOverrides {
fun foo()
@Ann
fun foo(withArg: Any)
}
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
actual class CompatibleOverrides {
actual fun foo() {}
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>foo<!>(withArg: Any) {}<!>
}
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// MODULE: m1-common
// FILE: common.kt
annotation class Ann
@@ -24,8 +24,8 @@ expect fun differentArgumentsOrder()
@Ann1
actual class AnnotationOrder
@Ann3(2, 1)
actual class ValuesOrderInsideAnnotationArgument
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@Ann3(2, 1)
actual class ValuesOrderInsideAnnotationArgument<!>
@Ann4(arg2 = "2", arg1 = "1")
actual fun differentArgumentsOrder() {}
@@ -7,5 +7,5 @@ expect fun floatNumbersComparison()
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
@Ann(0.1 + 0.1 + 0.1)
actual fun floatNumbersComparison() {}
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@Ann(0.1 + 0.1 + 0.1)
actual fun floatNumbersComparison() {}<!>
@@ -0,0 +1,22 @@
// WITH_STDLIB
// MODULE: m1-common
// FILE: common.kt
@Target(AnnotationTarget.TYPEALIAS, AnnotationTarget.CLASS)
annotation class Ann
@Ann
expect class KtTypealiasNotMatch
@Ann
expect class AnnotationsNotConsideredOnTypealias
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
class KtTypealiasNotMatchImpl
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>KtTypealiasNotMatch<!> = KtTypealiasNotMatchImpl<!>
class AnnotationsNotConsideredOnTypealiasImpl
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@Ann
actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>AnnotationsNotConsideredOnTypealias<!> = AnnotationsNotConsideredOnTypealiasImpl<!>
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// WITH_STDLIB
// MODULE: m1-common
// FILE: common.kt
@@ -9,6 +9,6 @@ expect annotation class MyDeprecatedMatch
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
actual typealias MyDeprecatedNotMatch = java.lang.Deprecated
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual typealias MyDeprecatedNotMatch = java.lang.Deprecated<!>
actual typealias MyDeprecatedMatch = java.lang.Deprecated
@@ -1,4 +1,5 @@
// WITH_STDLIB
// DIAGNOSTICS: -ACTUAL_TYPEALIAS_TO_SPECIAL_ANNOTATION
// MODULE: m1-common
// FILE: common.kt
@Target(
@@ -25,8 +26,17 @@ expect annotation class MyDeprecatedNotMatch
)
expect annotation class MyDeprecatedMatch
annotation class Ann(val s: String)
expect abstract class MyAbstractIterator<T> {
@Ann("something" + "complex")
fun hasNext(): Boolean
}
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
actual typealias MyDeprecatedNotMatch = kotlin.Deprecated
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual typealias MyDeprecatedNotMatch = kotlin.Deprecated<!>
actual typealias MyDeprecatedMatch = kotlin.Deprecated
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual typealias MyAbstractIterator<T> = AbstractIterator<T><!>
@@ -1,4 +1,5 @@
// WITH_STDLIB
// DIAGNOSTICS: -ACTUAL_TYPEALIAS_TO_SPECIAL_ANNOTATION
// MODULE: m1-common
// FILE: common.kt
@Target(
@@ -25,8 +26,17 @@ expect annotation class MyDeprecatedNotMatch
)
expect annotation class MyDeprecatedMatch
annotation class Ann(val s: String)
expect abstract class MyAbstractIterator<T> {
@Ann("something" + "complex")
fun hasNext(): Boolean
}
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>MyDeprecatedNotMatch<!> = kotlin.Deprecated
actual typealias MyDeprecatedMatch = kotlin.Deprecated
actual typealias MyAbstractIterator<T> = AbstractIterator<T>