From f39106f75c67cbad6fe89bdddc9899e65399f442 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 4 Jul 2017 16:46:27 +0300 Subject: [PATCH] Do not use parameter descriptors in AnnotationDescriptorImpl --- .../evaluate/ConstantExpressionEvaluator.kt | 8 ++- ...aryClassAnnotationAndConstantLoaderImpl.kt | 17 ++----- .../kotlin/builtins/KotlinBuiltIns.java | 1 + .../kotlin/builtins/functionTypes.kt | 4 +- .../annotations/AnnotationDescriptorImpl.java | 20 ++------ .../descriptors/annotations/annotationUtil.kt | 50 +++++++++---------- .../deserialization/AnnotationDeserializer.kt | 6 +-- 7 files changed, 42 insertions(+), 64 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt index 621657ad2c2..03184551642 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt @@ -29,7 +29,6 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.name.isSubpackageOf import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.resolve.* @@ -39,7 +38,6 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.resolve.constants.* -import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.checker.KotlinTypeChecker @@ -80,12 +78,12 @@ class ConstantExpressionEvaluator( internal fun resolveAnnotationArguments( resolvedCall: ResolvedCall<*>, trace: BindingTrace - ): Map> { - val arguments = HashMap>() + ): Map> { + val arguments = HashMap>() for ((parameterDescriptor, resolvedArgument) in resolvedCall.valueArguments.entries) { val value = getAnnotationArgumentValue(trace, parameterDescriptor, resolvedArgument) if (value != null) { - arguments.put(parameterDescriptor, value) + arguments.put(parameterDescriptor.name, value) } } return arguments diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/BinaryClassAnnotationAndConstantLoaderImpl.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/BinaryClassAnnotationAndConstantLoaderImpl.kt index 0739b40df16..62f59bab61f 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/BinaryClassAnnotationAndConstantLoaderImpl.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/BinaryClassAnnotationAndConstantLoaderImpl.kt @@ -89,16 +89,16 @@ class BinaryClassAnnotationAndConstantLoaderImpl( val annotationClass = resolveClass(annotationClassId) return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor { - private val arguments = HashMap>() + private val arguments = HashMap>() override fun visit(name: Name?, value: Any?) { if (name != null) { - setArgumentValueByName(name, createConstant(name, value)) + arguments[name] = createConstant(name, value) } } override fun visitEnum(name: Name, enumClassId: ClassId, enumEntryName: Name) { - setArgumentValueByName(name, enumEntryValue(enumClassId, enumEntryName)) + arguments[name] = enumEntryValue(enumClassId, enumEntryName) } override fun visitArray(name: Name): AnnotationArrayArgumentVisitor? { @@ -116,7 +116,7 @@ class BinaryClassAnnotationAndConstantLoaderImpl( override fun visitEnd() { val parameter = DescriptorResolverUtils.getAnnotationParameterByName(name, annotationClass) if (parameter != null) { - arguments[parameter] = factory.createArrayValue(elements.compact(), parameter.type) + arguments[name] = factory.createArrayValue(elements.compact(), parameter.type) } } } @@ -128,7 +128,7 @@ class BinaryClassAnnotationAndConstantLoaderImpl( return object: KotlinJvmBinaryClass.AnnotationArgumentVisitor by visitor { override fun visitEnd() { visitor.visitEnd() - setArgumentValueByName(name, AnnotationValue(list.single())) + arguments[name] = AnnotationValue(list.single()) } } } @@ -153,13 +153,6 @@ class BinaryClassAnnotationAndConstantLoaderImpl( return factory.createConstantValue(value) ?: factory.createErrorValue("Unsupported annotation argument: $name") } - - private fun setArgumentValueByName(name: Name, argumentValue: ConstantValue<*>) { - val parameter = DescriptorResolverUtils.getAnnotationParameterByName(name, annotationClass) - if (parameter != null) { - arguments[parameter] = argumentValue - } - } } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java b/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java index c01543fc9bf..479bad3ddc0 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java @@ -283,6 +283,7 @@ public abstract class KotlinBuiltIns { public final FqName deprecated = fqName("Deprecated"); public final FqName deprecationLevel = fqName("DeprecationLevel"); + public final FqName replaceWith = fqName("ReplaceWith"); public final FqName extensionFunctionType = fqName("ExtensionFunctionType"); public final FqName parameterName = fqName("ParameterName"); public final FqName annotation = fqName("Annotation"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/functionTypes.kt b/core/descriptors/src/org/jetbrains/kotlin/builtins/functionTypes.kt index 2b6a625af10..0fe20799436 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/functionTypes.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/functionTypes.kt @@ -168,8 +168,8 @@ fun getFunctionTypeArgumentProjections( val nameValue = ConstantValueFactory(builtIns).createStringValue(name.asString()) val parameterNameAnnotation = AnnotationDescriptorImpl( annotationClass.defaultType, - mapOf(annotationClass.unsubstitutedPrimaryConstructor!!.valueParameters.single() to nameValue), - org.jetbrains.kotlin.descriptors.SourceElement.NO_SOURCE + mapOf(Name.identifier("name") to nameValue), + SourceElement.NO_SOURCE ) type.replaceAnnotations(AnnotationsImpl(type.annotations + parameterNameAnnotation)) } 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 99a49064a85..d646aa2516b 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationDescriptorImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationDescriptorImpl.java @@ -16,33 +16,29 @@ 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; -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; -import java.util.Collections; import java.util.Map; public class AnnotationDescriptorImpl implements AnnotationDescriptor { private final KotlinType annotationType; - private final Map> valueArguments; + private final Map> valueArguments; private final SourceElement source; public AnnotationDescriptorImpl( @NotNull KotlinType annotationType, - @NotNull Map> valueArguments, + @NotNull Map> valueArguments, @NotNull SourceElement source ) { this.annotationType = annotationType; - this.valueArguments = Collections.unmodifiableMap(valueArguments); + this.valueArguments = valueArguments; this.source = source; } @@ -61,15 +57,7 @@ public class AnnotationDescriptorImpl implements AnnotationDescriptor { @NotNull @Override public Map> getAllValueArguments() { - return MapsKt.mapKeys( - valueArguments, - new Function1>, Name>() { - @Override - public Name invoke(Map.Entry> entry) { - return entry.getKey().getName(); - } - } - ); + return valueArguments; } @Override diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/annotationUtil.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/annotationUtil.kt index cb5640fb641..0c70e7cc762 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/annotationUtil.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/annotationUtil.kt @@ -17,7 +17,10 @@ package org.jetbrains.kotlin.descriptors.annotations import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor +import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.descriptors.MemberDescriptor +import org.jetbrains.kotlin.descriptors.SourceElement import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.DescriptorUtils @@ -33,42 +36,37 @@ fun KotlinBuiltIns.createDeprecatedAnnotation( replaceWith: String = "", level: String = "WARNING" ): AnnotationDescriptor { - val deprecatedAnnotation = deprecatedAnnotation - val parameters = deprecatedAnnotation.unsubstitutedPrimaryConstructor!!.valueParameters + val replaceWithAnnotation = AnnotationDescriptorImpl( + getBuiltInClassByFqName(KotlinBuiltIns.FQ_NAMES.replaceWith).defaultType, + mapOf( + REPLACE_WITH_EXPRESSION_NAME to StringValue(replaceWith, this), + REPLACE_WITH_IMPORTS_NAME to ArrayValue(emptyList(), getArrayType(Variance.INVARIANT, stringType), this) + ), + SourceElement.NO_SOURCE + ) - val replaceWithClass = getBuiltInClassByName(Name.identifier("ReplaceWith")) - - val replaceWithParameters = replaceWithClass.unsubstitutedPrimaryConstructor!!.valueParameters return AnnotationDescriptorImpl( deprecatedAnnotation.defaultType, mapOf( - parameters["message"] to StringValue(message, this), - parameters["replaceWith"] to AnnotationValue( - AnnotationDescriptorImpl( - replaceWithClass.defaultType, - mapOf( - replaceWithParameters["expression"] to StringValue(replaceWith, this), - replaceWithParameters["imports"] to ArrayValue( - emptyList(), getArrayType(Variance.INVARIANT, stringType), this) - ), - SourceElement.NO_SOURCE - ) - ), - parameters["level"] to EnumValue(getDeprecationLevelEnumEntry(level) ?: error("Deprecation level $level not found")) + DEPRECATED_MESSAGE_NAME to StringValue(message, this), + DEPRECATED_REPLACE_WITH_NAME to AnnotationValue(replaceWithAnnotation), + DEPRECATED_LEVEL_NAME to EnumValue(getDeprecationLevelEnumEntry(level) ?: error("Deprecation level $level not found")) ), - SourceElement.NO_SOURCE) + SourceElement.NO_SOURCE + ) } +private val DEPRECATED_MESSAGE_NAME = Name.identifier("message") +private val DEPRECATED_REPLACE_WITH_NAME = Name.identifier("replaceWith") +private val DEPRECATED_LEVEL_NAME = Name.identifier("level") +private val REPLACE_WITH_EXPRESSION_NAME = Name.identifier("expression") +private val REPLACE_WITH_IMPORTS_NAME = Name.identifier("imports") + fun KotlinBuiltIns.createUnsafeVarianceAnnotation(): AnnotationDescriptor { val unsafeVarianceAnnotation = getBuiltInClassByFqName(KotlinBuiltIns.FQ_NAMES.unsafeVariance) - return AnnotationDescriptorImpl( - unsafeVarianceAnnotation.defaultType, - emptyMap(), - SourceElement.NO_SOURCE) + return AnnotationDescriptorImpl(unsafeVarianceAnnotation.defaultType, emptyMap(), SourceElement.NO_SOURCE) } -private operator fun Collection.get(parameterName: String) = single { it.name.asString() == parameterName } - private val INLINE_ONLY_ANNOTATION_FQ_NAME = FqName("kotlin.internal.InlineOnly") fun MemberDescriptor.isInlineOnlyOrReifiable(): Boolean = diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationDeserializer.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationDeserializer.kt index 1ba65480bc0..bf3d0e13f80 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationDeserializer.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationDeserializer.kt @@ -46,7 +46,7 @@ class AnnotationDeserializer(private val module: ModuleDescriptor, private val n fun deserializeAnnotation(proto: Annotation, nameResolver: NameResolver): AnnotationDescriptor { val annotationClass = resolveClass(nameResolver.getClassId(proto.id)) - var arguments = emptyMap>() + var arguments = emptyMap>() if (proto.argumentCount != 0 && !ErrorUtils.isError(annotationClass) && DescriptorUtils.isAnnotationClass(annotationClass)) { val constructor = annotationClass.constructors.singleOrNull() if (constructor != null) { @@ -62,9 +62,9 @@ class AnnotationDeserializer(private val module: ModuleDescriptor, private val n proto: Argument, parameterByName: Map, nameResolver: NameResolver - ): Pair>? { + ): Pair>? { val parameter = parameterByName[nameResolver.getName(proto.nameId)] ?: return null - return Pair(parameter, resolveValue(parameter.type, proto.value, nameResolver)) + return Pair(nameResolver.getName(proto.nameId), resolveValue(parameter.type, proto.value, nameResolver)) } fun resolveValue(