diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyAnnotations.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyAnnotations.kt index 0b0f9a63d3b..626c9a4fec3 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyAnnotations.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyAnnotations.kt @@ -126,19 +126,18 @@ class LazyAnnotationDescriptor( c.scope } - override val valueArgumentsByParameterDescriptor by c.storageManager.createLazyValue { + override val allValueArguments by c.storageManager.createLazyValue { val resolutionResults = c.annotationResolver.resolveAnnotationCall(annotationEntry, scope, c.trace) AnnotationResolverImpl.checkAnnotationType(annotationEntry, c.trace, resolutionResults) - if (!resolutionResults.isSingleResult) return@createLazyValue emptyMap>() + if (!resolutionResults.isSingleResult) return@createLazyValue emptyMap>() - @Suppress("UNCHECKED_CAST") - resolutionResults.resultingCall.valueArguments - .mapValues { val (valueParameter, resolvedArgument) = it - if (resolvedArgument == null) null - else c.annotationResolver.getAnnotationArgumentValue(c.trace, valueParameter, resolvedArgument) - } - .filterValues { it != null } as Map> + resolutionResults.resultingCall.valueArguments.mapNotNull { (valueParameter, resolvedArgument) -> + if (resolvedArgument == null) null + else c.annotationResolver.getAnnotationArgumentValue(c.trace, valueParameter, resolvedArgument)?.let { value -> + valueParameter.name to value + } + }.toMap() } override fun forceResolveAllContents() { diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/replaceAnnotationClassWithInterface/replaceAnnotationClassWithInterface.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/replaceAnnotationClassWithInterface/replaceAnnotationClassWithInterface.txt index ce3621fb144..3c0fb004d1b 100644 --- a/compiler/testData/compileKotlinAgainstCustomBinaries/replaceAnnotationClassWithInterface/replaceAnnotationClassWithInterface.txt +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/replaceAnnotationClassWithInterface/replaceAnnotationClassWithInterface.txt @@ -5,7 +5,7 @@ public fun bar(): @test.Ann kotlin.String public interface Ann { } -@test.Ann public final class Test { +@test.Ann(s = "class") public final class Test { public constructor Test() - @test.Ann public final fun foo(/*0*/ @test.Ann s: @test.Ann kotlin.String): @test.Ann kotlin.String + @test.Ann(s = "function") public final fun foo(/*0*/ @test.Ann(s = "parameter") s: @test.Ann kotlin.String): @test.Ann kotlin.String } diff --git a/compiler/testData/diagnostics/tests/j+k/annotationWithArgumentsMissingDependencies.txt b/compiler/testData/diagnostics/tests/j+k/annotationWithArgumentsMissingDependencies.txt index 807261e07e3..6f4734ffcae 100644 --- a/compiler/testData/diagnostics/tests/j+k/annotationWithArgumentsMissingDependencies.txt +++ b/compiler/testData/diagnostics/tests/j+k/annotationWithArgumentsMissingDependencies.txt @@ -2,10 +2,10 @@ package public fun main(): kotlin.Unit -@missing.Ann /* annotation class not found */ public open class A { +@missing.Ann(x = "") /* annotation class not found */ public open class A { public constructor A() public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean - @missing.Ann /* annotation class not found */ public open fun foo(): kotlin.String! + @missing.Ann(value = 1) /* annotation class not found */ public open fun foo(): kotlin.String! public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/components/JavaAnnotationMapper.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/components/JavaAnnotationMapper.kt index 1c394bbd8ea..aedc1d30922 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/components/JavaAnnotationMapper.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/components/JavaAnnotationMapper.kt @@ -17,9 +17,7 @@ package org.jetbrains.kotlin.load.java.components import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.SourceElement -import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget @@ -52,20 +50,22 @@ object JavaAnnotationMapper { internal val DEPRECATED_ANNOTATION_MESSAGE = Name.identifier("message") internal val TARGET_ANNOTATION_ALLOWED_TARGETS = Name.identifier("allowedTargets") + internal val RETENTION_ANNOTATION_VALUE = Name.identifier("value") fun mapOrResolveJavaAnnotation(annotation: JavaAnnotation, c: LazyJavaResolverContext): AnnotationDescriptor? = when (annotation.classId) { ClassId.topLevel(JAVA_TARGET_FQ_NAME) -> JavaTargetAnnotationDescriptor(annotation, c) ClassId.topLevel(JAVA_RETENTION_FQ_NAME) -> JavaRetentionAnnotationDescriptor(annotation, c) - ClassId.topLevel(JAVA_REPEATABLE_FQ_NAME) -> JavaAnnotationDescriptor(c, annotation, c.module.builtIns.repeatableAnnotation) - ClassId.topLevel(JAVA_DOCUMENTED_FQ_NAME) -> JavaAnnotationDescriptor(c, annotation, c.module.builtIns.mustBeDocumentedAnnotation) + ClassId.topLevel(JAVA_REPEATABLE_FQ_NAME) -> JavaAnnotationDescriptor(c, annotation, KotlinBuiltIns.FQ_NAMES.repeatable) + ClassId.topLevel(JAVA_DOCUMENTED_FQ_NAME) -> JavaAnnotationDescriptor(c, annotation, KotlinBuiltIns.FQ_NAMES.mustBeDocumented) ClassId.topLevel(JAVA_DEPRECATED_FQ_NAME) -> null else -> LazyJavaAnnotationDescriptor(c, annotation) } - fun findMappedJavaAnnotation(kotlinName: FqName, - annotationOwner: JavaAnnotationOwner, - c: LazyJavaResolverContext + fun findMappedJavaAnnotation( + kotlinName: FqName, + annotationOwner: JavaAnnotationOwner, + c: LazyJavaResolverContext ): AnnotationDescriptor? { if (kotlinName == KotlinBuiltIns.FQ_NAMES.deprecated) { val javaAnnotation = annotationOwner.findAnnotation(JAVA_DEPRECATED_FQ_NAME) @@ -98,55 +98,48 @@ object JavaAnnotationMapper { open class JavaAnnotationDescriptor( c: LazyJavaResolverContext, annotation: JavaAnnotation?, - private val kotlinAnnotationClassDescriptor: ClassDescriptor + override val fqName: FqName ): AnnotationDescriptor { override val source: SourceElement = annotation?.let { c.components.sourceElementFactory.source(it) } ?: SourceElement.NO_SOURCE - override val type: SimpleType get() = kotlinAnnotationClassDescriptor.defaultType - - protected val valueParameters: List - get() = kotlinAnnotationClassDescriptor.constructors.single().valueParameters + override val type: SimpleType by c.storageManager.createLazyValue { c.module.builtIns.getBuiltInClassByFqName(fqName).defaultType } protected val firstArgument: JavaAnnotationArgument? = annotation?.arguments?.firstOrNull() - override val valueArgumentsByParameterDescriptor: Map> get() = emptyMap() + override val allValueArguments: Map> get() = emptyMap() } class JavaDeprecatedAnnotationDescriptor( annotation: JavaAnnotation?, c: LazyJavaResolverContext -): JavaAnnotationDescriptor(c, annotation, c.module.builtIns.deprecatedAnnotation) { - override val valueArgumentsByParameterDescriptor: Map> by c.storageManager.createLazyValue { - val parameterDescriptor = valueParameters.firstOrNull { - it.name == JavaAnnotationMapper.DEPRECATED_ANNOTATION_MESSAGE - } - parameterDescriptor?.let { - mapOf(it to ConstantValueFactory(c.module.builtIns).createStringValue("Deprecated in Java")) - }.orEmpty() +): JavaAnnotationDescriptor(c, annotation, KotlinBuiltIns.FQ_NAMES.deprecated) { + override val allValueArguments: Map> by c.storageManager.createLazyValue { + mapOf(JavaAnnotationMapper.DEPRECATED_ANNOTATION_MESSAGE to + ConstantValueFactory(c.module.builtIns).createStringValue("Deprecated in Java")) } } class JavaTargetAnnotationDescriptor( annotation: JavaAnnotation, c: LazyJavaResolverContext -): JavaAnnotationDescriptor(c, annotation, c.module.builtIns.targetAnnotation) { - override val valueArgumentsByParameterDescriptor by c.storageManager.createLazyValue { +): JavaAnnotationDescriptor(c, annotation, KotlinBuiltIns.FQ_NAMES.target) { + override val allValueArguments by c.storageManager.createLazyValue { val targetArgument = when (firstArgument) { is JavaArrayAnnotationArgument -> JavaAnnotationTargetMapper.mapJavaTargetArguments(firstArgument.getElements(), c.module.builtIns) is JavaEnumValueAnnotationArgument -> JavaAnnotationTargetMapper.mapJavaTargetArguments(listOf(firstArgument), c.module.builtIns) - else -> return@createLazyValue emptyMap>() + else -> null } - mapOf(valueParameters.single() to targetArgument) + targetArgument?.let { mapOf(JavaAnnotationMapper.TARGET_ANNOTATION_ALLOWED_TARGETS to it) }.orEmpty() } } class JavaRetentionAnnotationDescriptor( annotation: JavaAnnotation, c: LazyJavaResolverContext -): JavaAnnotationDescriptor(c, annotation, c.module.builtIns.retentionAnnotation) { - override val valueArgumentsByParameterDescriptor by c.storageManager.createLazyValue { +): JavaAnnotationDescriptor(c, annotation, KotlinBuiltIns.FQ_NAMES.retention) { + override val allValueArguments by c.storageManager.createLazyValue { val retentionArgument = JavaAnnotationTargetMapper.mapJavaRetentionArgument(firstArgument, c.module.builtIns) - retentionArgument?.let { mapOf(valueParameters.single() to it) }.orEmpty() + retentionArgument?.let { mapOf(JavaAnnotationMapper.RETENTION_ANNOTATION_VALUE to it) }.orEmpty() } } @@ -174,7 +167,8 @@ object JavaAnnotationTargetMapper { .mapNotNull { builtIns.getAnnotationTargetEnumEntry(it) } .map(::EnumValue) val parameterDescriptor = DescriptorResolverUtils.getAnnotationParameterByName( - JavaAnnotationMapper.TARGET_ANNOTATION_ALLOWED_TARGETS, builtIns.targetAnnotation + JavaAnnotationMapper.TARGET_ANNOTATION_ALLOWED_TARGETS, + builtIns.getBuiltInClassByFqName(KotlinBuiltIns.FQ_NAMES.target) ) return ArrayValue(kotlinTargets, parameterDescriptor?.type ?: ErrorUtils.createErrorType("Error: AnnotationTarget[]"), builtIns) } diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt index 43148235a63..b8b2fef39ed 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt @@ -17,7 +17,6 @@ package org.jetbrains.kotlin.load.java.lazy.descriptors import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.findNonGenericClassAcrossDependencies @@ -39,7 +38,6 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass import org.jetbrains.kotlin.resolve.descriptorUtil.resolveTopLevelClass import org.jetbrains.kotlin.storage.getValue import org.jetbrains.kotlin.types.* -import org.jetbrains.kotlin.utils.keysToMapExceptNulls class LazyJavaAnnotationDescriptor( private val c: LazyJavaResolverContext, @@ -61,20 +59,11 @@ class LazyJavaAnnotationDescriptor( private val factory = ConstantValueFactory(c.module.builtIns) - override val valueArgumentsByParameterDescriptor by c.storageManager.createLazyValue { - val constructors = annotationClass!!.constructors - if (constructors.isEmpty()) return@createLazyValue emptyMap>() - - val nameToArg = javaAnnotation.arguments.associateBy { it.name } - - constructors.first().valueParameters.keysToMapExceptNulls { valueParameter -> - var javaAnnotationArgument = nameToArg[valueParameter.name] - if (javaAnnotationArgument == null && valueParameter.name == DEFAULT_ANNOTATION_MEMBER_NAME) { - javaAnnotationArgument = nameToArg[null] - } - - resolveAnnotationArgument(javaAnnotationArgument) - } + override val allValueArguments by c.storageManager.createLazyValue { + javaAnnotation.arguments.mapNotNull { arg -> + val name = arg.name ?: DEFAULT_ANNOTATION_MEMBER_NAME + resolveAnnotationArgument(arg)?.let { value -> name to value } + }.toMap() } private fun resolveAnnotationArgument(argument: JavaAnnotationArgument?): ConstantValue<*>? { diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt index 370f463a4d3..b123b90f116 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt @@ -19,7 +19,6 @@ package org.jetbrains.kotlin.load.java.typeEnhancement import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassifierDescriptor import org.jetbrains.kotlin.descriptors.SourceElement -import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget import org.jetbrains.kotlin.descriptors.annotations.Annotations @@ -31,6 +30,7 @@ import org.jetbrains.kotlin.load.java.typeEnhancement.MutabilityQualifier.READ_O import org.jetbrains.kotlin.load.java.typeEnhancement.NullabilityQualifier.NOT_NULL import org.jetbrains.kotlin.load.java.typeEnhancement.NullabilityQualifier.NULLABLE import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.platform.JavaToKotlinClassMap import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.types.* @@ -209,7 +209,7 @@ private class EnhancedTypeAnnotations(private val fqNameToMatch: FqName) : Annot private object EnhancedTypeAnnotationDescriptor : AnnotationDescriptor { private fun throwError(): Nothing = error("No methods should be called on this descriptor. Only its presence matters") override val type: KotlinType get() = throwError() - override val valueArgumentsByParameterDescriptor: Map> get() = throwError() + override val allValueArguments: Map> get() = throwError() override val source: SourceElement get() = throwError() override fun toString() = "[EnhancedType]" } diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java b/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java index 6e885cbd030..c01543fc9bf 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java @@ -580,26 +580,6 @@ public abstract class KotlinBuiltIns { return getEnumEntry(getBuiltInClassByName(FQ_NAMES.deprecationLevel.shortName()), level); } - @NotNull - public ClassDescriptor getTargetAnnotation() { - return getAnnotationClassByName(FQ_NAMES.target.shortName()); - } - - @NotNull - public ClassDescriptor getRetentionAnnotation() { - return getAnnotationClassByName(FQ_NAMES.retention.shortName()); - } - - @NotNull - public ClassDescriptor getRepeatableAnnotation() { - return getAnnotationClassByName(FQ_NAMES.repeatable.shortName()); - } - - @NotNull - public ClassDescriptor getMustBeDocumentedAnnotation() { - return getAnnotationClassByName(FQ_NAMES.mustBeDocumented.shortName()); - } - @Nullable public ClassDescriptor getAnnotationTargetEnumEntry(@NotNull KotlinTarget target) { return getEnumEntry(getAnnotationClassByName(FQ_NAMES.annotationTarget.shortName()), target.name()); diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationDescriptor.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationDescriptor.kt index ddb37069e26..4a82fd7a69a 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationDescriptor.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationDescriptor.kt @@ -32,11 +32,7 @@ interface AnnotationDescriptor { val fqName: FqName? get() = (type.constructor.declarationDescriptor as? ClassDescriptor)?.fqNameUnsafe?.takeIf(FqNameUnsafe::isSafe)?.toSafe() - @Deprecated("Use allValueArguments instead") - val valueArgumentsByParameterDescriptor: Map> - val allValueArguments: Map> - get() = valueArgumentsByParameterDescriptor.mapKeys { (parameter) -> parameter.name } val source: SourceElement } diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationDescriptorImpl.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationDescriptorImpl.java index 7067598099f..99a49064a85 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationDescriptorImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationDescriptorImpl.java @@ -16,6 +16,8 @@ package org.jetbrains.kotlin.descriptors.annotations; +import kotlin.collections.MapsKt; +import kotlin.jvm.functions.Function1; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.descriptors.SourceElement; @@ -56,16 +58,18 @@ public class AnnotationDescriptorImpl implements AnnotationDescriptor { return AnnotationDescriptor.DefaultImpls.getFqName(this); } - @Override - @NotNull - public Map> getValueArgumentsByParameterDescriptor() { - return valueArguments; - } - @NotNull @Override public Map> getAllValueArguments() { - return AnnotationDescriptor.DefaultImpls.getAllValueArguments(this); + return MapsKt.mapKeys( + valueArguments, + new Function1>, Name>() { + @Override + public Name invoke(Map.Entry> entry) { + return entry.getKey().getName(); + } + } + ); } @Override