[FE] Check annotations on actual class members including fake overrides

^KT-60668
^KT-60936
This commit is contained in:
Roman Efremov
2023-08-04 13:09:36 +02:00
committed by Space Team
parent d614f06259
commit ab1c0e3c48
30 changed files with 601 additions and 34 deletions
@@ -1,11 +1,11 @@
// -- Module: <m1-common> --
// -- Module: <m1-jvm> --
/jvm.kt:27:14: warning: annotation `@Ann` is missing on actual declaration.
/jvm.kt:29:14: warning: annotation `@Ann` is missing on actual declaration.
All annotations from expect `class OnClass defined in root package in file common.kt` must be present with the same arguments on actual `class OnClass defined in root package in file jvm.kt`, otherwise they might behave incorrectly.
actual class OnClass
^
/jvm.kt:30:16: warning: annotation `@Ann` is missing on actual declaration.
/jvm.kt:32:16: warning: annotation `@Ann` is missing on actual declaration.
All annotations from expect `fun onMember(): Unit defined in OnMember` must be present with the same arguments on actual `fun onMember(): Unit defined in OnMember`, otherwise they might behave incorrectly.
actual fun onMember() {}
^
@@ -13,7 +13,11 @@ All annotations from expect `fun onMember(): Unit defined in OnMember` must be p
All annotations from expect `class ViaTypealias defined in root package in file common.kt` must be present with the same arguments on actual `class ViaTypealiasImpl defined in root package in file jvm.kt`, otherwise they might behave incorrectly.
actual typealias ViaTypealias = ViaTypealiasImpl
^
/jvm.kt:40:12: warning: annotation `@WithArg(s = "str")` has different arguments on actual declaration: `@WithArg(s = "other str")`.
/jvm.kt:42:18: warning: annotation `@Ann` is missing on actual declaration.
All annotations from expect `fun foo(): Unit defined in MemberScopeViaTypealias` must be present with the same arguments on actual `fun foo(): Unit defined in MemberScopeViaTypealiasImpl`, otherwise they might behave incorrectly.
actual typealias MemberScopeViaTypealias = MemberScopeViaTypealiasImpl
^
/jvm.kt:45:12: warning: annotation `@WithArg(s = "str")` has different arguments on actual declaration: `@WithArg(s = "other str")`.
All annotations from expect `fun withDifferentArg(): Unit defined in root package in file common.kt` must be present with the same arguments on actual `fun withDifferentArg(): Unit defined in root package in file jvm.kt`, otherwise they might behave incorrectly.
actual fun withDifferentArg() {}
^
@@ -1,11 +1,14 @@
/jvm.kt:(86,93): warning: Annotation `@Ann()` is missing on actual declaration.
/jvm.kt:(88,95): warning: Annotation `@Ann()` is missing on actual declaration.
All annotations from expect 'class OnClass : Any' must be present with the same arguments on actual 'class OnClass : Any', otherwise they might behave incorrectly.
/jvm.kt:(134,142): warning: Annotation `@Ann()` is missing on actual declaration.
/jvm.kt:(136,144): warning: Annotation `@Ann()` is missing on actual declaration.
All annotations from expect 'fun onMember(): Unit' must be present with the same arguments on actual 'fun onMember(): Unit', otherwise they might behave incorrectly.
/jvm.kt:(213,225): warning: Annotation `@Ann()` is missing on actual declaration.
/jvm.kt:(194,206): warning: Annotation `@Ann()` is missing on actual declaration.
All annotations from expect 'class ViaTypealias : Any' must be present with the same arguments on actual 'class ViaTypealiasImpl : Any', otherwise they might behave incorrectly.
/jvm.kt:(279,295): warning: Annotation `@WithArg(s = String(str))` has different arguments on actual declaration: `@WithArg(s = String(other str))`.
/jvm.kt:(299,322): warning: Annotation `@Ann()` is missing on actual declaration.
All annotations from expect 'fun foo(): Unit' must be present with the same arguments on actual 'fun foo(): Unit', otherwise they might behave incorrectly.
/jvm.kt:(387,403): warning: Annotation `@WithArg(s = String(str))` has different arguments on actual declaration: `@WithArg(s = String(other str))`.
All annotations from expect 'fun withDifferentArg(): Unit' must be present with the same arguments on actual 'fun withDifferentArg(): Unit', otherwise they might behave incorrectly.
@@ -12,7 +12,9 @@ expect class OnMember {
}
@Ann
expect class ViaTypealias {
expect class ViaTypealias
expect class MemberScopeViaTypealias {
@Ann
fun foo()
}
@@ -30,11 +32,14 @@ actual class OnMember {
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>onMember<!>() {}<!>
}
class ViaTypealiasImpl {
class ViaTypealiasImpl
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>ViaTypealias<!> = ViaTypealiasImpl<!>
class MemberScopeViaTypealiasImpl {
fun foo() {}
}
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT, ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>ViaTypealias<!> = ViaTypealiasImpl<!>
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>MemberScopeViaTypealias<!> = MemberScopeViaTypealiasImpl<!>
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@WithArg("other str")
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>withDifferentArg<!>() {}<!>
@@ -12,7 +12,9 @@ expect class OnMember {
}
@Ann
expect class ViaTypealias {
expect class ViaTypealias
expect class MemberScopeViaTypealias {
@Ann
fun foo()
}
@@ -30,11 +32,14 @@ actual class OnMember {
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>onMember<!>() {}
}
class ViaTypealiasImpl {
fun foo() {}
}
class ViaTypealiasImpl
actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>ViaTypealias<!> = ViaTypealiasImpl
class MemberScopeViaTypealiasImpl {
fun foo() {}
}
actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>MemberScopeViaTypealias<!> = MemberScopeViaTypealiasImpl
@WithArg("other str")
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>withDifferentArg<!>() {}
@@ -0,0 +1,22 @@
// MODULE: m1-common
// FILE: common.kt
annotation class Ann
expect class A {
class B {
class C {
@Ann
fun foo()
}
}
}
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
actual class A {
actual class B {
actual class C {
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>foo<!>() {}<!>
}
}
}
@@ -0,0 +1,22 @@
// MODULE: m1-common
// FILE: common.kt
annotation class Ann
expect class A {
class B {
class C {
@Ann
fun foo()
}
}
}
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
actual class A {
actual class B {
actual class C {
actual fun <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>foo<!>() {}
}
}
}
@@ -0,0 +1,27 @@
// MODULE: m1-common
// FILE: common.kt
annotation class Ann
<!INCOMPATIBLE_MATCHING{JVM}!>expect class WeakIncompatibility {
<!INCOMPATIBLE_MATCHING{JVM}!>@Ann
fun foo(p: String)<!>
}<!>
<!INCOMPATIBLE_MATCHING{JVM}!>expect class StrongIncompatibility {
<!INCOMPATIBLE_MATCHING{JVM}!>@Ann
fun foo(p: Int)<!>
}<!>
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
class WeakIncompatibilityImpl {
fun foo(differentName: String) {}
}
actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT, NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>WeakIncompatibility<!> = WeakIncompatibilityImpl
class StrongIncompatibilityImpl {
fun foo(p: String) {} // Different param type
}
actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT, NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>StrongIncompatibility<!> = StrongIncompatibilityImpl
@@ -0,0 +1,27 @@
// MODULE: m1-common
// FILE: common.kt
annotation class Ann
expect class WeakIncompatibility {
@Ann
fun foo(p: String)
}
expect class StrongIncompatibility {
@Ann
fun foo(p: Int)
}
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
class WeakIncompatibilityImpl {
fun foo(differentName: String) {}
}
actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT, NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>WeakIncompatibility<!> = WeakIncompatibilityImpl
class StrongIncompatibilityImpl {
fun foo(p: String) {} // Different param type
}
actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT, NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>StrongIncompatibility<!> = StrongIncompatibilityImpl
@@ -0,0 +1,31 @@
// MODULE: m1-common
// FILE: common.kt
annotation class Ann
abstract class A {
@Ann
open fun noAnnotationOnActual() {}
}
expect class FakeOverrideExpect : A
interface I {
fun noAnnotationOnActual()
}
expect class FakeOverrideActual : I {
@Ann
override fun noAnnotationOnActual()
}
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
actual class FakeOverrideExpect : A() {
override fun noAnnotationOnActual() {}
}
abstract class Intermediate : I {
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>override fun noAnnotationOnActual() {}<!>
}
actual class <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>FakeOverrideActual<!> : Intermediate(), I
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// MODULE: m1-common
// FILE: common.kt
annotation class Ann
@@ -29,4 +28,4 @@ abstract class Intermediate : I {
override fun noAnnotationOnActual() {}
}
actual class FakeOverrideActual : Intermediate(), I
actual class <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>FakeOverrideActual<!> : Intermediate(), I
@@ -0,0 +1,24 @@
// MODULE: m1-common
// FILE: common.kt
annotation class Ann
expect class WithAnn {
@Ann
fun foo(p: String)
}
expect class WithoutAnn {
fun foo(p: String)
}
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
abstract class Parent<T> {
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>open fun foo(p: T) {}<!>
}
abstract class Intermediate : Parent<String>()
actual class <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>WithAnn<!> : Intermediate()
actual class WithoutAnn : Intermediate()
@@ -0,0 +1,24 @@
// MODULE: m1-common
// FILE: common.kt
annotation class Ann
expect class WithAnn {
@Ann
fun foo(p: String)
}
expect class WithoutAnn {
fun foo(p: String)
}
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
abstract class Parent<T> {
open fun foo(p: T) {}
}
abstract class Intermediate : Parent<String>()
actual class <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>WithAnn<!> : Intermediate()
actual class WithoutAnn : Intermediate()
@@ -0,0 +1,21 @@
// MODULE: m1-common
// FILE: common.kt
annotation class Ann
expect class WithAnn {
@Ann
fun foo()
}
expect class WithoutAnn {
fun foo()
}
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
class Impl {
fun foo() {}
}
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>WithAnn<!> = Impl<!>
actual typealias WithoutAnn = Impl
@@ -0,0 +1,21 @@
// MODULE: m1-common
// FILE: common.kt
annotation class Ann
expect class WithAnn {
@Ann
fun foo()
}
expect class WithoutAnn {
fun foo()
}
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
class Impl {
fun foo() {}
}
actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>WithAnn<!> = Impl
actual typealias WithoutAnn = Impl
@@ -1,7 +1,15 @@
// WITH_STDLIB
// MODULE: m1-common
// FILE: common.kt
@Target(AnnotationTarget.TYPEALIAS, AnnotationTarget.CLASS)
@Target(
AnnotationTarget.TYPEALIAS,
AnnotationTarget.CLASS,
AnnotationTarget.FUNCTION,
AnnotationTarget.PROPERTY,
AnnotationTarget.PROPERTY_GETTER,
AnnotationTarget.PROPERTY_SETTER,
AnnotationTarget.CONSTRUCTOR,
)
annotation class Ann
@Ann
@@ -10,6 +18,32 @@ expect class KtTypealiasNotMatch
@Ann
expect class AnnotationsNotConsideredOnTypealias
annotation class ComplexAnn(val s: String)
expect class MethodsInsideTypealias {
@Ann
fun foo()
}
expect class ValueInsideTypealias {
@Ann
val value: String
}
expect class ConstructorInsideTypealias @Ann constructor()
expect class MethodWithComplexAnnInsideTypealias {
@ComplexAnn("1" + "2")
fun withComplexAnn()
}
expect class InnerClassInsideTypealias {
class Foo {
@Ann
fun foo()
}
}
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
class KtTypealiasNotMatchImpl
@@ -20,3 +54,34 @@ class AnnotationsNotConsideredOnTypealiasImpl
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>@Ann
actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>AnnotationsNotConsideredOnTypealias<!> = AnnotationsNotConsideredOnTypealiasImpl<!>
class MethodsInsideTypealiasImpl {
fun foo() {}
}
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>MethodsInsideTypealias<!> = MethodsInsideTypealiasImpl<!>
class ValueInsideTypealiasImpl {
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>val value: String = ""<!>
}
actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>ValueInsideTypealias<!> = ValueInsideTypealiasImpl
class ConstructorInsideTypealiasImpl
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>ConstructorInsideTypealias<!> = ConstructorInsideTypealiasImpl<!>
class MethodWithComplexAnnInsideTypealiasImpl {
@ComplexAnn("13")
fun withComplexAnn() {}
}
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual typealias MethodWithComplexAnnInsideTypealias = MethodWithComplexAnnInsideTypealiasImpl<!>
class InnerClassInsideTypealiasImpl {
class Foo {
fun foo() {}
}
}
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>InnerClassInsideTypealias<!> = InnerClassInsideTypealiasImpl<!>
@@ -1,7 +1,15 @@
// WITH_STDLIB
// MODULE: m1-common
// FILE: common.kt
@Target(AnnotationTarget.TYPEALIAS, AnnotationTarget.CLASS)
@Target(
AnnotationTarget.TYPEALIAS,
AnnotationTarget.CLASS,
AnnotationTarget.FUNCTION,
AnnotationTarget.PROPERTY,
AnnotationTarget.PROPERTY_GETTER,
AnnotationTarget.PROPERTY_SETTER,
AnnotationTarget.CONSTRUCTOR,
)
annotation class Ann
@Ann
@@ -10,6 +18,32 @@ expect class KtTypealiasNotMatch
@Ann
expect class AnnotationsNotConsideredOnTypealias
annotation class ComplexAnn(val s: String)
expect class MethodsInsideTypealias {
@Ann
fun foo()
}
expect class ValueInsideTypealias {
@Ann
val value: String
}
expect class ConstructorInsideTypealias @Ann constructor()
expect class MethodWithComplexAnnInsideTypealias {
@ComplexAnn("1" + "2")
fun withComplexAnn()
}
expect class InnerClassInsideTypealias {
class Foo {
@Ann
fun foo()
}
}
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
class KtTypealiasNotMatchImpl
@@ -20,3 +54,34 @@ class AnnotationsNotConsideredOnTypealiasImpl
@Ann
actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>AnnotationsNotConsideredOnTypealias<!> = AnnotationsNotConsideredOnTypealiasImpl
class MethodsInsideTypealiasImpl {
fun foo() {}
}
actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>MethodsInsideTypealias<!> = MethodsInsideTypealiasImpl
class ValueInsideTypealiasImpl {
val value: String = ""
}
actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>ValueInsideTypealias<!> = ValueInsideTypealiasImpl
class ConstructorInsideTypealiasImpl
actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>ConstructorInsideTypealias<!> = ConstructorInsideTypealiasImpl
class MethodWithComplexAnnInsideTypealiasImpl {
@ComplexAnn("13")
fun withComplexAnn() {}
}
actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>MethodWithComplexAnnInsideTypealias<!> = MethodWithComplexAnnInsideTypealiasImpl
class InnerClassInsideTypealiasImpl {
class Foo {
fun foo() {}
}
}
actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>InnerClassInsideTypealias<!> = InnerClassInsideTypealiasImpl
@@ -1,5 +1,5 @@
// WITH_STDLIB
// DIAGNOSTICS: -ACTUAL_TYPEALIAS_TO_SPECIAL_ANNOTATION
// DIAGNOSTICS: -ACTUAL_TYPEALIAS_TO_SPECIAL_ANNOTATION, -ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER, -ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_SUPERTYPES_AS_NON_FINAL_EXPECT_CLASSIFIER
// MODULE: m1-common
// FILE: common.kt
@Target(
@@ -40,4 +40,4 @@ expect abstract class MyAbstractIterator<T> {
actual typealias MyDeprecatedMatch = kotlin.Deprecated
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual typealias MyAbstractIterator<T> = AbstractIterator<T><!>
<!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>MyAbstractIterator<!><T> = AbstractIterator<T><!>
@@ -1,5 +1,5 @@
// WITH_STDLIB
// DIAGNOSTICS: -ACTUAL_TYPEALIAS_TO_SPECIAL_ANNOTATION
// DIAGNOSTICS: -ACTUAL_TYPEALIAS_TO_SPECIAL_ANNOTATION, -ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER, -ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_SUPERTYPES_AS_NON_FINAL_EXPECT_CLASSIFIER
// MODULE: m1-common
// FILE: common.kt
@Target(
@@ -40,4 +40,4 @@ actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>MyDeprecatedNotMatch<!>
actual typealias MyDeprecatedMatch = kotlin.Deprecated
actual typealias <!ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER, ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_SUPERTYPES_AS_NON_FINAL_EXPECT_CLASSIFIER!>MyAbstractIterator<!><T> = AbstractIterator<T>
actual typealias <!ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT!>MyAbstractIterator<!><T> = AbstractIterator<T>