diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated.java index 1f33cef8761..6be983aec34 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated.java @@ -926,6 +926,12 @@ public class FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated extends Abst runTest("compiler/testData/diagnostics/tests/multiplatform/annotationMatching/typealiasToKtLibrary.kt"); } + @Test + @TestMetadata("valueParameters.kt") + public void testValueParameters() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/annotationMatching/valueParameters.kt"); + } + @Test @TestMetadata("withAnnotationActualTypealias.kt") public void testWithAnnotationActualTypealias() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithPsiTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithPsiTestGenerated.java index 148f4d8a9ad..22c34459a89 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithPsiTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithPsiTestGenerated.java @@ -926,6 +926,12 @@ public class FirOldFrontendMPPDiagnosticsWithPsiTestGenerated extends AbstractFi runTest("compiler/testData/diagnostics/tests/multiplatform/annotationMatching/typealiasToKtLibrary.kt"); } + @Test + @TestMetadata("valueParameters.kt") + public void testValueParameters() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/annotationMatching/valueParameters.kt"); + } + @Test @TestMetadata("withAnnotationActualTypealias.kt") public void testWithAnnotationActualTypealias() throws Exception { diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/AbstractExpectActualAnnotationMatchChecker.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/AbstractExpectActualAnnotationMatchChecker.kt index 9a981acd7b1..da63de306a7 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/AbstractExpectActualAnnotationMatchChecker.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/AbstractExpectActualAnnotationMatchChecker.kt @@ -28,6 +28,14 @@ object AbstractExpectActualAnnotationMatchChecker { ) class Incompatibility( + /** + * [expectSymbol] and [actualSymbol] are declaration symbols where annotation been mismatched. + * They are needed for writing whole declarations in diagnostic text. + * They are not the same as symbols passed to checker as arguments in [areAnnotationsCompatible] in following cases: + * 1. If [actualSymbol] is typealias, it will be expanded. + * 2. If problem is in class member, [expectSymbol] will be mismatched member, not the original class. + * 3. If annotation mismatched on function value parameter, symbols will be whole functions, not value parameter symbols. + */ val expectSymbol: DeclarationSymbolMarker, val actualSymbol: DeclarationSymbolMarker, val type: IncompatibilityType, @@ -63,6 +71,7 @@ object AbstractExpectActualAnnotationMatchChecker { actualSymbol: CallableSymbolMarker, ): Incompatibility? { commonForClassAndCallableChecks(expectSymbol, actualSymbol)?.let { return it } + areAnnotationsOnValueParametersCompatible(expectSymbol, actualSymbol)?.let { return it } return null } @@ -100,6 +109,24 @@ object AbstractExpectActualAnnotationMatchChecker { return null } + context (ExpectActualMatchingContext<*>) + private fun areAnnotationsOnValueParametersCompatible( + expectSymbol: CallableSymbolMarker, + actualSymbol: CallableSymbolMarker, + ): Incompatibility? { + val expectParams = expectSymbol.valueParameters + val actualParams = actualSymbol.valueParameters + + if (expectParams.size != actualParams.size) return null + + return expectParams.zip(actualParams).firstNotNullOfOrNull { (expectParam, actualParam) -> + areAnnotationsSetOnDeclarationsCompatible(expectParam, actualParam)?.let { + // Write containing declarations into diagnostic + Incompatibility(expectSymbol, actualSymbol, it.type) + } + } + } + context (ExpectActualMatchingContext<*>) private fun areAnnotationsSetOnDeclarationsCompatible( expectSymbol: DeclarationSymbolMarker, diff --git a/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/checkDiagnosticFullText.diag.txt b/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/checkDiagnosticFullText.diag.txt index 29e0266a9a2..97ee54f26b9 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/checkDiagnosticFullText.diag.txt +++ b/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/checkDiagnosticFullText.diag.txt @@ -1,24 +1,28 @@ // -- Module: -- // -- Module: -- -/jvm.kt:29:14: warning: annotation `@Ann` is missing on actual declaration. +/jvm.kt:31: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:32:16: warning: annotation `@Ann` is missing on actual declaration. +/jvm.kt:34: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() {} ^ -/jvm.kt:37:18: warning: annotation `@Ann` is missing on actual declaration. +/jvm.kt:39:18: warning: annotation `@Ann` is missing on actual declaration. 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:42:18: warning: annotation `@Ann` is missing on actual declaration. +/jvm.kt:44: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")`. +/jvm.kt:47: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() {} ^ +/jvm.kt:49:12: warning: annotation `@Ann` is missing on actual declaration. +All annotations from expect `fun inValueParam(arg: String): Unit defined in root package in file common.kt` must be present with the same arguments on actual `fun inValueParam(arg: String): Unit defined in root package in file jvm.kt`, otherwise they might behave incorrectly. +actual fun inValueParam(arg: String) {} + ^ diff --git a/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/checkDiagnosticFullText.fir.diag.txt b/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/checkDiagnosticFullText.fir.diag.txt index f3fe0e8065d..f03b1674954 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/checkDiagnosticFullText.fir.diag.txt +++ b/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/checkDiagnosticFullText.fir.diag.txt @@ -1,14 +1,17 @@ -/jvm.kt:(88,95): warning: Annotation `@Ann()` is missing on actual declaration. +/jvm.kt:(90,97): 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:(136,144): warning: Annotation `@Ann()` is missing on actual declaration. +/jvm.kt:(138,146): 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:(194,206): warning: Annotation `@Ann()` is missing on actual declaration. +/jvm.kt:(196,208): 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:(299,322): warning: Annotation `@Ann()` is missing on actual declaration. +/jvm.kt:(301,324): 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))`. +/jvm.kt:(389,405): 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. + +/jvm.kt:(423,435): warning: Annotation `@Ann()` is missing on actual declaration. +All annotations from expect 'fun inValueParam(arg: String): Unit' must be present with the same arguments on actual 'fun inValueParam(arg: String): Unit', otherwise they might behave incorrectly. diff --git a/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/checkDiagnosticFullText.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/checkDiagnosticFullText.fir.kt index 8da9e0b3283..a455012e5fd 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/checkDiagnosticFullText.fir.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/checkDiagnosticFullText.fir.kt @@ -24,6 +24,8 @@ annotation class WithArg(val s: String) @WithArg("str") expect fun withDifferentArg() +expect fun inValueParam(@Ann arg: String) + // MODULE: m1-jvm()()(m1-common) // FILE: jvm.kt actual class OnClass @@ -43,3 +45,5 @@ class MemberScopeViaTypealiasImpl { @WithArg("other str") actual fun withDifferentArg() {} + +actual fun inValueParam(arg: String) {} diff --git a/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/checkDiagnosticFullText.kt b/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/checkDiagnosticFullText.kt index 912ff475112..a9219fe1e95 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/checkDiagnosticFullText.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/checkDiagnosticFullText.kt @@ -24,6 +24,8 @@ annotation class WithArg(val s: String) @WithArg("str") expect fun withDifferentArg() +expect fun inValueParam(@Ann arg: String) + // MODULE: m1-jvm()()(m1-common) // FILE: jvm.kt actual class OnClass @@ -43,3 +45,5 @@ actual typealias MemberScopeViaTypealias< @WithArg("other str") actual fun withDifferentArg() {} + +actual fun inValueParam(arg: String) {} diff --git a/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/valueParameters.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/valueParameters.fir.kt new file mode 100644 index 00000000000..4746b2a2413 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/valueParameters.fir.kt @@ -0,0 +1,18 @@ +// MODULE: m1-common +// FILE: common.kt +@Target(AnnotationTarget.VALUE_PARAMETER) +annotation class Ann + +expect fun inMethod(@Ann arg: String) + +expect class InConstructor(@Ann arg: String) + +expect fun withIncopatibility(@Ann p1: String, @Ann p2: String) + +// MODULE: m1-jvm()()(m1-common) +// FILE: jvm.kt +actual fun inMethod(arg: String) {} + +actual class InConstructor actual constructor(arg: String) {} + +actual fun withIncopatibility(p1: String) {} diff --git a/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/valueParameters.kt b/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/valueParameters.kt new file mode 100644 index 00000000000..cc74b97805f --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/valueParameters.kt @@ -0,0 +1,18 @@ +// MODULE: m1-common +// FILE: common.kt +@Target(AnnotationTarget.VALUE_PARAMETER) +annotation class Ann + +expect fun inMethod(@Ann arg: String) + +expect class InConstructor(@Ann arg: String) + +expect fun withIncopatibility(@Ann p1: String, @Ann p2: String) + +// MODULE: m1-jvm()()(m1-common) +// FILE: jvm.kt +actual fun inMethod(arg: String) {} + +actual class InConstructor actual constructor(arg: String) {} + +actual fun withIncopatibility(p1: String) {} 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 a5271203cdd..327dc132c44 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 @@ -23921,6 +23921,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/multiplatform/annotationMatching/typealiasToKtLibrary.kt"); } + @Test + @TestMetadata("valueParameters.kt") + public void testValueParameters() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/annotationMatching/valueParameters.kt"); + } + @Test @TestMetadata("withAnnotationActualTypealias.kt") public void testWithAnnotationActualTypealias() throws Exception {