diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java index 96515b3e985..0ae797ffac3 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java @@ -438,7 +438,7 @@ public abstract class AnnotationCodegen { } @Nullable - private Set getJavaTargetList(ClassDescriptor descriptor) { + private static Set getJavaTargetList(ClassDescriptor descriptor) { AnnotationDescriptor targetAnnotation = descriptor.getAnnotations().findAnnotation(new FqName(Target.class.getName())); if (targetAnnotation != null) { Collection> valueArguments = targetAnnotation.getAllValueArguments().values(); @@ -449,12 +449,9 @@ public abstract class AnnotationCodegen { Set result = EnumSet.noneOf(ElementType.class); for (ConstantValue value : values) { if (value instanceof EnumValue) { - ClassDescriptor enumEntry = ((EnumValue) value).getValue(); - KotlinType classObjectType = DescriptorUtilsKt.getClassValueType(enumEntry); - if (classObjectType != null) { - if ("java/lang/annotation/ElementType".equals(typeMapper.mapType(classObjectType).getInternalName())) { - result.add(ElementType.valueOf(enumEntry.getName().asString())); - } + FqName enumClassFqName = ((EnumValue) value).getEnumClassId().asSingleFqName(); + if (ElementType.class.getName().equals(enumClassFqName.asString())) { + result.add(ElementType.valueOf(((EnumValue) value).getEnumEntryName().asString())); } } } @@ -466,21 +463,18 @@ public abstract class AnnotationCodegen { } @NotNull - private RetentionPolicy getRetentionPolicy(@NotNull Annotated descriptor) { + private static RetentionPolicy getRetentionPolicy(@NotNull Annotated descriptor) { KotlinRetention retention = DescriptorUtilsKt.getAnnotationRetention(descriptor); if (retention != null) { return annotationRetentionMap.get(retention); } AnnotationDescriptor retentionAnnotation = descriptor.getAnnotations().findAnnotation(new FqName(Retention.class.getName())); if (retentionAnnotation != null) { - 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()); - } + ConstantValue value = CollectionsKt.firstOrNull(retentionAnnotation.getAllValueArguments().values()); + if (value instanceof EnumValue) { + FqName enumClassFqName = ((EnumValue) value).getEnumClassId().asSingleFqName(); + if (RetentionPolicy.class.getName().equals(enumClassFqName.asString())) { + return RetentionPolicy.valueOf(((EnumValue) value).getEnumEntryName().asString()); } } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmStringTable.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmStringTable.kt index acf7cf3f09d..7f7b18e7e2d 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmStringTable.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmStringTable.kt @@ -59,16 +59,18 @@ class JvmStringTable(private val typeMapper: KotlinTypeMapper) : StringTable { throw IllegalStateException("Cannot get FQ name of error class: " + descriptor) } - // We use the following format to encode ClassId: "pkg/Outer.Inner". - // It represents a unique name, but such names don't usually appear in the constant pool, so we're writing "Lpkg/Outer$Inner;" - // instead and an instruction to drop the first and the last character in this string and replace all '$' with '.'. - // This works most of the time, except in two rare cases: - // - the name of the class or any of its outer classes contains dollars. In this case we're just storing the described - // string literally: "pkg/Outer.Inner$with$dollars" - // - the class is local or nested in local. In this case we're also storing the literal string, and also storing the fact that - // this name represents a local class in a separate list + return getClassIdIndex(descriptor.classId) + } - val classId = descriptor.classId + // We use the following format to encode ClassId: "pkg/Outer.Inner". + // It represents a unique name, but such names don't usually appear in the constant pool, so we're writing "Lpkg/Outer$Inner;" + // instead and an instruction to drop the first and the last character in this string and replace all '$' with '.'. + // This works most of the time, except in two rare cases: + // - the name of the class or any of its outer classes contains dollars. In this case we're just storing the described + // string literally: "pkg/Outer.Inner$with$dollars" + // - the class is local or nested in local. In this case we're also storing the literal string, and also storing the fact that + // this name represents a local class in a separate list + override fun getClassIdIndex(classId: ClassId): Int { val string = classId.asString() map[string]?.let { recordedIndex -> diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/when/MappingClassesForWhenByEnumCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/when/MappingClassesForWhenByEnumCodegen.java index c592c315a20..5448f2a68c2 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/when/MappingClassesForWhenByEnumCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/when/MappingClassesForWhenByEnumCodegen.java @@ -108,11 +108,11 @@ public class MappingClassesForWhenByEnumCodegen { v.putstatic(cb.getThisName(), mapping.getFieldName(), MAPPINGS_FIELD_DESCRIPTOR); for (Map.Entry item : mapping.enumValuesToIntMapping()) { - EnumValue enumEntry = item.getKey(); + EnumValue enumValue = item.getKey(); int mappedValue = item.getValue(); v.getstatic(cb.getThisName(), mapping.getFieldName(), MAPPINGS_FIELD_DESCRIPTOR); - v.getstatic(enumType.getInternalName(), enumEntry.getValue().getName().asString(), enumType.getDescriptor()); + v.getstatic(enumType.getInternalName(), enumValue.getEnumEntryName().asString(), enumType.getDescriptor()); v.invokevirtual(enumType.getInternalName(), "ordinal", Type.getMethodDescriptor(Type.INT_TYPE), false); v.iconst(mappedValue); v.astore(Type.INT_TYPE); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationChecker.kt index 67d2769b708..f6e2d235380 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationChecker.kt @@ -208,7 +208,7 @@ class AnnotationChecker( val valueArguments = targetEntryDescriptor.allValueArguments val valueArgument = valueArguments.entries.firstOrNull()?.value as? ArrayValue ?: return null return valueArgument.value.filterIsInstance().mapNotNull { - KotlinTarget.valueOrNull(it.value.name.asString()) + KotlinTarget.valueOrNull(it.enumEntryName.asString()) }.toSet() } 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 5a2f4a6646a..9ded952af40 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 @@ -38,6 +38,7 @@ 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.classId import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.checker.KotlinTypeChecker @@ -662,7 +663,8 @@ private class ConstantExpressionEvaluatorVisitor( override fun visitSimpleNameExpression(expression: KtSimpleNameExpression, expectedType: KotlinType?): CompileTimeConstant<*>? { val enumDescriptor = trace.bindingContext.get(BindingContext.REFERENCE_TARGET, expression) if (enumDescriptor != null && DescriptorUtils.isEnumEntry(enumDescriptor)) { - return ConstantValueFactory.createEnumValue(enumDescriptor as ClassDescriptor).wrap() + val enumClassId = (enumDescriptor.containingDeclaration as ClassDescriptor).classId ?: return null + return EnumValue(enumClassId, enumDescriptor.name).wrap() } val resolvedCall = expression.getResolvedCall(trace.bindingContext) diff --git a/compiler/serialization/src/org/jetbrains/kotlin/serialization/AnnotationSerializer.kt b/compiler/serialization/src/org/jetbrains/kotlin/serialization/AnnotationSerializer.kt index 8072bdf6e8e..8bb20289cdb 100644 --- a/compiler/serialization/src/org/jetbrains/kotlin/serialization/AnnotationSerializer.kt +++ b/compiler/serialization/src/org/jetbrains/kotlin/serialization/AnnotationSerializer.kt @@ -78,9 +78,8 @@ class AnnotationSerializer(private val stringTable: StringTable) { override fun visitEnumValue(value: EnumValue, data: Unit) { type = Type.ENUM - val enumEntry = value.value - classId = stringTable.getFqNameIndex(enumEntry.containingDeclaration as ClassDescriptor) - enumValueId = stringTable.getStringIndex(enumEntry.name.asString()) + classId = stringTable.getClassIdIndex(value.enumClassId) + enumValueId = stringTable.getStringIndex(value.enumEntryName.asString()) } override fun visitErrorValue(value: ErrorValue, data: Unit) { diff --git a/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt b/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt index ece8ed5b2f7..838eb6192c0 100644 --- a/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt +++ b/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt @@ -644,19 +644,19 @@ class DescriptorSerializer private constructor( proto.message = stringTable.getStringIndex(message) } - val level = (args[RequireKotlinNames.LEVEL] as? EnumValue)?.value?.name?.asString() + val level = (args[RequireKotlinNames.LEVEL] as? EnumValue)?.enumEntryName?.asString() when (level) { - DeprecationLevel.ERROR.toString() -> { /* ERROR is the default level */ } - DeprecationLevel.WARNING.toString() -> proto.level = ProtoBuf.VersionRequirement.Level.WARNING - DeprecationLevel.HIDDEN.toString() -> proto.level = ProtoBuf.VersionRequirement.Level.HIDDEN + DeprecationLevel.ERROR.name -> { /* ERROR is the default level */ } + DeprecationLevel.WARNING.name -> proto.level = ProtoBuf.VersionRequirement.Level.WARNING + DeprecationLevel.HIDDEN.name -> proto.level = ProtoBuf.VersionRequirement.Level.HIDDEN } - val versionKind = (args[RequireKotlinNames.VERSION_KIND] as? EnumValue)?.value?.name?.asString() + val versionKind = (args[RequireKotlinNames.VERSION_KIND] as? EnumValue)?.enumEntryName?.asString() when (versionKind) { - ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION.toString() -> { /* LANGUAGE_VERSION is the default kind */ } - ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION.toString() -> + ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION.name -> { /* LANGUAGE_VERSION is the default kind */ } + ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION.name -> proto.versionKind = ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION - ProtoBuf.VersionRequirement.VersionKind.API_VERSION.toString() -> + ProtoBuf.VersionRequirement.VersionKind.API_VERSION.name -> proto.versionKind = ProtoBuf.VersionRequirement.VersionKind.API_VERSION } diff --git a/compiler/serialization/src/org/jetbrains/kotlin/serialization/StringTable.kt b/compiler/serialization/src/org/jetbrains/kotlin/serialization/StringTable.kt index e711050db90..0a289ca4f1e 100644 --- a/compiler/serialization/src/org/jetbrains/kotlin/serialization/StringTable.kt +++ b/compiler/serialization/src/org/jetbrains/kotlin/serialization/StringTable.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.serialization import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters +import org.jetbrains.kotlin.name.ClassId import java.io.OutputStream interface StringTable { @@ -24,5 +25,7 @@ interface StringTable { fun getFqNameIndex(descriptor: ClassifierDescriptorWithTypeParameters): Int + fun getClassIdIndex(classId: ClassId): Int + fun serializeTo(output: OutputStream) } diff --git a/compiler/serialization/src/org/jetbrains/kotlin/serialization/StringTableImpl.kt b/compiler/serialization/src/org/jetbrains/kotlin/serialization/StringTableImpl.kt index 427139e58a5..0b1306600e0 100644 --- a/compiler/serialization/src/org/jetbrains/kotlin/serialization/StringTableImpl.kt +++ b/compiler/serialization/src/org/jetbrains/kotlin/serialization/StringTableImpl.kt @@ -62,7 +62,7 @@ open class StringTableImpl : StringTable { return getClassIdIndex(classId) } - fun getClassIdIndex(classId: ClassId): Int { + override fun getClassIdIndex(classId: ClassId): Int { val builder = QualifiedName.newBuilder() builder.kind = QualifiedName.Kind.CLASS diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/missingEnumReferencedInAnnotationArgument/missingEnumReferencedInAnnotationArgument.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/missingEnumReferencedInAnnotationArgument/missingEnumReferencedInAnnotationArgument.txt index 8f45601d63d..5620c1a69eb 100644 --- a/compiler/testData/compileKotlinAgainstCustomBinaries/missingEnumReferencedInAnnotationArgument/missingEnumReferencedInAnnotationArgument.txt +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/missingEnumReferencedInAnnotationArgument/missingEnumReferencedInAnnotationArgument.txt @@ -5,7 +5,7 @@ public final annotation class Anno : kotlin.Annotation { public final val e: test.E } -@test.Anno(e = Unresolved enum entry: test/E.ENTRY) public open class Class { +@test.Anno(e = E.ENTRY) public open class Class { public constructor Class() } diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/MultiModuleJavaAnalysisCustomTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/MultiModuleJavaAnalysisCustomTest.kt index f1c3b865f8d..76d2403cc92 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/MultiModuleJavaAnalysisCustomTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/MultiModuleJavaAnalysisCustomTest.kt @@ -169,8 +169,7 @@ class MultiModuleJavaAnalysisCustomTest : KtUsefulTestCase() { it.allValueArguments.forEach { val argument = it.value if (argument is EnumValue) { - Assert.assertEquals("Enum entry name should be X", "X", argument.value.name.identifier.last().toString()) - checkDescriptor(argument.value, callable) + Assert.assertEquals("Enum entry name should be X", "X", argument.enumEntryName.identifier.last().toString()) } } } diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/AnnotationTypeQualifierResolver.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/AnnotationTypeQualifierResolver.kt index 30c6ce18554..2223590e910 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/AnnotationTypeQualifierResolver.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/AnnotationTypeQualifierResolver.kt @@ -33,7 +33,6 @@ import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.utils.Jsr305State import org.jetbrains.kotlin.utils.ReportLevel import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult -import org.jetbrains.kotlin.utils.addToStdlib.safeAs private val TYPE_QUALIFIER_NICKNAME_FQNAME = FqName("javax.annotation.meta.TypeQualifierNickname") private val TYPE_QUALIFIER_FQNAME = FqName("javax.annotation.meta.TypeQualifier") @@ -148,12 +147,12 @@ class AnnotationTypeQualifierResolver(storageManager: StorageManager, private va } private fun ClassDescriptor.migrationAnnotationStatus(): ReportLevel? { - val stateDescriptor = annotations.findAnnotation(MIGRATION_ANNOTATION_FQNAME)?.firstArgument()?.safeAs()?.value - ?: return null + val enumValue = annotations.findAnnotation(MIGRATION_ANNOTATION_FQNAME)?.firstArgument() as? EnumValue + ?: return null - jsr305State.migration?.let { return jsr305State.migration } + jsr305State.migration?.let { return it } - return when (stateDescriptor.name.asString()) { + return when (enumValue.enumEntryName.asString()) { "STRICT" -> ReportLevel.STRICT "WARN" -> ReportLevel.WARN "IGNORE" -> ReportLevel.IGNORE @@ -165,7 +164,7 @@ class AnnotationTypeQualifierResolver(storageManager: StorageManager, private va when (this) { is ArrayValue -> value.flatMap { it.mapConstantToQualifierApplicabilityTypes() } is EnumValue -> listOfNotNull( - when (value.name.identifier) { + when (enumEntryName.identifier) { "METHOD" -> QualifierApplicabilityType.METHOD_RETURN_TYPE "FIELD" -> QualifierApplicabilityType.FIELD "PARAMETER" -> QualifierApplicabilityType.VALUE_PARAMETER diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/components/JavaAnnotationMapper.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/components/JavaAnnotationMapper.kt index 2a956a7a932..4a9d3f8a00d 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/components/JavaAnnotationMapper.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/components/JavaAnnotationMapper.kt @@ -124,8 +124,8 @@ class JavaTargetAnnotationDescriptor( ): 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) + is JavaArrayAnnotationArgument -> JavaAnnotationTargetMapper.mapJavaTargetArguments(firstArgument.getElements()) + is JavaEnumValueAnnotationArgument -> JavaAnnotationTargetMapper.mapJavaTargetArguments(listOf(firstArgument)) else -> null } targetArgument?.let { mapOf(JavaAnnotationMapper.TARGET_ANNOTATION_ALLOWED_TARGETS to it) }.orEmpty() @@ -137,7 +137,7 @@ class JavaRetentionAnnotationDescriptor( c: LazyJavaResolverContext ): JavaAnnotationDescriptor(c, annotation, KotlinBuiltIns.FQ_NAMES.retention) { override val allValueArguments by c.storageManager.createLazyValue { - val retentionArgument = JavaAnnotationTargetMapper.mapJavaRetentionArgument(firstArgument, c.module.builtIns) + val retentionArgument = JavaAnnotationTargetMapper.mapJavaRetentionArgument(firstArgument) retentionArgument?.let { mapOf(JavaAnnotationMapper.RETENTION_ANNOTATION_VALUE to it) }.orEmpty() } } @@ -159,17 +159,20 @@ object JavaAnnotationTargetMapper { fun mapJavaTargetArgumentByName(argumentName: String?): Set = targetNameLists[argumentName] ?: emptySet() - internal fun mapJavaTargetArguments(arguments: List, builtIns: KotlinBuiltIns): ConstantValue<*> { + internal fun mapJavaTargetArguments(arguments: List): ConstantValue<*> { // Map arguments: java.lang.annotation.Target -> kotlin.annotation.Target val kotlinTargets = arguments.filterIsInstance() .flatMap { mapJavaTargetArgumentByName(it.entryName?.asString()) } - .mapNotNull { builtIns.getAnnotationTargetEnumEntry(it) } - .map(::EnumValue) - val parameterDescriptor = DescriptorResolverUtils.getAnnotationParameterByName( - JavaAnnotationMapper.TARGET_ANNOTATION_ALLOWED_TARGETS, - builtIns.getBuiltInClassByFqName(KotlinBuiltIns.FQ_NAMES.target) - ) - return ArrayValue(kotlinTargets) { parameterDescriptor?.type ?: ErrorUtils.createErrorType("Error: AnnotationTarget[]") } + .map { kotlinTarget -> + EnumValue(ClassId.topLevel(KotlinBuiltIns.FQ_NAMES.annotationTarget), Name.identifier(kotlinTarget.name)) + } + return ArrayValue(kotlinTargets) { module -> + val parameterDescriptor = DescriptorResolverUtils.getAnnotationParameterByName( + JavaAnnotationMapper.TARGET_ANNOTATION_ALLOWED_TARGETS, + module.builtIns.getBuiltInClassByFqName(KotlinBuiltIns.FQ_NAMES.target) + ) + parameterDescriptor?.type ?: ErrorUtils.createErrorType("Error: AnnotationTarget[]") + } } private val retentionNameList = mapOf( @@ -178,11 +181,11 @@ object JavaAnnotationTargetMapper { "SOURCE" to KotlinRetention.SOURCE ) - internal fun mapJavaRetentionArgument(element: JavaAnnotationArgument?, builtIns: KotlinBuiltIns): ConstantValue<*>? { - // Map argument: java.lang.annotation.Retention -> kotlin.annotation.annotation + internal fun mapJavaRetentionArgument(element: JavaAnnotationArgument?): ConstantValue<*>? { + // Map argument: java.lang.annotation.Retention -> kotlin.annotation.Retention return (element as? JavaEnumValueAnnotationArgument)?.let { - retentionNameList[it.entryName?.asString()]?.let { - builtIns.getAnnotationRetentionEnumEntry(it)?.let(::EnumValue) + retentionNameList[it.entryName?.asString()]?.let { retention -> + EnumValue(ClassId.topLevel(KotlinBuiltIns.FQ_NAMES.annotationRetention), Name.identifier(retention.name)) } } } diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt index f213a8fcf7e..2489461b180 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt @@ -16,7 +16,6 @@ package org.jetbrains.kotlin.load.java.lazy.descriptors -import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.findNonGenericClassAcrossDependencies @@ -34,6 +33,7 @@ import org.jetbrains.kotlin.platform.JavaToKotlinClassMap import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory +import org.jetbrains.kotlin.resolve.constants.EnumValue import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass import org.jetbrains.kotlin.resolve.descriptorUtil.resolveTopLevelClass import org.jetbrains.kotlin.storage.getValue @@ -98,21 +98,9 @@ class LazyJavaAnnotationDescriptor( } private fun resolveFromEnumValue(enumClassId: ClassId?, entryName: Name?): ConstantValue<*>? { - if (entryName == null) return null + if (enumClassId == null || entryName == null) return null - if (enumClassId == null) { - return ConstantValueFactory.createEnumValue(ErrorUtils.createErrorClassWithExactName(entryName)) - } - - val enumClass = c.module.findNonGenericClassAcrossDependencies( - enumClassId, - c.components.deserializedDescriptorResolver.components.notFoundClasses - ) - - val classifier = enumClass.unsubstitutedInnerClassesScope.getContributedClassifier(entryName, NoLookupLocation.FROM_JAVA_LOADER) - as? ClassDescriptor ?: return null - - return ConstantValueFactory.createEnumValue(classifier) + return EnumValue(enumClassId, entryName) } private fun resolveFromJavaClassObjectType(javaType: JavaType): ConstantValue<*>? { diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt index d5bcc376032..d7d73f5d9a1 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt @@ -50,11 +50,11 @@ class SignatureEnhancement( ) { private fun AnnotationDescriptor.extractNullabilityTypeFromArgument(): NullabilityQualifierWithMigrationStatus? { - val enumEntryDescriptor = firstArgument().safeAs()?.value - // if no argument is specified, use default value: NOT_NULL - ?: return NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL) + val enumValue = firstArgument() as? EnumValue + // if no argument is specified, use default value: NOT_NULL + ?: return NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL) - return when (enumEntryDescriptor.name.asString()) { + return when (enumValue.enumEntryName.asString()) { "ALWAYS" -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL) "MAYBE", "NEVER" -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE) "UNKNOWN" -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.FORCE_FLEXIBILITY) diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/BinaryClassAnnotationAndConstantLoaderImpl.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/BinaryClassAnnotationAndConstantLoaderImpl.kt index c6ddc1f8644..8f7187cc7d8 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/BinaryClassAnnotationAndConstantLoaderImpl.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/BinaryClassAnnotationAndConstantLoaderImpl.kt @@ -21,7 +21,6 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget -import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.load.java.components.DescriptorResolverUtils import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor import org.jetbrains.kotlin.name.ClassId @@ -29,6 +28,7 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.constants.AnnotationValue import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory +import org.jetbrains.kotlin.resolve.constants.EnumValue import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.deserialization.AnnotationDeserializer import org.jetbrains.kotlin.serialization.deserialization.NameResolver @@ -97,7 +97,7 @@ class BinaryClassAnnotationAndConstantLoaderImpl( } override fun visitEnum(name: Name, enumClassId: ClassId, enumEntryName: Name) { - arguments[name] = enumEntryValue(enumClassId, enumEntryName) + arguments[name] = EnumValue(enumClassId, enumEntryName) } override fun visitArray(name: Name): AnnotationArrayArgumentVisitor? { @@ -109,7 +109,7 @@ class BinaryClassAnnotationAndConstantLoaderImpl( } override fun visitEnum(enumClassId: ClassId, enumEntryName: Name) { - elements.add(enumEntryValue(enumClassId, enumEntryName)) + elements.add(EnumValue(enumClassId, enumEntryName)) } override fun visitEnd() { @@ -132,18 +132,6 @@ class BinaryClassAnnotationAndConstantLoaderImpl( } } - // NOTE: see analogous code in AnnotationDeserializer - private fun enumEntryValue(enumClassId: ClassId, name: Name): ConstantValue<*> { - val enumClass = resolveClass(enumClassId) - if (enumClass.kind == ClassKind.ENUM_CLASS) { - val classifier = enumClass.unsubstitutedInnerClassesScope.getContributedClassifier(name, NoLookupLocation.FROM_JAVA_LOADER) - if (classifier is ClassDescriptor) { - return ConstantValueFactory.createEnumValue(classifier) - } - } - return ConstantValueFactory.createErrorValue("Unresolved enum entry: $enumClassId.$name") - } - override fun visitEnd() { result.add(AnnotationDescriptorImpl(annotationClass.defaultType, arguments, source)) } diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java b/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java index dc4f99d4bab..a7f8c1cd5a0 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java @@ -26,8 +26,6 @@ import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget; import org.jetbrains.kotlin.descriptors.annotations.Annotations; -import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention; -import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget; import org.jetbrains.kotlin.descriptors.deserialization.AdditionalClassPartsProvider; import org.jetbrains.kotlin.descriptors.deserialization.ClassDescriptorFactory; import org.jetbrains.kotlin.descriptors.deserialization.PlatformDependentDeclarationFilter; @@ -574,29 +572,6 @@ public abstract class KotlinBuiltIns { return getBuiltInClassByName("Throwable"); } - @Nullable - private static ClassDescriptor getEnumEntry(@NotNull ClassDescriptor enumDescriptor, @NotNull String entryName) { - ClassifierDescriptor result = enumDescriptor.getUnsubstitutedInnerClassesScope().getContributedClassifier( - Name.identifier(entryName), NoLookupLocation.FROM_BUILTINS - ); - return result instanceof ClassDescriptor ? (ClassDescriptor) result : null; - } - - @Nullable - public ClassDescriptor getDeprecationLevelEnumEntry(@NotNull String level) { - return getEnumEntry(getBuiltInClassByName(FQ_NAMES.deprecationLevel.shortName()), level); - } - - @Nullable - public ClassDescriptor getAnnotationTargetEnumEntry(@NotNull KotlinTarget target) { - return getEnumEntry(getAnnotationClassByName(FQ_NAMES.annotationTarget.shortName()), target.name()); - } - - @Nullable - public ClassDescriptor getAnnotationRetentionEnumEntry(@NotNull KotlinRetention retention) { - return getEnumEntry(getAnnotationClassByName(FQ_NAMES.annotationRetention.shortName()), retention.name()); - } - @NotNull public ClassDescriptor getString() { return getBuiltInClassByName("String"); 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 2f1a8ffe9e0..223613b5a3e 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/annotationUtil.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/annotationUtil.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.MemberDescriptor +import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.DescriptorUtils @@ -52,7 +53,10 @@ fun KotlinBuiltIns.createDeprecatedAnnotation( mapOf( DEPRECATED_MESSAGE_NAME to StringValue(message), DEPRECATED_REPLACE_WITH_NAME to AnnotationValue(replaceWithAnnotation), - DEPRECATED_LEVEL_NAME to EnumValue(getDeprecationLevelEnumEntry(level) ?: error("Deprecation level $level not found")) + DEPRECATED_LEVEL_NAME to EnumValue( + ClassId.topLevel(KotlinBuiltIns.FQ_NAMES.deprecationLevel), + Name.identifier(level) + ) ) ) } diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt index 412710122b5..c06a882e8cb 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt @@ -45,6 +45,8 @@ import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.SmartList import org.jetbrains.kotlin.utils.addToStdlib.safeAs +private val RETENTION_PARAMETER_NAME = Name.identifier("value") + fun ClassDescriptor.getClassObjectReferenceTarget(): ClassDescriptor = companionObjectDescriptor ?: this fun DeclarationDescriptor.getImportableDescriptor(): DeclarationDescriptor { @@ -216,11 +218,10 @@ fun Annotated.isDocumentedAnnotation(): Boolean = annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.mustBeDocumented) != null fun Annotated.getAnnotationRetention(): KotlinRetention? { - val retentionArgumentValue = annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.retention) - ?.allValueArguments - ?.get(Name.identifier("value")) - as? EnumValue ?: return null - return KotlinRetention.valueOf(retentionArgumentValue.value.name.asString()) + val retentionArgumentValue = + annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.retention)?.allValueArguments?.get(RETENTION_PARAMETER_NAME) + as? EnumValue ?: return null + return KotlinRetention.valueOf(retentionArgumentValue.enumEntryName.asString()) } val DeclarationDescriptor.parentsWithSelf: Sequence diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/ConstantValueFactory.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/ConstantValueFactory.kt index c9bc96f1188..5b56ab61213 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/ConstantValueFactory.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/ConstantValueFactory.kt @@ -18,7 +18,6 @@ package org.jetbrains.kotlin.resolve.constants import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.PrimitiveType -import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.types.KotlinType @@ -47,8 +46,6 @@ object ConstantValueFactory { fun createNullValue() = NullValue() - fun createEnumValue(enumEntryClass: ClassDescriptor): EnumValue = EnumValue(enumEntryClass) - fun createArrayValue(value: List>, type: KotlinType) = createArrayValue(value) { type } fun createAnnotationValue(value: AnnotationDescriptor) = AnnotationValue(value) diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/constantValues.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/constantValues.kt index 1c88a3415be..b41cfc510a5 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/constantValues.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/constantValues.kt @@ -17,15 +17,13 @@ package org.jetbrains.kotlin.resolve.constants import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationArgumentVisitor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor +import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.resolve.descriptorUtil.classId -import org.jetbrains.kotlin.resolve.descriptorUtil.classValueType -import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe +import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.KotlinType @@ -111,14 +109,10 @@ class DoubleValue(value: Double) : ConstantValue(value) { override fun toString() = "$value.toDouble()" } -class EnumValue(value: ClassDescriptor) : ConstantValue(value) { - val enumClassId: ClassId get() = (value.containingDeclaration as ClassDescriptor).classId!! - - val enumEntryName: Name get() = value.name - +class EnumValue(val enumClassId: ClassId, val enumEntryName: Name) : ConstantValue>(enumClassId to enumEntryName) { override fun getType(module: ModuleDescriptor): KotlinType = - value.classValueType - ?: ErrorUtils.createErrorType("Containing class for error-class based enum entry ${value.fqNameUnsafe}") + module.findClassAcrossModuleDependencies(enumClassId)?.takeIf(DescriptorUtils::isEnumClass)?.defaultType + ?: ErrorUtils.createErrorType("Containing class for error-class based enum entry $enumClassId.$enumEntryName") override fun accept(visitor: AnnotationArgumentVisitor, data: D) = visitor.visitEnumValue(this, data) diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java b/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java index 7e150f13119..9216637bc9a 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java @@ -368,11 +368,6 @@ public class ErrorUtils { return new ErrorClassDescriptor(Name.special("")); } - @NotNull - public static ClassDescriptor createErrorClassWithExactName(@NotNull Name name) { - return new ErrorClassDescriptor(name); - } - @NotNull public static MemberScope createErrorScope(@NotNull String debugMessage) { return createErrorScope(debugMessage, false); 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 56245cffa73..d141f297ecc 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationDeserializer.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationDeserializer.kt @@ -21,13 +21,13 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl import org.jetbrains.kotlin.descriptors.annotations.Annotations -import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.constants.AnnotationValue import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory +import org.jetbrains.kotlin.resolve.constants.EnumValue import org.jetbrains.kotlin.serialization.ProtoBuf.Annotation import org.jetbrains.kotlin.serialization.ProtoBuf.Annotation.Argument import org.jetbrains.kotlin.serialization.ProtoBuf.Annotation.Argument.Value @@ -85,7 +85,7 @@ class AnnotationDeserializer(private val module: ModuleDescriptor, private val n resolveClassLiteralValue(nameResolver.getClassId(value.classId)) } Type.ENUM -> { - resolveEnumValue(nameResolver.getClassId(value.classId), nameResolver.getName(value.enumValueId)) + EnumValue(nameResolver.getClassId(value.classId), nameResolver.getName(value.enumValueId)) } Type.ANNOTATION -> { AnnotationValue(deserializeAnnotation(value.annotation, nameResolver)) @@ -137,18 +137,6 @@ class AnnotationDeserializer(private val module: ModuleDescriptor, private val n return ConstantValueFactory.createKClassValue(type) } - // NOTE: see analogous code in BinaryClassAnnotationAndConstantLoaderImpl - private fun resolveEnumValue(enumClassId: ClassId, enumEntryName: Name): ConstantValue<*> { - val enumClass = resolveClass(enumClassId) - if (enumClass.kind == ClassKind.ENUM_CLASS) { - val enumEntry = enumClass.unsubstitutedInnerClassesScope.getContributedClassifier(enumEntryName, NoLookupLocation.FROM_DESERIALIZATION) - if (enumEntry is ClassDescriptor) { - return ConstantValueFactory.createEnumValue(enumEntry) - } - } - return ConstantValueFactory.createErrorValue("Unresolved enum entry: $enumClassId.$enumEntryName") - } - private fun resolveArrayElementType(value: Value, nameResolver: NameResolver): SimpleType = with(builtIns) { when (value.type) { diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/WhenTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/WhenTranslator.kt index 07919aa0435..82b9f7ab00e 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/WhenTranslator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/WhenTranslator.kt @@ -197,7 +197,7 @@ private constructor(private val whenExpression: KtWhenExpression, context: Trans ): Pair, Int> { return collectConstantEntries( fromIndex, entries, - { (it.toConstantValue(expectedType) as? EnumValue)?.value?.name?.identifier }, + { (it.toConstantValue(expectedType) as? EnumValue)?.enumEntryName?.identifier }, { uniqueEnumNames.add(it) }, { JsStringLiteral(it) } ) diff --git a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/descriptors/ContainerOptionsProxy.kt b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/descriptors/ContainerOptionsProxy.kt index 401900b739e..9c12c471df1 100644 --- a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/descriptors/ContainerOptionsProxy.kt +++ b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/descriptors/ContainerOptionsProxy.kt @@ -17,7 +17,8 @@ package org.jetbrains.kotlin.android.synthetic.descriptors import kotlinx.android.extensions.CacheImplementation -import kotlinx.android.extensions.CacheImplementation.* +import kotlinx.android.extensions.CacheImplementation.NO_CACHE +import kotlinx.android.extensions.CacheImplementation.valueOf import kotlinx.android.extensions.ContainerOptions import org.jetbrains.kotlin.android.synthetic.codegen.AndroidContainerType import org.jetbrains.kotlin.descriptors.ClassDescriptor @@ -61,7 +62,7 @@ class ContainerOptionsProxy(val containerType: AndroidContainerType, val cache: } private fun > AnnotationDescriptor.getEnumValue(name: String, factory: (String) -> E): E? { - val valueName = (allValueArguments[Name.identifier(name)] as? EnumValue)?.value?.name?.asString() ?: return null + val valueName = (allValueArguments[Name.identifier(name)] as? EnumValue)?.enumEntryName?.asString() ?: return null return try { factory(valueName) @@ -70,4 +71,4 @@ private fun > AnnotationDescriptor.getEnumValue(name: String, factor // Enum.valueOf() may throw this null } -} \ No newline at end of file +}