From 6611a55a6068690a0bedb47fdeb342141fc98da7 Mon Sep 17 00:00:00 2001 From: Roman Efremov Date: Mon, 17 Jul 2023 14:55:03 +0200 Subject: [PATCH] [FE] Relax rules of matching `@Target` annotation on expect and actual Allow `expect` targets to be subset of `actual`. ^KT-58551 --- ...DiagnosticsWithLightTreeTestGenerated.java | 6 +++ ...endMPPDiagnosticsWithPsiTestGenerated.java | 6 +++ .../mpp/FirExpectActualMatchingContextImpl.kt | 7 +++- .../IrExpectActualMatchingContext.kt | 12 +++++- .../irConstExpressionValuesEqualityChecker.kt | 18 +++++++-- ...tractExpectActualAnnotationMatchChecker.kt | 20 ++++++++-- ...tionArgumentsCompatibilityCheckStrategy.kt | 37 +++++++++++++++++++ .../calls/mpp/ExpectActualMatchingContext.kt | 6 ++- .../ClassicExpectActualMatchingContext.kt | 14 +++++-- .../constExpressionValuesEqualityChecker.kt | 19 +++++++--- .../annotationTarget.fir.kt | 33 +++++++++++++++++ .../annotationMatching/annotationTarget.kt | 33 +++++++++++++++++ .../typealiasToKtLibrary.fir.kt | 3 +- .../typealiasToKtLibrary.kt | 3 +- .../test/runners/DiagnosticTestGenerated.java | 6 +++ 15 files changed, 202 insertions(+), 21 deletions(-) create mode 100644 compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/ExpectActualCollectionArgumentsCompatibilityCheckStrategy.kt create mode 100644 compiler/testData/diagnostics/tests/multiplatform/annotationMatching/annotationTarget.fir.kt create mode 100644 compiler/testData/diagnostics/tests/multiplatform/annotationMatching/annotationTarget.kt 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 a611748b6e4..875abb9c763 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 @@ -226,6 +226,12 @@ public class FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated extends Abst runTest("compiler/testData/diagnostics/tests/multiplatform/annotationMatching/annotationArgumentsDefaults.kt"); } + @Test + @TestMetadata("annotationTarget.kt") + public void testAnnotationTarget() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/annotationMatching/annotationTarget.kt"); + } + @Test @TestMetadata("annotationTypeParameters.kt") public void testAnnotationTypeParameters() 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 10e11534929..87f7d4b0f35 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 @@ -226,6 +226,12 @@ public class FirOldFrontendMPPDiagnosticsWithPsiTestGenerated extends AbstractFi runTest("compiler/testData/diagnostics/tests/multiplatform/annotationMatching/annotationArgumentsDefaults.kt"); } + @Test + @TestMetadata("annotationTarget.kt") + public void testAnnotationTarget() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/annotationMatching/annotationTarget.kt"); + } + @Test @TestMetadata("annotationTypeParameters.kt") public void testAnnotationTypeParameters() throws Exception { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatchingContextImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatchingContextImpl.kt index f16871c5d7c..8b0dda18578 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatchingContextImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatchingContextImpl.kt @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.mpp.* import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualCollectionArgumentsCompatibilityCheckStrategy import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualMatchingContext.AnnotationCallInfo import org.jetbrains.kotlin.resolve.checkers.OptInNames import org.jetbrains.kotlin.types.AbstractTypeChecker @@ -317,7 +318,11 @@ class FirExpectActualMatchingContextImpl private constructor( override val DeclarationSymbolMarker.annotations: List get() = asSymbol().resolvedAnnotationsWithArguments.map(::AnnotationCallInfoImpl) - override fun areAnnotationArgumentsEqual(annotation1: AnnotationCallInfo, annotation2: AnnotationCallInfo): Boolean { + override fun areAnnotationArgumentsEqual( + annotation1: AnnotationCallInfo, + annotation2: AnnotationCallInfo, + collectionArgumentsCompatibilityCheckStrategy: ExpectActualCollectionArgumentsCompatibilityCheckStrategy, + ): Boolean { fun AnnotationCallInfo.getFirAnnotation(): FirAnnotation { return (this as AnnotationCallInfoImpl).annotation } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrExpectActualMatchingContext.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrExpectActualMatchingContext.kt index 0c585187d11..7ede47d26e6 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrExpectActualMatchingContext.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrExpectActualMatchingContext.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.mpp.* import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualCollectionArgumentsCompatibilityCheckStrategy import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualMatchingContext import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualMatchingContext.AnnotationCallInfo import org.jetbrains.kotlin.resolve.checkers.OptInNames @@ -453,10 +454,17 @@ internal abstract class IrExpectActualMatchingContext( override val DeclarationSymbolMarker.annotations: List get() = asIr().annotations.map(::AnnotationCallInfoImpl) - override fun areAnnotationArgumentsEqual(annotation1: AnnotationCallInfo, annotation2: AnnotationCallInfo): Boolean { + override fun areAnnotationArgumentsEqual( + annotation1: AnnotationCallInfo, annotation2: AnnotationCallInfo, + collectionArgumentsCompatibilityCheckStrategy: ExpectActualCollectionArgumentsCompatibilityCheckStrategy, + ): Boolean { fun AnnotationCallInfo.getIrElement(): IrConstructorCall = (this as AnnotationCallInfoImpl).irElement - return areIrExpressionConstValuesEqual(annotation1.getIrElement(), annotation2.getIrElement()) + return areIrExpressionConstValuesEqual( + annotation1.getIrElement(), + annotation2.getIrElement(), + collectionArgumentsCompatibilityCheckStrategy, + ) } internal fun getClassIdAfterActualization(classId: ClassId): ClassId { diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/irConstExpressionValuesEqualityChecker.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/irConstExpressionValuesEqualityChecker.kt index 00b425f9578..45aefdd003f 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/irConstExpressionValuesEqualityChecker.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/irConstExpressionValuesEqualityChecker.kt @@ -8,8 +8,13 @@ package org.jetbrains.kotlin.backend.common.actualizer import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.types.classOrFail +import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualCollectionArgumentsCompatibilityCheckStrategy -internal fun IrExpectActualMatchingContext.areIrExpressionConstValuesEqual(a: IrElement?, b: IrElement?): Boolean { +internal fun IrExpectActualMatchingContext.areIrExpressionConstValuesEqual( + a: IrElement?, + b: IrElement?, + collectionArgumentsCompatibilityCheckStrategy: ExpectActualCollectionArgumentsCompatibilityCheckStrategy, +): Boolean { return when { a == null || b == null -> (a == null) == (b == null) @@ -25,15 +30,20 @@ internal fun IrExpectActualMatchingContext.areIrExpressionConstValuesEqual(a: Ir a is IrGetEnumValue && b is IrGetEnumValue -> equalBy(a, b) { it.symbol.signature?.toString() } a is IrVararg && b is IrVararg -> { - equalBy(a, b) { it.elements.size } && - a.elements.zip(b.elements).all { (f, s) -> areIrExpressionConstValuesEqual(f, s) } + collectionArgumentsCompatibilityCheckStrategy.areCompatible(a.elements, b.elements) { f, s -> + areIrExpressionConstValuesEqual(f, s, collectionArgumentsCompatibilityCheckStrategy) + } } a is IrConstructorCall && b is IrConstructorCall -> { equalBy(a, b) { it.valueArgumentsCount } && areCompatibleExpectActualTypes(a.type, b.type) && (0.. - areIrExpressionConstValuesEqual(a.getValueArgument(i), b.getValueArgument(i)) + areIrExpressionConstValuesEqual( + a.getValueArgument(i), + b.getValueArgument(i), + collectionArgumentsCompatibilityCheckStrategy + ) } } 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 a04a845851f..8be8406c7f9 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 @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.resolve.calls.mpp import org.jetbrains.kotlin.mpp.DeclarationSymbolMarker import org.jetbrains.kotlin.mpp.TypeAliasSymbolMarker +import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.StandardClassIds object AbstractExpectActualAnnotationMatchChecker { @@ -46,17 +47,30 @@ object AbstractExpectActualAnnotationMatchChecker { val actualAnnotationsByName = actualSymbol.annotations.groupBy { it.classId } for (expectAnnotation in expectSymbol.annotations) { - if (expectAnnotation.classId in SKIPPED_CLASS_IDS || expectAnnotation.isOptIn) { + val expectClassId = expectAnnotation.classId ?: continue + if (expectClassId in SKIPPED_CLASS_IDS || expectAnnotation.isOptIn) { continue } if (expectAnnotation.isRetentionSource && skipSourceAnnotations) { continue } - val actualAnnotationsWithSameClassId = actualAnnotationsByName[expectAnnotation.classId] ?: emptyList() - if (actualAnnotationsWithSameClassId.none { areAnnotationArgumentsEqual(expectAnnotation, it) }) { + val actualAnnotationsWithSameClassId = actualAnnotationsByName[expectClassId] ?: emptyList() + val collectionCompatibilityChecker = getAnnotationCollectionArgumentsCompatibilityChecker(expectClassId) + if (actualAnnotationsWithSameClassId.none { + areAnnotationArgumentsEqual(expectAnnotation, it, collectionCompatibilityChecker) + }) { return Incompatibility(expectSymbol, actualSymbol) } } return null } + + private fun getAnnotationCollectionArgumentsCompatibilityChecker(annotationClassId: ClassId): + ExpectActualCollectionArgumentsCompatibilityCheckStrategy { + return if (annotationClassId == StandardClassIds.Annotations.Target) { + ExpectActualCollectionArgumentsCompatibilityCheckStrategy.ExpectIsSubsetOfActual + } else { + ExpectActualCollectionArgumentsCompatibilityCheckStrategy.Default + } + } } \ No newline at end of file diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/ExpectActualCollectionArgumentsCompatibilityCheckStrategy.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/ExpectActualCollectionArgumentsCompatibilityCheckStrategy.kt new file mode 100644 index 00000000000..c813a200a83 --- /dev/null +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/ExpectActualCollectionArgumentsCompatibilityCheckStrategy.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.resolve.calls.mpp + + +sealed class ExpectActualCollectionArgumentsCompatibilityCheckStrategy { + abstract fun areCompatible( + expectArg: Collection, + actualArg: Collection, + elementsEqual: (T, T) -> Boolean, + ): Boolean + + internal data object Default : ExpectActualCollectionArgumentsCompatibilityCheckStrategy() { + override fun areCompatible( + expectArg: Collection, + actualArg: Collection, + elementsEqual: (T, T) -> Boolean, + ): Boolean { + return expectArg.size == actualArg.size && expectArg.zip(actualArg).all { (e1, e2) -> elementsEqual(e1, e2) } + } + } + + internal data object ExpectIsSubsetOfActual : ExpectActualCollectionArgumentsCompatibilityCheckStrategy() { + override fun areCompatible( + expectArg: Collection, + actualArg: Collection, + elementsEqual: (T, T) -> Boolean, + ): Boolean { + return expectArg.all { e1 -> + actualArg.any { e2 -> elementsEqual(e1, e2) } + } + } + } +} diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/ExpectActualMatchingContext.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/ExpectActualMatchingContext.kt index 65c984e4606..7c0053e1ff7 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/ExpectActualMatchingContext.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/ExpectActualMatchingContext.kt @@ -160,7 +160,11 @@ interface ExpectActualMatchingContext : TypeSystemC val DeclarationSymbolMarker.annotations: List - fun areAnnotationArgumentsEqual(annotation1: AnnotationCallInfo, annotation2: AnnotationCallInfo): Boolean + fun areAnnotationArgumentsEqual( + annotation1: AnnotationCallInfo, + annotation2: AnnotationCallInfo, + collectionArgumentsCompatibilityCheckStrategy: ExpectActualCollectionArgumentsCompatibilityCheckStrategy, + ): Boolean val DeclarationSymbolMarker.hasSourceAnnotationsErased: Boolean diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ClassicExpectActualMatchingContext.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ClassicExpectActualMatchingContext.kt index bc607e98118..8c2361ef21c 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ClassicExpectActualMatchingContext.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ClassicExpectActualMatchingContext.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.calls.components.ClassicTypeSystemContextForCS +import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualCollectionArgumentsCompatibilityCheckStrategy import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualMatchingContext import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualMatchingContext.AnnotationCallInfo import org.jetbrains.kotlin.resolve.checkers.OptInNames @@ -337,11 +338,18 @@ class ClassicExpectActualMatchingContext(val platformModule: ModuleDescriptor) : override val DeclarationSymbolMarker.annotations: List get() = asDescriptor().annotations.map(::AnnotationCallInfoImpl) - - override fun areAnnotationArgumentsEqual(annotation1: AnnotationCallInfo, annotation2: AnnotationCallInfo): Boolean { + override fun areAnnotationArgumentsEqual( + annotation1: AnnotationCallInfo, + annotation2: AnnotationCallInfo, + collectionArgumentsCompatibilityCheckStrategy: ExpectActualCollectionArgumentsCompatibilityCheckStrategy, + ): Boolean { fun AnnotationCallInfo.getDescriptor(): AnnotationDescriptor = (this as AnnotationCallInfoImpl).annotationDescriptor - return areExpressionConstValuesEqual(annotation1.getDescriptor(), annotation2.getDescriptor()) + return areExpressionConstValuesEqual( + annotation1.getDescriptor(), + annotation2.getDescriptor(), + collectionArgumentsCompatibilityCheckStrategy, + ) } private class AnnotationCallInfoImpl( diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/constExpressionValuesEqualityChecker.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/constExpressionValuesEqualityChecker.kt index 34b3d46bfb5..977f46b6aa8 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/constExpressionValuesEqualityChecker.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/constExpressionValuesEqualityChecker.kt @@ -6,10 +6,15 @@ package org.jetbrains.kotlin.resolve.multiplatform import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor +import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualCollectionArgumentsCompatibilityCheckStrategy import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualMatchingContext import org.jetbrains.kotlin.resolve.constants.ConstantValue -internal fun ExpectActualMatchingContext<*>.areExpressionConstValuesEqual(a: Any?, b: Any?): Boolean { +internal fun ExpectActualMatchingContext<*>.areExpressionConstValuesEqual( + a: Any?, + b: Any?, + collectionArgumentsCompatibilityCheckStrategy: ExpectActualCollectionArgumentsCompatibilityCheckStrategy, +): Boolean { return when { a is AnnotationDescriptor && b is AnnotationDescriptor -> { val aArgs = a.allValueArguments @@ -17,16 +22,20 @@ internal fun ExpectActualMatchingContext<*>.areExpressionConstValuesEqual(a: Any a.fqName == b.fqName && aArgs.size == bArgs.size && areCompatibleExpectActualTypes(a.type, b.type) && - aArgs.keys.all { k -> areExpressionConstValuesEqual(aArgs[k], bArgs[k]) } + aArgs.keys.all { k -> areExpressionConstValuesEqual(aArgs[k], bArgs[k], collectionArgumentsCompatibilityCheckStrategy) } } a is ConstantValue<*> && b is ConstantValue<*> -> { - areExpressionConstValuesEqual(a.value, b.value) + areExpressionConstValuesEqual(a.value, b.value, collectionArgumentsCompatibilityCheckStrategy) } a is Collection<*> && b is Collection<*> -> { - a.size == b.size && a.zip(b).all { (f, s) -> areExpressionConstValuesEqual(f, s) } + collectionArgumentsCompatibilityCheckStrategy.areCompatible(a, b) { f, s -> + areExpressionConstValuesEqual(f, s, collectionArgumentsCompatibilityCheckStrategy) + } } a is Array<*> && b is Array<*> -> { - a.size == b.size && a.zip(b).all { (f, s) -> areExpressionConstValuesEqual(f, s) } + collectionArgumentsCompatibilityCheckStrategy.areCompatible(a.toList(), b.toList()) { f, s -> + areExpressionConstValuesEqual(f, s, collectionArgumentsCompatibilityCheckStrategy) + } } else -> a == b } diff --git a/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/annotationTarget.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/annotationTarget.fir.kt new file mode 100644 index 00000000000..577a9ce58b7 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/annotationTarget.fir.kt @@ -0,0 +1,33 @@ +// MODULE: m1-common +// FILE: common.kt +@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS) +expect annotation class ExpectIsSubsetOfActual + +@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) +expect annotation class ExpectIsSubsetOfActualDifferentOrder + +@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS) +expect annotation class MoreTargetsOnExpect + +@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) +expect annotation class RepeatedTargetsInExpect + +@Target(allowedTargets = []) +expect annotation class EmptyTargetsActual + +// MODULE: m1-jvm()()(m1-common) +// FILE: jvm.kt +@Target(AnnotationTarget.CONSTRUCTOR, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.CLASS) +actual annotation class ExpectIsSubsetOfActual + +@Target(AnnotationTarget.CONSTRUCTOR, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.CLASS) +actual annotation class ExpectIsSubsetOfActualDifferentOrder + +@Target(AnnotationTarget.FUNCTION) +actual annotation class MoreTargetsOnExpect + +@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS, AnnotationTarget.TYPEALIAS) +actual annotation class RepeatedTargetsInExpect + +@Target(AnnotationTarget.FUNCTION) +actual annotation class EmptyTargetsActual diff --git a/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/annotationTarget.kt b/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/annotationTarget.kt new file mode 100644 index 00000000000..308afdf6bba --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/annotationTarget.kt @@ -0,0 +1,33 @@ +// MODULE: m1-common +// FILE: common.kt +@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS) +expect annotation class ExpectIsSubsetOfActual + +@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) +expect annotation class ExpectIsSubsetOfActualDifferentOrder + +@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS) +expect annotation class MoreTargetsOnExpect + +@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) +expect annotation class RepeatedTargetsInExpect + +@Target(allowedTargets = []) +expect annotation class EmptyTargetsActual + +// MODULE: m1-jvm()()(m1-common) +// FILE: jvm.kt +@Target(AnnotationTarget.CONSTRUCTOR, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.CLASS) +actual annotation class ExpectIsSubsetOfActual + +@Target(AnnotationTarget.CONSTRUCTOR, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.CLASS) +actual annotation class ExpectIsSubsetOfActualDifferentOrder + +@Target(AnnotationTarget.FUNCTION) +actual annotation class MoreTargetsOnExpect + +@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS, AnnotationTarget.TYPEALIAS) +actual annotation class RepeatedTargetsInExpect + +@Target(AnnotationTarget.FUNCTION) +actual annotation class EmptyTargetsActual diff --git a/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/typealiasToKtLibrary.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/typealiasToKtLibrary.fir.kt index a97a63c68d1..605cb6c9b96 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/typealiasToKtLibrary.fir.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/typealiasToKtLibrary.fir.kt @@ -10,7 +10,8 @@ AnnotationTarget.CONSTRUCTOR, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.PROPERTY_GETTER, - // removed target TYPEALIAS + AnnotationTarget.TYPEALIAS, + AnnotationTarget.TYPE, // added target ) expect annotation class MyDeprecatedNotMatch diff --git a/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/typealiasToKtLibrary.kt b/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/typealiasToKtLibrary.kt index cff8a1b7bde..067dc4f9558 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/typealiasToKtLibrary.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/annotationMatching/typealiasToKtLibrary.kt @@ -10,7 +10,8 @@ AnnotationTarget.CONSTRUCTOR, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.PROPERTY_GETTER, - // removed target TYPEALIAS + AnnotationTarget.TYPEALIAS, + AnnotationTarget.TYPE, // added target ) expect annotation class MyDeprecatedNotMatch 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 189d6075b71..032d6582bdd 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 @@ -22771,6 +22771,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/multiplatform/annotationMatching/annotationArgumentsDefaults.kt"); } + @Test + @TestMetadata("annotationTarget.kt") + public void testAnnotationTarget() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/annotationMatching/annotationTarget.kt"); + } + @Test @TestMetadata("annotationTypeParameters.kt") public void testAnnotationTypeParameters() throws Exception {