Change map key type in AnnotationDescriptor.getAllValueArguments

Turns out, only the parameter's name is needed at all usages of this
method. Such a map is both easier to use (no need to call
ValueParameterDescriptor.getName) and easier to construct (no need to
resolve annotation class, its constructor, its parameters). In this
commit, only usages have changed but the implementations are still using
the old logic, this is going to be refactored in subsequent commits
This commit is contained in:
Alexander Udalov
2017-07-04 15:45:16 +03:00
parent 41ea0e8ef8
commit cc7ed2ba54
15 changed files with 65 additions and 71 deletions
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.codegen;
import kotlin.collections.CollectionsKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.annotation.WrappedAnnotated;
@@ -25,6 +26,7 @@ import org.jetbrains.kotlin.descriptors.annotations.*;
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.AnnotationChecker;
import org.jetbrains.kotlin.resolve.constants.*;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
@@ -291,32 +293,27 @@ public abstract class AnnotationCodegen {
@Nullable
private String genAnnotation(@NotNull AnnotationDescriptor annotationDescriptor) {
ClassifierDescriptor classifierDescriptor = getAnnotationClass(annotationDescriptor);
assert classifierDescriptor != null : "Annotation descriptor has no class: " + annotationDescriptor;
RetentionPolicy rp = getRetentionPolicy(classifierDescriptor);
ClassDescriptor classDescriptor = getAnnotationClass(annotationDescriptor);
assert classDescriptor != null : "Annotation descriptor has no class: " + annotationDescriptor;
RetentionPolicy rp = getRetentionPolicy(classDescriptor);
if (rp == RetentionPolicy.SOURCE && !typeMapper.getClassBuilderMode().generateSourceRetentionAnnotations) {
return null;
}
String descriptor = typeMapper.mapType(annotationDescriptor.getType()).getDescriptor();
innerClassConsumer.addInnerClassInfoFromAnnotation(classDescriptor);
if (classifierDescriptor instanceof ClassDescriptor) {
innerClassConsumer.addInnerClassInfoFromAnnotation(((ClassDescriptor) classifierDescriptor));
}
AnnotationVisitor annotationVisitor = visitAnnotation(descriptor, rp == RetentionPolicy.RUNTIME);
String asmTypeDescriptor = typeMapper.mapType(annotationDescriptor.getType()).getDescriptor();
AnnotationVisitor annotationVisitor = visitAnnotation(asmTypeDescriptor, rp == RetentionPolicy.RUNTIME);
genAnnotationArguments(annotationDescriptor, annotationVisitor);
annotationVisitor.visitEnd();
return descriptor;
return asmTypeDescriptor;
}
private void genAnnotationArguments(AnnotationDescriptor annotationDescriptor, AnnotationVisitor annotationVisitor) {
for (Map.Entry<ValueParameterDescriptor, ConstantValue<?>> entry : annotationDescriptor.getAllValueArguments().entrySet()) {
ValueParameterDescriptor descriptor = entry.getKey();
String name = descriptor.getName().asString();
genCompileTimeValue(name, entry.getValue(), annotationVisitor);
for (Map.Entry<Name, ConstantValue<?>> entry : annotationDescriptor.getAllValueArguments().entrySet()) {
genCompileTimeValue(entry.getKey().asString(), entry.getValue(), annotationVisitor);
}
}
@@ -475,16 +472,13 @@ public abstract class AnnotationCodegen {
}
AnnotationDescriptor retentionAnnotation = descriptor.getAnnotations().findAnnotation(new FqName(Retention.class.getName()));
if (retentionAnnotation != null) {
Collection<ConstantValue<?>> valueArguments = retentionAnnotation.getAllValueArguments().values();
if (!valueArguments.isEmpty()) {
ConstantValue<?> compileTimeConstant = valueArguments.iterator().next();
if (compileTimeConstant instanceof EnumValue) {
ClassDescriptor enumEntry = ((EnumValue) compileTimeConstant).getValue();
KotlinType classObjectType = DescriptorUtilsKt.getClassValueType(enumEntry);
if (classObjectType != null) {
if ("java/lang/annotation/RetentionPolicy".equals(typeMapper.mapType(classObjectType).getInternalName())) {
return RetentionPolicy.valueOf(enumEntry.getName().asString());
}
ConstantValue<?> compileTimeConstant = CollectionsKt.firstOrNull(retentionAnnotation.getAllValueArguments().values());
if (compileTimeConstant instanceof EnumValue) {
ClassDescriptor enumEntry = ((EnumValue) compileTimeConstant).getValue();
KotlinType classObjectType = DescriptorUtilsKt.getClassValueType(enumEntry);
if (classObjectType != null) {
if ("java/lang/annotation/RetentionPolicy".equals(typeMapper.mapType(classObjectType).getInternalName())) {
return RetentionPolicy.valueOf(enumEntry.getName().asString());
}
}
}
@@ -19,8 +19,8 @@ package org.jetbrains.kotlin.resolve.annotations
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.constants.ErrorValue
private val JVM_STATIC_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.JvmStatic")
@@ -42,12 +42,5 @@ fun DeclarationDescriptor.findStrictfpAnnotation() =
DescriptorUtils.getAnnotationByFqName(annotations, STRICTFP_ANNOTATION_FQ_NAME)
fun AnnotationDescriptor.argumentValue(parameterName: String): Any? {
val constant: ConstantValue<*>? = allValueArguments.entries
.singleOrNull { it.key.name.asString() == parameterName }
?.value
if (constant == null || constant is ErrorValue)
return null
return constant.value
return allValueArguments[Name.identifier(parameterName)].takeUnless { it is ErrorValue }?.value
}
@@ -126,7 +126,7 @@ class LazyAnnotationDescriptor(
c.scope
}
override val allValueArguments by c.storageManager.createLazyValue {
override val valueArgumentsByParameterDescriptor by c.storageManager.createLazyValue {
val resolutionResults = c.annotationResolver.resolveAnnotationCall(annotationEntry, scope, c.trace)
AnnotationResolverImpl.checkAnnotationType(annotationEntry, c.trace, resolutionResults)
@@ -34,9 +34,9 @@ class AnnotationSerializer(private val stringTable: StringTable) {
id = stringTable.getFqNameIndex(annotationClass)
for ((parameter, value) in annotation.allValueArguments) {
for ((name, value) in annotation.allValueArguments) {
val argument = ProtoBuf.Annotation.Argument.newBuilder()
argument.nameId = stringTable.getStringIndex(parameter.name.asString())
argument.nameId = stringTable.getStringIndex(name.asString())
argument.setValue(valueProto(value))
addArgument(argument)
}
@@ -92,7 +92,7 @@ class AnnotationTypeQualifierResolverImpl(storageManager: StorageManager) : Anno
.annotations.findAnnotation(TYPE_QUALIFIER_DEFAULT_FQNAME)!!
.allValueArguments
.flatMap { (parameter, argument) ->
if (parameter.name == JvmAnnotationNames.DEFAULT_ANNOTATION_MEMBER_NAME)
if (parameter == JvmAnnotationNames.DEFAULT_ANNOTATION_MEMBER_NAME)
argument.mapConstantToQualifierApplicabilityTypes()
else
emptyList()
@@ -109,14 +109,14 @@ open class JavaAnnotationDescriptor(
protected val firstArgument: JavaAnnotationArgument? = annotation?.arguments?.firstOrNull()
override val allValueArguments: Map<ValueParameterDescriptor, ConstantValue<*>> get() = emptyMap()
override val valueArgumentsByParameterDescriptor: Map<ValueParameterDescriptor, ConstantValue<*>> get() = emptyMap()
}
class JavaDeprecatedAnnotationDescriptor(
annotation: JavaAnnotation?,
c: LazyJavaResolverContext
): JavaAnnotationDescriptor(c, annotation, c.module.builtIns.deprecatedAnnotation) {
override val allValueArguments: Map<ValueParameterDescriptor, ConstantValue<*>> by c.storageManager.createLazyValue {
override val valueArgumentsByParameterDescriptor: Map<ValueParameterDescriptor, ConstantValue<*>> by c.storageManager.createLazyValue {
val parameterDescriptor = valueParameters.firstOrNull {
it.name == JavaAnnotationMapper.DEPRECATED_ANNOTATION_MESSAGE
}
@@ -130,7 +130,7 @@ class JavaTargetAnnotationDescriptor(
annotation: JavaAnnotation,
c: LazyJavaResolverContext
): JavaAnnotationDescriptor(c, annotation, c.module.builtIns.targetAnnotation) {
override val allValueArguments by c.storageManager.createLazyValue {
override val valueArgumentsByParameterDescriptor 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)
@@ -144,7 +144,7 @@ class JavaRetentionAnnotationDescriptor(
annotation: JavaAnnotation,
c: LazyJavaResolverContext
): JavaAnnotationDescriptor(c, annotation, c.module.builtIns.retentionAnnotation) {
override val allValueArguments by c.storageManager.createLazyValue {
override val valueArgumentsByParameterDescriptor by c.storageManager.createLazyValue {
val retentionArgument = JavaAnnotationTargetMapper.mapJavaRetentionArgument(firstArgument, c.module.builtIns)
retentionArgument?.let { mapOf(valueParameters.single() to it) }.orEmpty()
}
@@ -61,7 +61,7 @@ class LazyJavaAnnotationDescriptor(
private val factory = ConstantValueFactory(c.module.builtIns)
override val allValueArguments by c.storageManager.createLazyValue {
override val valueArgumentsByParameterDescriptor by c.storageManager.createLazyValue {
val constructors = annotationClass!!.constructors
if (constructors.isEmpty()) return@createLazyValue emptyMap<ValueParameterDescriptor, ConstantValue<*>>()
@@ -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 allValueArguments: Map<ValueParameterDescriptor, ConstantValue<*>> get() = throwError()
override val valueArgumentsByParameterDescriptor: Map<ValueParameterDescriptor, ConstantValue<*>> get() = throwError()
override val source: SourceElement get() = throwError()
override fun toString() = "[EnhancedType]"
}
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.types.KotlinType
@@ -31,7 +32,11 @@ interface AnnotationDescriptor {
val fqName: FqName? get() =
(type.constructor.declarationDescriptor as? ClassDescriptor)?.fqNameUnsafe?.takeIf(FqNameUnsafe::isSafe)?.toSafe()
val allValueArguments: Map<ValueParameterDescriptor, ConstantValue<*>>
@Deprecated("Use allValueArguments instead")
val valueArgumentsByParameterDescriptor: Map<ValueParameterDescriptor, ConstantValue<*>>
val allValueArguments: Map<Name, ConstantValue<*>>
get() = valueArgumentsByParameterDescriptor.mapKeys { (parameter) -> parameter.name }
val source: SourceElement
}
@@ -21,6 +21,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.SourceElement;
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.types.KotlinType;
@@ -57,10 +58,16 @@ public class AnnotationDescriptorImpl implements AnnotationDescriptor {
@Override
@NotNull
public Map<ValueParameterDescriptor, ConstantValue<?>> getAllValueArguments() {
public Map<ValueParameterDescriptor, ConstantValue<?>> getValueArgumentsByParameterDescriptor() {
return valueArguments;
}
@NotNull
@Override
public Map<Name, ConstantValue<?>> getAllValueArguments() {
return AnnotationDescriptor.DefaultImpls.getAllValueArguments(this);
}
@Override
@NotNull
public SourceElement getSource() {
@@ -429,17 +429,14 @@ internal class DescriptorRendererImpl(
private fun renderAndSortAnnotationArguments(descriptor: AnnotationDescriptor): List<String> {
val allValueArguments = descriptor.allValueArguments
val classDescriptor = if (renderDefaultAnnotationArguments) TypeUtils.getClassDescriptor(descriptor.type) else null
val parameterDescriptorsWithDefaultValue = classDescriptor?.unsubstitutedPrimaryConstructor?.valueParameters?.filter {
it.declaresDefaultValue()
} ?: emptyList()
val defaultList = parameterDescriptorsWithDefaultValue.filter { !allValueArguments.containsKey(it) }.map {
"${it.name.asString()} = ..."
}
val parameterDescriptorsWithDefaultValue = classDescriptor?.unsubstitutedPrimaryConstructor?.valueParameters
?.filter { it.declaresDefaultValue() }
?.map { it.name }
.orEmpty()
val defaultList = parameterDescriptorsWithDefaultValue.filter { it !in allValueArguments }.map { "${it.asString()} = ..." }
val argumentList = allValueArguments.entries
.map { entry ->
val name = entry.key.name.asString()
val value = if (!parameterDescriptorsWithDefaultValue.contains(entry.key)) renderConstant(entry.value) else "..."
"$name = $value"
.map { (name, value) ->
"${name.asString()} = ${if (name !in parameterDescriptorsWithDefaultValue) renderConstant(value) else "..."}"
}
return (defaultList + argumentList).sorted()
}
@@ -522,10 +522,10 @@ public class DescriptorUtils {
}
@Nullable
public static String getJvmName(@Nullable AnnotationDescriptor jvmNameAnnotation) {
private static String getJvmName(@Nullable AnnotationDescriptor jvmNameAnnotation) {
if (jvmNameAnnotation == null) return null;
Map<ValueParameterDescriptor, ConstantValue<?>> arguments = jvmNameAnnotation.getAllValueArguments();
Map<Name, ConstantValue<?>> arguments = jvmNameAnnotation.getAllValueArguments();
if (arguments.isEmpty()) return null;
ConstantValue<?> name = arguments.values().iterator().next();
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils.getContainingClass
import org.jetbrains.kotlin.resolve.constants.EnumValue
@@ -213,10 +214,10 @@ fun Annotated.isDocumentedAnnotation(): Boolean =
annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.mustBeDocumented) != null
fun Annotated.getAnnotationRetention(): KotlinRetention? {
val annotationEntryDescriptor = annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.retention) ?: return null
val retentionArgumentValue = annotationEntryDescriptor.allValueArguments.entries.firstOrNull {
it.key.name.asString() == "value"
}?.value as? EnumValue ?: return null
val retentionArgumentValue = annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.retention)
?.allValueArguments
?.get(Name.identifier("value"))
as? EnumValue ?: return null
return KotlinRetention.valueOf(retentionArgumentValue.value.name.asString())
}
@@ -53,7 +53,7 @@ private val PROPERTY_KEY = FqName(AnnotationUtil.PROPERTY_KEY)
private val PROPERTY_KEY_RESOURCE_BUNDLE = Name.identifier(AnnotationUtil.PROPERTY_KEY_RESOURCE_BUNDLE_PARAMETER)
private fun AnnotationDescriptor.getBundleName(): String? {
return allValueArguments.entries.singleOrNull { it.key.name == PROPERTY_KEY_RESOURCE_BUNDLE }?.value?.value as? String
return allValueArguments[PROPERTY_KEY_RESOURCE_BUNDLE]?.value as? String
}
private fun DeclarationDescriptor.getBundleNameByAnnotation(): String? {
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.android.synthetic.descriptors
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import kotlinx.android.extensions.CacheImplementation
import kotlinx.android.extensions.CacheImplementation.*
import kotlinx.android.extensions.ContainerOptions
@@ -25,6 +24,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.constants.EnumValue
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
@@ -59,17 +59,14 @@ class ContainerOptionsProxy(val containerType: AndroidContainerType, val cache:
}
}
private operator fun AnnotationDescriptor.get(name: String): ConstantValue<*>? {
return allValueArguments.entries.firstOrNull { it.key.name.asString() == name }?.value
}
private fun <E: Enum<E>> AnnotationDescriptor.getEnumValue(name: String, defaultValue: E, factory: (String) -> E): E {
val valueName = (this[name] as? EnumValue)?.value?.name?.asString() ?: defaultValue.name
private fun <E : Enum<E>> AnnotationDescriptor.getEnumValue(name: String, defaultValue: E, factory: (String) -> E): E {
val valueName = (allValueArguments[Name.identifier(name)] as? EnumValue)?.value?.name?.asString() ?: defaultValue.name
return try {
factory(valueName)
} catch (e: IllegalArgumentException) {
}
catch (e: IllegalArgumentException) {
// Enum.valueOf() may throw this
defaultValue
}
}
}