KT-57135 Take into account annotations' allowed targets
diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirUtils.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirUtils.kt
index e774866..adabb47 100644
--- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirUtils.kt
+++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirUtils.kt
@@ -10,6 +10,7 @@
import org.jetbrains.kotlin.analysis.api.fir.annotations.mapAnnotationParameters
import org.jetbrains.kotlin.analysis.api.fir.evaluate.FirAnnotationValueConverter
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
+import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.toAnnotationClassId
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
@@ -74,7 +75,7 @@
): KtAnnotationApplicationWithArgumentsInfo = KtAnnotationApplicationWithArgumentsInfo(
classId = toAnnotationClassId(useSiteSession),
psi = psi as? KtCallElement,
- useSiteTarget = useSiteTarget,
+ useSiteTarget = effectiveUseSiteTarget,
arguments = FirAnnotationValueConverter.toNamedConstantValue(
mapAnnotationParameters(this),
useSiteSession,
@@ -88,7 +89,11 @@
): KtAnnotationApplicationInfo = KtAnnotationApplicationInfo(
classId = toAnnotationClassId(useSiteSession),
psi = psi as? KtCallElement,
- useSiteTarget = useSiteTarget,
+ useSiteTarget = effectiveUseSiteTarget,
isCallWithArguments = this is FirAnnotationCall && arguments.isNotEmpty(),
index = index,
)
+
+
+val FirAnnotation.effectiveUseSiteTarget: AnnotationUseSiteTarget?
+ get() = calculatedUseSiteTarget ?: useSiteTarget
\ No newline at end of file
diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/KtFirAnnotationListForType.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/KtFirAnnotationListForType.kt
index 1f1e13f..4592076 100644
--- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/KtFirAnnotationListForType.kt
+++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/KtFirAnnotationListForType.kt
@@ -9,6 +9,7 @@
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationInfo
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationWithArgumentsInfo
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList
+import org.jetbrains.kotlin.analysis.api.fir.effectiveUseSiteTarget
import org.jetbrains.kotlin.analysis.api.fir.toKtAnnotationApplication
import org.jetbrains.kotlin.analysis.api.fir.toKtAnnotationInfo
import org.jetbrains.kotlin.analysis.api.impl.base.annotations.KtEmptyAnnotationsList
@@ -46,7 +47,7 @@
override fun hasAnnotation(classId: ClassId, useSiteTargetFilter: AnnotationUseSiteTargetFilter): Boolean = withValidityAssertion {
coneType.customAnnotationsWithLazyResolve(FirResolvePhase.TYPES).any {
- useSiteTargetFilter.isAllowed(it.useSiteTarget) && it.toAnnotationClassId(useSiteSession) == classId
+ useSiteTargetFilter.isAllowed(it.effectiveUseSiteTarget) && it.toAnnotationClassId(useSiteSession) == classId
}
}
@@ -55,7 +56,7 @@
useSiteTargetFilter: AnnotationUseSiteTargetFilter,
): List<KtAnnotationApplicationWithArgumentsInfo> = withValidityAssertion {
coneType.customAnnotationsWithLazyResolve(FirResolvePhase.ANNOTATIONS_ARGUMENTS_MAPPING).mapIndexedNotNull { index, annotation ->
- if (!useSiteTargetFilter.isAllowed(annotation.useSiteTarget) || annotation.toAnnotationClassId(useSiteSession) != classId) {
+ if (!useSiteTargetFilter.isAllowed(annotation.effectiveUseSiteTarget) || annotation.toAnnotationClassId(useSiteSession) != classId) {
return@mapIndexedNotNull null
}
diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/firAnnotationUtils.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/firAnnotationUtils.kt
index 04d656c..4b0b98e 100644
--- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/firAnnotationUtils.kt
+++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/firAnnotationUtils.kt
@@ -8,6 +8,7 @@
import org.jetbrains.kotlin.analysis.api.annotations.AnnotationUseSiteTargetFilter
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationInfo
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationWithArgumentsInfo
+import org.jetbrains.kotlin.analysis.api.fir.effectiveUseSiteTarget
import org.jetbrains.kotlin.analysis.api.fir.toKtAnnotationApplication
import org.jetbrains.kotlin.analysis.api.fir.toKtAnnotationInfo
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirEntry
@@ -56,14 +57,14 @@
val annotations = annotationContainer.resolvedCompilerRequiredAnnotations(firSymbol)
for (index in annotations.indices) {
val annotation = annotations[index]
- if (useSiteTargetFilter.isAllowed(annotation.useSiteTarget) && annotation.toAnnotationClassIdSafe(useSiteSession) == classId) {
+ if (useSiteTargetFilter.isAllowed(annotation.effectiveUseSiteTarget) && annotation.toAnnotationClassIdSafe(useSiteSession) == classId) {
add(annotation.toKtAnnotationApplication(useSiteSession, index))
}
}
}
} else {
annotationContainer.resolvedAnnotationsWithArguments(firSymbol).mapIndexedNotNull { index, annotation ->
- if (!useSiteTargetFilter.isAllowed(annotation.useSiteTarget) || annotation.toAnnotationClassId(useSiteSession) != classId) {
+ if (!useSiteTargetFilter.isAllowed(annotation.effectiveUseSiteTarget) || annotation.toAnnotationClassId(useSiteSession) != classId) {
return@mapIndexedNotNull null
}
@@ -108,7 +109,7 @@
val annotations = annotationContainer.resolvedCompilerRequiredAnnotations(firSymbol)
for (index in annotations.indices) {
val annotation = annotations[index]
- if (useSiteTargetFilter.isAllowed(annotation.useSiteTarget) && annotation.toAnnotationClassIdSafe(useSiteSession) == classId) {
+ if (useSiteTargetFilter.isAllowed(annotation.effectiveUseSiteTarget) && annotation.toAnnotationClassIdSafe(useSiteSession) == classId) {
return true
}
}
@@ -116,7 +117,7 @@
false
} else {
annotationContainer.resolvedAnnotationsWithClassIds(firSymbol).any {
- useSiteTargetFilter.isAllowed(it.useSiteTarget) && it.toAnnotationClassId(useSiteSession) == classId
+ useSiteTargetFilter.isAllowed(it.effectiveUseSiteTarget) && it.toAnnotationClassId(useSiteSession) == classId
}
}
}
diff --git a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/SymbolLightClassesByPsiForLibraryTestGenerated.java b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/SymbolLightClassesByPsiForLibraryTestGenerated.java
index 7faf340..e0d57f1 100644
--- a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/SymbolLightClassesByPsiForLibraryTestGenerated.java
+++ b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/SymbolLightClassesByPsiForLibraryTestGenerated.java
@@ -25,6 +25,12 @@
}
@Test
+ @TestMetadata("allowedTargets.kt")
+ public void testAllowedTargets() throws Exception {
+ runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/allowedTargets.kt");
+ }
+
+ @Test
@TestMetadata("annotationWithSetParamPropertyModifier.kt")
public void testAnnotationWithSetParamPropertyModifier() throws Exception {
runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/annotationWithSetParamPropertyModifier.kt");
diff --git a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/SymbolLightClassesEqualityByPsiForLibraryTestGenerated.java b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/SymbolLightClassesEqualityByPsiForLibraryTestGenerated.java
index 782d0ae..ac8f9e7 100644
--- a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/SymbolLightClassesEqualityByPsiForLibraryTestGenerated.java
+++ b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/SymbolLightClassesEqualityByPsiForLibraryTestGenerated.java
@@ -25,6 +25,12 @@
}
@Test
+ @TestMetadata("allowedTargets.kt")
+ public void testAllowedTargets() throws Exception {
+ runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/allowedTargets.kt");
+ }
+
+ @Test
@TestMetadata("annotationWithSetParamPropertyModifier.kt")
public void testAnnotationWithSetParamPropertyModifier() throws Exception {
runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/annotationWithSetParamPropertyModifier.kt");
diff --git a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/SymbolLightClassesParentingByPsiForLibraryTestGenerated.java b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/SymbolLightClassesParentingByPsiForLibraryTestGenerated.java
index 2c9d62a..06f521d 100644
--- a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/SymbolLightClassesParentingByPsiForLibraryTestGenerated.java
+++ b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/SymbolLightClassesParentingByPsiForLibraryTestGenerated.java
@@ -25,6 +25,12 @@
}
@Test
+ @TestMetadata("allowedTargets.kt")
+ public void testAllowedTargets() throws Exception {
+ runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/allowedTargets.kt");
+ }
+
+ @Test
@TestMetadata("annotationWithSetParamPropertyModifier.kt")
public void testAnnotationWithSetParamPropertyModifier() throws Exception {
runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/annotationWithSetParamPropertyModifier.kt");
diff --git a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/SymbolLightClassesByPsiForSourceTestGenerated.java b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/SymbolLightClassesByPsiForSourceTestGenerated.java
index b44d182..6958ec7 100644
--- a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/SymbolLightClassesByPsiForSourceTestGenerated.java
+++ b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/SymbolLightClassesByPsiForSourceTestGenerated.java
@@ -25,6 +25,12 @@
}
@Test
+ @TestMetadata("allowedTargets.kt")
+ public void testAllowedTargets() throws Exception {
+ runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/allowedTargets.kt");
+ }
+
+ @Test
@TestMetadata("annotationWithSetParamPropertyModifier.kt")
public void testAnnotationWithSetParamPropertyModifier() throws Exception {
runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/annotationWithSetParamPropertyModifier.kt");
diff --git a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/SymbolLightClassesEqualityByPsiForSourceTestGenerated.java b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/SymbolLightClassesEqualityByPsiForSourceTestGenerated.java
index 9267866..2ec35a2 100644
--- a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/SymbolLightClassesEqualityByPsiForSourceTestGenerated.java
+++ b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/SymbolLightClassesEqualityByPsiForSourceTestGenerated.java
@@ -25,6 +25,12 @@
}
@Test
+ @TestMetadata("allowedTargets.kt")
+ public void testAllowedTargets() throws Exception {
+ runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/allowedTargets.kt");
+ }
+
+ @Test
@TestMetadata("annotationWithSetParamPropertyModifier.kt")
public void testAnnotationWithSetParamPropertyModifier() throws Exception {
runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/annotationWithSetParamPropertyModifier.kt");
diff --git a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/SymbolLightClassesParentingByPsiForSourceTestGenerated.java b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/SymbolLightClassesParentingByPsiForSourceTestGenerated.java
index f2eaa66..0a1f559 100644
--- a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/SymbolLightClassesParentingByPsiForSourceTestGenerated.java
+++ b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/SymbolLightClassesParentingByPsiForSourceTestGenerated.java
@@ -25,6 +25,12 @@
}
@Test
+ @TestMetadata("allowedTargets.kt")
+ public void testAllowedTargets() throws Exception {
+ runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/allowedTargets.kt");
+ }
+
+ @Test
@TestMetadata("annotationWithSetParamPropertyModifier.kt")
public void testAnnotationWithSetParamPropertyModifier() throws Exception {
runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/annotationWithSetParamPropertyModifier.kt");
diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirRepeatableAnnotationChecker.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirRepeatableAnnotationChecker.kt
index 5679ba8..ebb9322 100644
--- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirRepeatableAnnotationChecker.kt
+++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirRepeatableAnnotationChecker.kt
@@ -52,11 +52,11 @@
if (annotationClassId.isLocal) continue
val annotationClass = session.symbolProvider.getClassLikeSymbolByClassId(annotationClassId) ?: continue
- val useSiteTarget = annotation.useSiteTarget
+ val effectiveUseSiteTarget = annotation.calculatedUseSiteTarget ?: annotation.useSiteTarget
val expandedType = annotation.annotationTypeRef.coneType.fullyExpandedType(context.session)
val existingTargetsForAnnotation = annotationsMap.getOrPut(expandedType) { arrayListOf() }
- val duplicateAnnotation = useSiteTarget in existingTargetsForAnnotation ||
- existingTargetsForAnnotation.any { (it == null) != (useSiteTarget == null) }
+ val duplicateAnnotation = effectiveUseSiteTarget in existingTargetsForAnnotation ||
+ existingTargetsForAnnotation.any { (it == null) != (effectiveUseSiteTarget == null) }
if (duplicateAnnotation &&
annotationClass.containsRepeatableAnnotation(session) &&
@@ -83,7 +83,7 @@
}
}
- existingTargetsForAnnotation.add(useSiteTarget)
+ existingTargetsForAnnotation.add(effectiveUseSiteTarget)
}
if (declaration is FirRegularClass) {
diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirAnnotationHelpers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirAnnotationHelpers.kt
index 029c448..9c4f601 100644
--- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirAnnotationHelpers.kt
+++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirAnnotationHelpers.kt
@@ -189,7 +189,7 @@
val annotationsMap = hashMapOf<ConeKotlinType, MutableList<AnnotationUseSiteTarget?>>()
for (annotation in annotations) {
- val useSiteTarget = annotation.useSiteTarget ?: annotationContainer?.getDefaultUseSiteTarget(annotation, context)
+ val useSiteTarget = annotation.calculatedUseSiteTarget ?: annotation.useSiteTarget ?: annotationContainer?.getDefaultUseSiteTarget(annotation, context)
val expandedType = annotation.annotationTypeRef.coneType.fullyExpandedType(context.session)
val existingTargetsForAnnotation = annotationsMap.getOrPut(expandedType) { arrayListOf() }
diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AnnotationGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AnnotationGenerator.kt
index 59726bb..8b1d16a 100644
--- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AnnotationGenerator.kt
+++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AnnotationGenerator.kt
@@ -40,7 +40,7 @@
}
private fun FirAnnotation.target(applicable: List<AnnotationUseSiteTarget>): AnnotationUseSiteTarget? =
- useSiteTarget ?: applicable.firstOrNull(useSiteTargetsFromMetaAnnotation(session)::contains)
+ calculatedUseSiteTarget ?: useSiteTarget ?: applicable.firstOrNull(useSiteTargetsFromMetaAnnotation(session)::contains)
companion object {
private val propertyTargets = listOf(AnnotationUseSiteTarget.PROPERTY, AnnotationUseSiteTarget.FIELD)
diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt
index 96e6d55..662f739 100644
--- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt
+++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt
@@ -677,6 +677,7 @@
if (this is FirAnnotationCall) return this
return buildAnnotationCall {
useSiteTarget = this@toAnnotationCall.useSiteTarget
+ calculatedUseSiteTarget = this@toAnnotationCall.calculatedUseSiteTarget
annotationTypeRef = this@toAnnotationCall.annotationTypeRef
val symbol = annotationTypeRef.coneType.fullyExpandedType(session).toSymbol(session) as? FirRegularClassSymbol ?: return null
val constructorSymbol = symbol.declarationSymbols.firstIsInstanceOrNull<FirConstructorSymbol>() ?: return null
diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java
index 0438cd9..0b9f454 100644
--- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java
+++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java
@@ -36,6 +36,12 @@
}
@Test
+ @TestMetadata("allowedTargets.kt")
+ public void testAllowedTargets() throws Exception {
+ runTest("compiler/testData/codegen/box/annotations/allowedTargets.kt");
+ }
+
+ @Test
@TestMetadata("annotatedAnnotationParameter.kt")
public void testAnnotatedAnnotationParameter() throws Exception {
runTest("compiler/testData/codegen/box/annotations/annotatedAnnotationParameter.kt");
diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java
index 37e68ac..593d24a 100644
--- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java
+++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java
@@ -36,6 +36,12 @@
}
@Test
+ @TestMetadata("allowedTargets.kt")
+ public void testAllowedTargets() throws Exception {
+ runTest("compiler/testData/codegen/box/annotations/allowedTargets.kt");
+ }
+
+ @Test
@TestMetadata("annotatedAnnotationParameter.kt")
public void testAnnotatedAnnotationParameter() throws Exception {
runTest("compiler/testData/codegen/box/annotations/annotatedAnnotationParameter.kt");
diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/fir/ValueParameter.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/fir/ValueParameter.kt
index 5930611..ecf9b4d 100644
--- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/fir/ValueParameter.kt
+++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/fir/ValueParameter.kt
@@ -143,9 +143,10 @@
status = status.copy(),
)
annotations += modifiers.annotations.filter {
- it.useSiteTarget == null || it.useSiteTarget == AnnotationUseSiteTarget.PROPERTY ||
- it.useSiteTarget == AnnotationUseSiteTarget.FIELD ||
- it.useSiteTarget == AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD
+ val useSiteTarget = it.calculatedUseSiteTarget ?: it.useSiteTarget
+ useSiteTarget == null || useSiteTarget == AnnotationUseSiteTarget.PROPERTY ||
+ useSiteTarget == AnnotationUseSiteTarget.FIELD ||
+ useSiteTarget == AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD
}
val defaultAccessorSource = propertySource?.fakeElement(KtFakeSourceElementKind.DefaultAccessor)
getter = FirDefaultPropertyGetter(
diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt
index 95eb14b..519b3fa 100644
--- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt
+++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt
@@ -600,10 +600,11 @@
val isFromPrimaryConstructor = valueParameterDeclaration == ValueParameterDeclaration.PRIMARY_CONSTRUCTOR
for (annotationEntry in annotationEntries) {
annotationEntry.convert<FirAnnotation>().takeIf {
- !isFromPrimaryConstructor || it.useSiteTarget == null ||
- it.useSiteTarget == CONSTRUCTOR_PARAMETER ||
- it.useSiteTarget == RECEIVER ||
- it.useSiteTarget == FILE
+ val useSiteTarget = it.calculatedUseSiteTarget ?: it.useSiteTarget
+ !isFromPrimaryConstructor || useSiteTarget == null ||
+ useSiteTarget == CONSTRUCTOR_PARAMETER ||
+ useSiteTarget == RECEIVER ||
+ useSiteTarget == FILE
}?.let {
this.annotations += it
}
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt
index 28f8653..173ac9f 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt
@@ -122,7 +122,7 @@
if (result.isPrimary) {
for (valueParameter in result.valueParameters) {
if (valueParameter.correspondingProperty != null) {
- valueParameter.removeDuplicateAnnotationsOfPrimaryConstructorElement()
+ valueParameter.removeIrrelevantAnnotations()
}
}
}
@@ -183,7 +183,7 @@
unboundCyclesInTypeParametersSupertypes(property)
if (property.source?.kind == KtFakeSourceElementKind.PropertyFromParameter) {
- property.removeDuplicateAnnotationsOfPrimaryConstructorElement()
+ property.removeIrrelevantAnnotations()
}
property
@@ -398,28 +398,40 @@
}
/**
- * In a scenario like
- *
+ * Filters annotations by target.
+ * For example, in the following snippet the annotation may apply to the constructor value parameter, the property or the underlying field:
* ```
- * annotation class Ann
* class Foo(@Ann val x: String)
* ```
- *
- * both, the primary ctor value parameter and the property `x` will be annotated with `@Ann`. This is due to the fact, that the
- * annotation needs to be resolved in order to determine its annotation targets. We remove annotations from the wrong target if they
- * don't explicitly specify the use-site target (in which case they shouldn't have been added to the element in the raw FIR).
- *
- * For value parameters, we remove the annotation if the targets don't include [AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER].
- * For properties, we remove the annotation, if the targets include [AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER].
+ * This ambiguity may be resolved by specifying the use-site explicitly, i.e. `@field:Ann` or by analysing the allowed targets from
+ * the [kotlin.annotation.Target] meta-annotation. In latter case, the method will assign a use-site target to the corresponding
+ * annotation.
*/
- private fun FirVariable.removeDuplicateAnnotationsOfPrimaryConstructorElement() {
+ private fun FirVariable.removeIrrelevantAnnotations() {
val isParameter = this is FirValueParameter
- replaceAnnotations(annotations.filter {
- it.useSiteTarget != null ||
- // equivalent to
- // CONSTRUCTOR_PARAMETER in targets && isParameter ||
- // CONSTRUCTOR_PARAMETER !in targets && !isParameter
- AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER in it.useSiteTargetsFromMetaAnnotation(session) == isParameter
+
+ replaceAnnotations(annotations.filter { annotation ->
+ when (annotation.useSiteTarget) {
+ AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER -> isParameter
+ AnnotationUseSiteTarget.PROPERTY, AnnotationUseSiteTarget.FIELD -> !isParameter
+ else -> {
+ val allowedTargets = annotation.useSiteTargetsFromMetaAnnotation(session)
+
+ val calculatedUseSiteTarget = when {
+ isParameter ->
+ if (AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER in allowedTargets) AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER
+ else null
+ this.source?.kind == KtFakeSourceElementKind.PropertyFromParameter && AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER in allowedTargets -> null
+ AnnotationUseSiteTarget.FIELD in allowedTargets && AnnotationUseSiteTarget.PROPERTY !in allowedTargets -> AnnotationUseSiteTarget.FIELD
+ else -> AnnotationUseSiteTarget.PROPERTY
+ }
+
+ if (calculatedUseSiteTarget != null) {
+ annotation.replaceCalculatedUseSiteTarget(calculatedUseSiteTarget)
+ true
+ } else false
+ }
+ }
})
}
}
diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirAnnotation.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirAnnotation.kt
index bcc395e..75e21a3 100644
--- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirAnnotation.kt
+++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirAnnotation.kt
@@ -22,6 +22,7 @@
abstract override val typeRef: FirTypeRef
abstract override val annotations: List<FirAnnotation>
abstract val useSiteTarget: AnnotationUseSiteTarget?
+ abstract val calculatedUseSiteTarget: AnnotationUseSiteTarget?
abstract val annotationTypeRef: FirTypeRef
abstract val argumentMapping: FirAnnotationArgumentMapping
abstract val typeArguments: List<FirTypeProjection>
@@ -36,6 +37,8 @@
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
+ abstract fun replaceCalculatedUseSiteTarget(newCalculatedUseSiteTarget: AnnotationUseSiteTarget?)
+
abstract fun replaceAnnotationTypeRef(newAnnotationTypeRef: FirTypeRef)
abstract fun replaceArgumentMapping(newArgumentMapping: FirAnnotationArgumentMapping)
diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirAnnotationCall.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirAnnotationCall.kt
index e6e6b10..68b1e22 100644
--- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirAnnotationCall.kt
+++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirAnnotationCall.kt
@@ -23,6 +23,7 @@
abstract override val typeRef: FirTypeRef
abstract override val annotations: List<FirAnnotation>
abstract override val useSiteTarget: AnnotationUseSiteTarget?
+ abstract override val calculatedUseSiteTarget: AnnotationUseSiteTarget?
abstract override val annotationTypeRef: FirTypeRef
abstract override val typeArguments: List<FirTypeProjection>
abstract override val argumentList: FirArgumentList
@@ -40,6 +41,8 @@
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
+ abstract override fun replaceCalculatedUseSiteTarget(newCalculatedUseSiteTarget: AnnotationUseSiteTarget?)
+
abstract override fun replaceAnnotationTypeRef(newAnnotationTypeRef: FirTypeRef)
abstract override fun replaceTypeArguments(newTypeArguments: List<FirTypeProjection>)
diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirErrorAnnotationCall.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirErrorAnnotationCall.kt
index 97910ac..358bd6f 100644
--- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirErrorAnnotationCall.kt
+++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirErrorAnnotationCall.kt
@@ -25,6 +25,7 @@
abstract override val typeRef: FirTypeRef
abstract override val annotations: List<FirAnnotation>
abstract override val useSiteTarget: AnnotationUseSiteTarget?
+ abstract override val calculatedUseSiteTarget: AnnotationUseSiteTarget?
abstract override val annotationTypeRef: FirTypeRef
abstract override val typeArguments: List<FirTypeProjection>
abstract override val argumentList: FirArgumentList
@@ -43,6 +44,8 @@
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
+ abstract override fun replaceCalculatedUseSiteTarget(newCalculatedUseSiteTarget: AnnotationUseSiteTarget?)
+
abstract override fun replaceAnnotationTypeRef(newAnnotationTypeRef: FirTypeRef)
abstract override fun replaceTypeArguments(newTypeArguments: List<FirTypeProjection>)
diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirAnnotationBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirAnnotationBuilder.kt
index b89f146..8eb236ce 100644
--- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirAnnotationBuilder.kt
+++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirAnnotationBuilder.kt
@@ -30,6 +30,7 @@
class FirAnnotationBuilder : FirAnnotationContainerBuilder, FirExpressionBuilder {
override var source: KtSourceElement? = null
var useSiteTarget: AnnotationUseSiteTarget? = null
+ var calculatedUseSiteTarget: AnnotationUseSiteTarget? = null
lateinit var annotationTypeRef: FirTypeRef
lateinit var argumentMapping: FirAnnotationArgumentMapping
val typeArguments: MutableList<FirTypeProjection> = mutableListOf()
@@ -38,6 +39,7 @@
return FirAnnotationImpl(
source,
useSiteTarget,
+ calculatedUseSiteTarget,
annotationTypeRef,
argumentMapping,
typeArguments.toMutableOrEmpty(),
diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirAnnotationCallBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirAnnotationCallBuilder.kt
index 7b46202..23fc4b7 100644
--- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirAnnotationCallBuilder.kt
+++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirAnnotationCallBuilder.kt
@@ -38,6 +38,7 @@
class FirAnnotationCallBuilder : FirCallBuilder, FirAnnotationContainerBuilder, FirExpressionBuilder {
override var source: KtSourceElement? = null
var useSiteTarget: AnnotationUseSiteTarget? = null
+ var calculatedUseSiteTarget: AnnotationUseSiteTarget? = null
var annotationTypeRef: FirTypeRef = FirImplicitTypeRefImplWithoutSource
val typeArguments: MutableList<FirTypeProjection> = mutableListOf()
override var argumentList: FirArgumentList = FirEmptyArgumentList
@@ -49,6 +50,7 @@
return FirAnnotationCallImpl(
source,
useSiteTarget,
+ calculatedUseSiteTarget,
annotationTypeRef,
typeArguments.toMutableOrEmpty(),
argumentList,
@@ -86,6 +88,7 @@
val copyBuilder = FirAnnotationCallBuilder()
copyBuilder.source = original.source
copyBuilder.useSiteTarget = original.useSiteTarget
+ copyBuilder.calculatedUseSiteTarget = original.calculatedUseSiteTarget
copyBuilder.annotationTypeRef = original.annotationTypeRef
copyBuilder.typeArguments.addAll(original.typeArguments)
copyBuilder.argumentList = original.argumentList
diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirErrorAnnotationCallBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirErrorAnnotationCallBuilder.kt
index 836eda8..d3daf9b 100644
--- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirErrorAnnotationCallBuilder.kt
+++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirErrorAnnotationCallBuilder.kt
@@ -39,6 +39,7 @@
class FirErrorAnnotationCallBuilder : FirCallBuilder, FirAnnotationContainerBuilder, FirExpressionBuilder {
override var source: KtSourceElement? = null
var useSiteTarget: AnnotationUseSiteTarget? = null
+ var calculatedUseSiteTarget: AnnotationUseSiteTarget? = null
var annotationTypeRef: FirTypeRef = FirImplicitTypeRefImplWithoutSource
val typeArguments: MutableList<FirTypeProjection> = mutableListOf()
override var argumentList: FirArgumentList = FirEmptyArgumentList
@@ -50,6 +51,7 @@
return FirErrorAnnotationCallImpl(
source,
useSiteTarget,
+ calculatedUseSiteTarget,
annotationTypeRef,
typeArguments.toMutableOrEmpty(),
argumentList,
diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirAnnotationCallImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirAnnotationCallImpl.kt
index 91b0b9c..afc6dfc 100644
--- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirAnnotationCallImpl.kt
+++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirAnnotationCallImpl.kt
@@ -29,6 +29,7 @@
internal class FirAnnotationCallImpl(
override val source: KtSourceElement?,
override val useSiteTarget: AnnotationUseSiteTarget?,
+ override var calculatedUseSiteTarget: AnnotationUseSiteTarget?,
override var annotationTypeRef: FirTypeRef,
override var typeArguments: MutableOrEmptyList<FirTypeProjection>,
override var argumentList: FirArgumentList,
@@ -77,6 +78,10 @@
override fun replaceAnnotations(newAnnotations: List<FirAnnotation>) {}
+ override fun replaceCalculatedUseSiteTarget(newCalculatedUseSiteTarget: AnnotationUseSiteTarget?) {
+ calculatedUseSiteTarget = newCalculatedUseSiteTarget
+ }
+
override fun replaceAnnotationTypeRef(newAnnotationTypeRef: FirTypeRef) {
annotationTypeRef = newAnnotationTypeRef
}
diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirAnnotationImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirAnnotationImpl.kt
index 826d104..45a5eb8 100644
--- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirAnnotationImpl.kt
+++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirAnnotationImpl.kt
@@ -25,6 +25,7 @@
internal class FirAnnotationImpl(
override val source: KtSourceElement?,
override val useSiteTarget: AnnotationUseSiteTarget?,
+ override var calculatedUseSiteTarget: AnnotationUseSiteTarget?,
override var annotationTypeRef: FirTypeRef,
override var argumentMapping: FirAnnotationArgumentMapping,
override var typeArguments: MutableOrEmptyList<FirTypeProjection>,
@@ -63,6 +64,10 @@
override fun replaceAnnotations(newAnnotations: List<FirAnnotation>) {}
+ override fun replaceCalculatedUseSiteTarget(newCalculatedUseSiteTarget: AnnotationUseSiteTarget?) {
+ calculatedUseSiteTarget = newCalculatedUseSiteTarget
+ }
+
override fun replaceAnnotationTypeRef(newAnnotationTypeRef: FirTypeRef) {
annotationTypeRef = newAnnotationTypeRef
}
diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirErrorAnnotationCallImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirErrorAnnotationCallImpl.kt
index 9e453c6..33c82db 100644
--- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirErrorAnnotationCallImpl.kt
+++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirErrorAnnotationCallImpl.kt
@@ -30,6 +30,7 @@
internal class FirErrorAnnotationCallImpl(
override val source: KtSourceElement?,
override val useSiteTarget: AnnotationUseSiteTarget?,
+ override var calculatedUseSiteTarget: AnnotationUseSiteTarget?,
override var annotationTypeRef: FirTypeRef,
override var typeArguments: MutableOrEmptyList<FirTypeProjection>,
override var argumentList: FirArgumentList,
@@ -79,6 +80,10 @@
override fun replaceAnnotations(newAnnotations: List<FirAnnotation>) {}
+ override fun replaceCalculatedUseSiteTarget(newCalculatedUseSiteTarget: AnnotationUseSiteTarget?) {
+ calculatedUseSiteTarget = newCalculatedUseSiteTarget
+ }
+
override fun replaceAnnotationTypeRef(newAnnotationTypeRef: FirTypeRef) {
annotationTypeRef = newAnnotationTypeRef
}
diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt
index ff7f470..a455709 100644
--- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt
+++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt
@@ -515,6 +515,7 @@
annotation.configure {
+field("useSiteTarget", annotationUseSiteTargetType, nullable = true)
+ +field("calculatedUseSiteTarget", annotationUseSiteTargetType, nullable = true, withReplace = true)
+field("annotationTypeRef", typeRef, withReplace = true).withTransform()
+field("argumentMapping", annotationArgumentMapping, withReplace = true)
+typeArguments.withTransform()
diff --git a/compiler/testData/asJava/lightClasses/lightClassByPsi/allowedTargets.fir.java b/compiler/testData/asJava/lightClasses/lightClassByPsi/allowedTargets.fir.java
new file mode 100644
index 0000000..2f69a8a
--- /dev/null
+++ b/compiler/testData/asJava/lightClasses/lightClassByPsi/allowedTargets.fir.java
@@ -0,0 +1,80 @@
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+public abstract @interface AnotherUniversalAnnotation /* AnotherUniversalAnnotation*/ {
+}
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.FIELD})
+@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.FIELD})
+public abstract @interface FieldAnnotation /* FieldAnnotation*/ {
+}
+
+public final class MyClass /* MyClass*/ {
+ @AnotherUniversalAnnotation()
+ private final int x5;
+
+ @FieldAnnotation()
+ private final int x1;
+
+ @UniversalAnnotation()
+ private final int x6;
+
+ private final int x2;
+
+ private final int x3;
+
+ private final int x4;
+
+ private final int x7;
+
+ public MyClass(@AnotherUniversalAnnotation() @ParameterAnnotation() @UniversalAnnotation() int, int, @PropertyOrParameterAnnotation() int, @ParameterOrFieldAnnotation() int, int, @AnotherUniversalAnnotation() int, @UniversalAnnotation() int);// .ctor(int, int, int, int, int, int, int)
+
+ public final int getX1();// getX1()
+
+ public final int getX2();// getX2()
+
+ public final int getX3();// getX3()
+
+ public final int getX4();// getX4()
+
+ public final int getX5();// getX5()
+
+ public final int getX6();// getX6()
+
+ public final int getX7();// getX7()
+}
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.PARAMETER})
+@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.VALUE_PARAMETER})
+public abstract @interface ParameterAnnotation /* ParameterAnnotation*/ {
+}
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.PARAMETER})
+@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.FIELD, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER})
+public abstract @interface ParameterOrFieldAnnotation /* ParameterOrFieldAnnotation*/ {
+}
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@java.lang.annotation.Target(value = {})
+@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.PROPERTY})
+public abstract @interface PropertyAnnotation /* PropertyAnnotation*/ {
+}
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.FIELD})
+@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.FIELD})
+public abstract @interface PropertyOrFieldAnnotation /* PropertyOrFieldAnnotation*/ {
+}
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.PARAMETER})
+@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER})
+public abstract @interface PropertyOrParameterAnnotation /* PropertyOrParameterAnnotation*/ {
+}
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.PARAMETER})
+@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.FIELD, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER})
+public abstract @interface UniversalAnnotation /* UniversalAnnotation*/ {
+}
diff --git a/compiler/testData/asJava/lightClasses/lightClassByPsi/allowedTargets.java b/compiler/testData/asJava/lightClasses/lightClassByPsi/allowedTargets.java
new file mode 100644
index 0000000..95244ad
--- /dev/null
+++ b/compiler/testData/asJava/lightClasses/lightClassByPsi/allowedTargets.java
@@ -0,0 +1,80 @@
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+public abstract @interface AnotherUniversalAnnotation /* AnotherUniversalAnnotation*/ {
+}
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.FIELD})
+@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.FIELD})
+public abstract @interface FieldAnnotation /* FieldAnnotation*/ {
+}
+
+public final class MyClass /* MyClass*/ {
+ @AnotherUniversalAnnotation()
+ private final int x5;
+
+ @FieldAnnotation()
+ private final int x1;
+
+ @UniversalAnnotation()
+ private final int x6;
+
+ private final int x2;
+
+ private final int x3;
+
+ private final int x4;
+
+ private final int x7;
+
+ public MyClass(@AnotherUniversalAnnotation() @FieldAnnotation() @ParameterAnnotation() @PropertyAnnotation() @UniversalAnnotation() int, @PropertyOrFieldAnnotation() int, @PropertyOrParameterAnnotation() int, @ParameterOrFieldAnnotation() int, int, @AnotherUniversalAnnotation() int, @UniversalAnnotation() int);// .ctor(int, int, int, int, int, int, int)
+
+ public final int getX1();// getX1()
+
+ public final int getX2();// getX2()
+
+ public final int getX3();// getX3()
+
+ public final int getX4();// getX4()
+
+ public final int getX5();// getX5()
+
+ public final int getX6();// getX6()
+
+ public final int getX7();// getX7()
+}
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.PARAMETER})
+@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.VALUE_PARAMETER})
+public abstract @interface ParameterAnnotation /* ParameterAnnotation*/ {
+}
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.PARAMETER})
+@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.FIELD, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER})
+public abstract @interface ParameterOrFieldAnnotation /* ParameterOrFieldAnnotation*/ {
+}
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@java.lang.annotation.Target(value = {})
+@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.PROPERTY})
+public abstract @interface PropertyAnnotation /* PropertyAnnotation*/ {
+}
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.FIELD})
+@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.FIELD})
+public abstract @interface PropertyOrFieldAnnotation /* PropertyOrFieldAnnotation*/ {
+}
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.PARAMETER})
+@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER})
+public abstract @interface PropertyOrParameterAnnotation /* PropertyOrParameterAnnotation*/ {
+}
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.PARAMETER})
+@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.FIELD, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER})
+public abstract @interface UniversalAnnotation /* UniversalAnnotation*/ {
+}
diff --git a/compiler/testData/asJava/lightClasses/lightClassByPsi/allowedTargets.kt b/compiler/testData/asJava/lightClasses/lightClassByPsi/allowedTargets.kt
new file mode 100644
index 0000000..9c1081a
--- /dev/null
+++ b/compiler/testData/asJava/lightClasses/lightClassByPsi/allowedTargets.kt
@@ -0,0 +1,33 @@
+@Target(AnnotationTarget.PROPERTY)
+annotation class PropertyAnnotation
+
+@Target(AnnotationTarget.FIELD)
+annotation class FieldAnnotation
+
+@Target(AnnotationTarget.VALUE_PARAMETER)
+annotation class ParameterAnnotation
+
+@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FIELD)
+annotation class PropertyOrFieldAnnotation
+
+@Target(AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER)
+annotation class PropertyOrParameterAnnotation
+
+@Target(AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER)
+annotation class ParameterOrFieldAnnotation
+
+@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER)
+annotation class UniversalAnnotation
+
+annotation class AnotherUniversalAnnotation
+
+
+class MyClass(
+ @PropertyAnnotation @FieldAnnotation @ParameterAnnotation @UniversalAnnotation @AnotherUniversalAnnotation val x1: Int,
+ @PropertyOrFieldAnnotation val x2: Int,
+ @PropertyOrParameterAnnotation val x3: Int,
+ @ParameterOrFieldAnnotation val x4: Int,
+ @property:UniversalAnnotation @field:AnotherUniversalAnnotation val x5: Int,
+ @field:UniversalAnnotation @param:AnotherUniversalAnnotation val x6: Int,
+ @param:UniversalAnnotation @property:AnotherUniversalAnnotation val x7: Int
+)
diff --git a/compiler/testData/asJava/lightClasses/lightClassByPsi/allowedTargets.lib.java b/compiler/testData/asJava/lightClasses/lightClassByPsi/allowedTargets.lib.java
new file mode 100644
index 0000000..2f69a8a
--- /dev/null
+++ b/compiler/testData/asJava/lightClasses/lightClassByPsi/allowedTargets.lib.java
@@ -0,0 +1,80 @@
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+public abstract @interface AnotherUniversalAnnotation /* AnotherUniversalAnnotation*/ {
+}
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.FIELD})
+@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.FIELD})
+public abstract @interface FieldAnnotation /* FieldAnnotation*/ {
+}
+
+public final class MyClass /* MyClass*/ {
+ @AnotherUniversalAnnotation()
+ private final int x5;
+
+ @FieldAnnotation()
+ private final int x1;
+
+ @UniversalAnnotation()
+ private final int x6;
+
+ private final int x2;
+
+ private final int x3;
+
+ private final int x4;
+
+ private final int x7;
+
+ public MyClass(@AnotherUniversalAnnotation() @ParameterAnnotation() @UniversalAnnotation() int, int, @PropertyOrParameterAnnotation() int, @ParameterOrFieldAnnotation() int, int, @AnotherUniversalAnnotation() int, @UniversalAnnotation() int);// .ctor(int, int, int, int, int, int, int)
+
+ public final int getX1();// getX1()
+
+ public final int getX2();// getX2()
+
+ public final int getX3();// getX3()
+
+ public final int getX4();// getX4()
+
+ public final int getX5();// getX5()
+
+ public final int getX6();// getX6()
+
+ public final int getX7();// getX7()
+}
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.PARAMETER})
+@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.VALUE_PARAMETER})
+public abstract @interface ParameterAnnotation /* ParameterAnnotation*/ {
+}
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.PARAMETER})
+@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.FIELD, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER})
+public abstract @interface ParameterOrFieldAnnotation /* ParameterOrFieldAnnotation*/ {
+}
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@java.lang.annotation.Target(value = {})
+@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.PROPERTY})
+public abstract @interface PropertyAnnotation /* PropertyAnnotation*/ {
+}
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.FIELD})
+@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.FIELD})
+public abstract @interface PropertyOrFieldAnnotation /* PropertyOrFieldAnnotation*/ {
+}
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.PARAMETER})
+@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER})
+public abstract @interface PropertyOrParameterAnnotation /* PropertyOrParameterAnnotation*/ {
+}
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.PARAMETER})
+@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.FIELD, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER})
+public abstract @interface UniversalAnnotation /* UniversalAnnotation*/ {
+}
diff --git a/compiler/testData/codegen/box/annotations/allowedTargets.kt b/compiler/testData/codegen/box/annotations/allowedTargets.kt
new file mode 100644
index 0000000..1d0f81e
--- /dev/null
+++ b/compiler/testData/codegen/box/annotations/allowedTargets.kt
@@ -0,0 +1,73 @@
+// WITH_STDLIB
+// WITH_REFLECT
+// TARGET_BACKEND: JVM_IR
+
+import kotlin.test.assertEquals
+import kotlin.reflect.*
+import kotlin.reflect.jvm.javaField
+
+@Target(AnnotationTarget.PROPERTY)
+annotation class PropertyAnnotation
+
+@Target(AnnotationTarget.FIELD)
+annotation class FieldAnnotation
+
+@Target(AnnotationTarget.VALUE_PARAMETER)
+annotation class ParameterAnnotation
+
+@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FIELD)
+annotation class PropertyOrFieldAnnotation
+
+@Target(AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER)
+annotation class PropertyOrParameterAnnotation
+
+@Target(AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER)
+annotation class ParameterOrFieldAnnotation
+
+@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER)
+annotation class UniversalAnnotation
+
+annotation class AnotherUniversalAnnotation
+
+
+class C(
+ @PropertyAnnotation @FieldAnnotation @ParameterAnnotation @UniversalAnnotation @AnotherUniversalAnnotation val x1: Int,
+ @PropertyOrFieldAnnotation val x2: Int,
+ @PropertyOrParameterAnnotation val x3: Int,
+ @ParameterOrFieldAnnotation val x4: Int,
+ @property:UniversalAnnotation @field:AnotherUniversalAnnotation val x5: Int,
+ @field:UniversalAnnotation @param:AnotherUniversalAnnotation val x6: Int,
+ @param:UniversalAnnotation @property:AnotherUniversalAnnotation val x7: Int
+)
+
+fun box(): String {
+ val parameterAnnotations = C::class.constructors.single().parameters.map { it.name to it.annotations.map { it.annotationClass.simpleName ?: "" }.toSet() }.toMap()
+ assertEquals(setOf("ParameterAnnotation", "UniversalAnnotation", "AnotherUniversalAnnotation"), parameterAnnotations["x1"])
+ assertEquals(setOf(), parameterAnnotations["x2"])
+ assertEquals(setOf("PropertyOrParameterAnnotation"), parameterAnnotations["x3"])
+ assertEquals(setOf("ParameterOrFieldAnnotation"), parameterAnnotations["x4"])
+ assertEquals(setOf(), parameterAnnotations["x5"])
+ assertEquals(setOf("AnotherUniversalAnnotation"), parameterAnnotations["x6"])
+ assertEquals(setOf("UniversalAnnotation"), parameterAnnotations["x7"])
+
+ val properties = C::class.members.filterIsInstance<KProperty<*>>()
+ val propertyAnnotations = properties.map { it.name to it.annotations.map { it.annotationClass.simpleName ?: "" }.toSet() }.toMap()
+ assertEquals(setOf("PropertyAnnotation"), propertyAnnotations["x1"])
+ assertEquals(setOf("PropertyOrFieldAnnotation"), propertyAnnotations["x2"])
+ assertEquals(setOf(), propertyAnnotations["x3"])
+ assertEquals(setOf(), propertyAnnotations["x4"])
+ assertEquals(setOf("UniversalAnnotation"), propertyAnnotations["x5"])
+ assertEquals(setOf(), propertyAnnotations["x6"])
+ assertEquals(setOf("AnotherUniversalAnnotation"), propertyAnnotations["x7"])
+
+ val fieldAnnotations = properties.map { it.javaField!! }.map { it.name to it.declaredAnnotations.map { it.annotationClass.simpleName ?: "" }.toSet() }.toMap()
+ assertEquals(setOf("FieldAnnotation"), fieldAnnotations["x1"])
+ assertEquals(setOf(), fieldAnnotations["x2"])
+ assertEquals(setOf(), fieldAnnotations["x3"])
+ assertEquals(setOf(), fieldAnnotations["x4"])
+ assertEquals(setOf("AnotherUniversalAnnotation"), fieldAnnotations["x5"])
+ assertEquals(setOf("UniversalAnnotation"), fieldAnnotations["x6"])
+ assertEquals(setOf(), fieldAnnotations["x7"])
+
+ return "OK"
+}
\ No newline at end of file
diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java
index 6c9db95..98923bf 100644
--- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java
+++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java
@@ -36,6 +36,12 @@
}
@Test
+ @TestMetadata("allowedTargets.kt")
+ public void testAllowedTargets() throws Exception {
+ runTest("compiler/testData/codegen/box/annotations/allowedTargets.kt");
+ }
+
+ @Test
@TestMetadata("annotatedAnnotationParameter.kt")
public void testAnnotatedAnnotationParameter() throws Exception {
runTest("compiler/testData/codegen/box/annotations/annotatedAnnotationParameter.kt");
diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java
index 28fadf8..e9f615b 100644
--- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java
+++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java
@@ -36,6 +36,12 @@
}
@Test
+ @TestMetadata("allowedTargets.kt")
+ public void testAllowedTargets() throws Exception {
+ runTest("compiler/testData/codegen/box/annotations/allowedTargets.kt");
+ }
+
+ @Test
@TestMetadata("annotatedAnnotationParameter.kt")
public void testAnnotatedAnnotationParameter() throws Exception {
runTest("compiler/testData/codegen/box/annotations/annotatedAnnotationParameter.kt");
diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/FirSerializer.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/FirSerializer.kt
index 5b86ac1..f78acda 100644
--- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/FirSerializer.kt
+++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/FirSerializer.kt
@@ -175,7 +175,7 @@
// inspired by KlibMetadataSerializerExtension.serializeProperty
declarationFileId(property)?.let { proto.setExtension(KlibMetadataProtoBuf.propertyFile, it) }
property.nonSourceAnnotations(session).forEach {
- val extension = when (it.useSiteTarget) { // Revise this code after KT-54385
+ val extension = when (it.calculatedUseSiteTarget ?: it.useSiteTarget) { // Revise this code after KT-54385
AnnotationUseSiteTarget.FIELD -> KlibMetadataProtoBuf.propertyBackingFieldAnnotation
AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD -> KlibMetadataProtoBuf.propertyDelegatedFieldAnnotation
else -> KlibMetadataProtoBuf.propertyAnnotation
diff --git a/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/diagnostics/FirParcelizePropertyChecker.kt b/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/diagnostics/FirParcelizePropertyChecker.kt
index ac71315..20562ae 100644
--- a/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/diagnostics/FirParcelizePropertyChecker.kt
+++ b/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/diagnostics/FirParcelizePropertyChecker.kt
@@ -155,7 +155,7 @@
private fun List<FirAnnotation>.hasIgnoredOnParcel(): Boolean {
return this.any {
if (it.annotationTypeRef.coneType.classId !in IGNORED_ON_PARCEL_CLASS_IDS) return@any false
- val target = it.useSiteTarget
+ val target = it.calculatedUseSiteTarget ?: it.useSiteTarget
target == null || target == AnnotationUseSiteTarget.PROPERTY || target == AnnotationUseSiteTarget.PROPERTY_GETTER
}
}