Do not use parameter descriptors in most annotation implementations
Except AnnotationDescriptorImpl, which is refactored in the subsequent commit. Note that we no longer check the presence of parameters with the corresponding names in the annotation class in LazyJavaAnnotationDescriptor, this is why test data changed
This commit is contained in:
+23
-29
@@ -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<ValueParameterDescriptor>
|
||||
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<ValueParameterDescriptor, ConstantValue<*>> get() = emptyMap()
|
||||
override val allValueArguments: Map<Name, ConstantValue<*>> get() = emptyMap()
|
||||
}
|
||||
|
||||
class JavaDeprecatedAnnotationDescriptor(
|
||||
annotation: JavaAnnotation?,
|
||||
c: LazyJavaResolverContext
|
||||
): JavaAnnotationDescriptor(c, annotation, c.module.builtIns.deprecatedAnnotation) {
|
||||
override val valueArgumentsByParameterDescriptor: Map<ValueParameterDescriptor, ConstantValue<*>> 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<Name, ConstantValue<*>> 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<ValueParameterDescriptor, ConstantValue<*>>()
|
||||
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)
|
||||
}
|
||||
|
||||
+5
-16
@@ -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<ValueParameterDescriptor, ConstantValue<*>>()
|
||||
|
||||
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<*>? {
|
||||
|
||||
+2
-2
@@ -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<ValueParameterDescriptor, ConstantValue<*>> get() = throwError()
|
||||
override val allValueArguments: Map<Name, ConstantValue<*>> get() = throwError()
|
||||
override val source: SourceElement get() = throwError()
|
||||
override fun toString() = "[EnhancedType]"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user