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 c3690c7c8a4..98cc0d83a49 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 @@ -22,6 +22,12 @@ import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name internal fun mapAnnotationParameters(annotation: FirAnnotation, session: FirSession): Map { + // TODO: Alas, argument mapping for annotations on [FirValueParameter] is not properly built, even after BODY_RESOLVE ensured. + // Once fixed, manual building of argument mapping below is redundant. I.e., this util can be as simple as: + // return if (annotation.resolved) + // annotation.argumentMapping.mapping.mapKeys { (name, _) -> name } + // else + // emptyMap() if (annotation.resolved) return annotation.argumentMapping.mapping.mapKeys { (name, _) -> name } if (annotation !is FirAnnotationCall) return emptyMap() val annotationCone = (annotation.annotationTypeRef.coneType as? ConeClassLikeType)?.fullyExpandedType(session) diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/FirBasedSymbol.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/FirBasedSymbol.kt index 781e5ff4c71..b250024fc0b 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/FirBasedSymbol.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/FirBasedSymbol.kt @@ -41,7 +41,10 @@ abstract class FirBasedSymbol { val resolvedAnnotationsWithArguments: List get() { - ensureResolved(FirResolvePhase.ARGUMENTS_OF_ANNOTATIONS) + // NB: annotation argument mapping (w/ vararg) are built/replaced during call completion, hence BODY_RESOLVE. + // TODO(KT-53371): optimize ARGUMENTS_OF_ANNOTATIONS to build annotation argument mapping too. + // TODO(KT-53519): Even with BODY_RESOLVE, argument mapping for annotations on [FirValueParameter] is not properly built. + ensureResolved(FirResolvePhase.BODY_RESOLVE) return fir.annotations } diff --git a/compiler/testData/asJava/ultraLightClasses/annotations.fir.java b/compiler/testData/asJava/ultraLightClasses/annotations.fir.java index 91aad7bde22..889f5aa5130 100644 --- a/compiler/testData/asJava/ultraLightClasses/annotations.fir.java +++ b/compiler/testData/asJava/ultraLightClasses/annotations.fir.java @@ -14,12 +14,12 @@ public abstract @interface Anno4 /* Anno4*/ { } @java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME) -@kotlin.annotation.Target(allowedTargets = ?) +@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER, kotlin.annotation.AnnotationTarget.EXPRESSION}) public abstract @interface Anno5 /* Anno5*/ { } @java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME) -@kotlin.annotation.Target(allowedTargets = ?) +@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER, kotlin.annotation.AnnotationTarget.EXPRESSION}) public abstract @interface Anno6 /* Anno6*/ { } @@ -48,7 +48,7 @@ public abstract @interface Anno /* Anno*/ { } -@Deprecated(message = "This anno is deprecated, use === instead", replaceWith = ?) +@Deprecated(message = "This anno is deprecated, use === instead", replaceWith = @ReplaceWith(expression = "this === other")) @java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME) @kotlin.annotation.MustBeDocumented() @kotlin.annotation.Retention(value = kotlin.annotation.AnnotationRetention.SOURCE) diff --git a/compiler/testData/asJava/ultraLightClasses/delegatesWithAnnotations.fir.java b/compiler/testData/asJava/ultraLightClasses/delegatesWithAnnotations.fir.java index 79ec2d272b4..ed2b70a677d 100644 --- a/compiler/testData/asJava/ultraLightClasses/delegatesWithAnnotations.fir.java +++ b/compiler/testData/asJava/ultraLightClasses/delegatesWithAnnotations.fir.java @@ -21,14 +21,14 @@ public abstract @interface Ann /* Ann*/ { } public abstract interface Base /* Base*/ { - @Ann(x = 1L, y = "134", z = java.lang.String.class, e = ?, depr = kotlin.DeprecationLevel.WARNING, t = {}) - public abstract void foo(@Ann(x = 2L, y = "324", z = Ann.class, e = ?, depr = kotlin.DeprecationLevel.WARNING, t = {}) @org.jetbrains.annotations.NotNull() java.lang.String);// foo(java.lang.String) + @Ann(x = 1L, y = "134", z = java.lang.String.class, e = {int.class, double.class}, depr = kotlin.DeprecationLevel.WARNING, t = {SimpleAnn("243"), SimpleAnn("4324")}) + public abstract void foo(@Ann(x = 2L, y = "324", z = Ann.class, e = {byte.class, Base.class}, depr = kotlin.DeprecationLevel.WARNING, t = {SimpleAnn("687"), SimpleAnn("78")}) @org.jetbrains.annotations.NotNull() java.lang.String);// foo(java.lang.String) } public final class Derived /* Derived*/ implements Base { - @Ann(x = 1L, y = "134", z = java.lang.String.class, e = ?, depr = kotlin.DeprecationLevel.WARNING, t = {}) - public void foo(@Ann(x = 2L, y = "324", z = Ann.class, e = ?, depr = kotlin.DeprecationLevel.WARNING, t = {}) @org.jetbrains.annotations.NotNull() java.lang.String);// foo(java.lang.String) + @Ann(x = 1L, y = "134", z = java.lang.String.class, e = {int.class, double.class}, depr = kotlin.DeprecationLevel.WARNING, t = {SimpleAnn("243"), SimpleAnn("4324")}) + public void foo(@Ann(x = 2L, y = "324", z = Ann.class, e = {byte.class, Base.class}, depr = kotlin.DeprecationLevel.WARNING, t = {SimpleAnn("687"), SimpleAnn("78")}) @org.jetbrains.annotations.NotNull() java.lang.String);// foo(java.lang.String) public Derived(@org.jetbrains.annotations.NotNull() Base);// .ctor(Base)