diff --git a/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/DeserializerForClassfileDecompiler.kt b/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/DeserializerForClassfileDecompiler.kt index 629bd393100..d7f2f48bd27 100644 --- a/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/DeserializerForClassfileDecompiler.kt +++ b/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/DeserializerForClassfileDecompiler.kt @@ -63,7 +63,8 @@ class DeserializerForClassfileDecompiler( LookupTracker.DO_NOTHING, JavaFlexibleTypeDeserializer, emptyList(), notFoundClasses, ContractDeserializerImpl(configuration, storageManager), extensionRegistryLite = JvmProtoBufUtil.EXTENSION_REGISTRY, - samConversionResolver = SamConversionResolverImpl(storageManager, samWithReceiverResolvers = emptyList()) + samConversionResolver = SamConversionResolverImpl(storageManager, samWithReceiverResolvers = emptyList()), + enumEntriesDeserializationSupport = enumEntriesDeserializationSupport, ) } diff --git a/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/DeserializerForDecompilerBase.kt b/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/DeserializerForDecompilerBase.kt index 7f56cc8a488..472a3163454 100644 --- a/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/DeserializerForDecompilerBase.kt +++ b/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/DeserializerForDecompilerBase.kt @@ -11,7 +11,9 @@ import org.jetbrains.kotlin.descriptors.impl.MutablePackageFragmentDescriptor import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.jvm.EnumEntriesDeserializationSupportImpl import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents +import org.jetbrains.kotlin.serialization.deserialization.EnumEntriesDeserializationSupport import org.jetbrains.kotlin.serialization.deserialization.LocalClassifierTypeSettings import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.storage.StorageManager @@ -43,6 +45,9 @@ abstract class DeserializerForDecompilerBase(val directoryPackageFqName: FqName) } } + protected val enumEntriesDeserializationSupport: EnumEntriesDeserializationSupport = + EnumEntriesDeserializationSupportImpl(moduleDescriptor.platform) + override fun resolveTopLevelClass(classId: ClassId) = deserializationComponents.deserializeClass(classId) protected fun createDummyPackageFragment(fqName: FqName): MutablePackageFragmentDescriptor = diff --git a/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/KotlinMetadataDeserializerForDecompiler.kt b/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/KotlinMetadataDeserializerForDecompiler.kt index b35c51ef150..6c43c5ba924 100644 --- a/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/KotlinMetadataDeserializerForDecompiler.kt +++ b/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/KotlinMetadataDeserializerForDecompiler.kt @@ -40,7 +40,8 @@ class KotlinMetadataDeserializerForDecompiler( LookupTracker.DO_NOTHING, flexibleTypeDeserializer, emptyList(), notFoundClasses, ContractDeserializer.DEFAULT, extensionRegistryLite = serializerProtocol.extensionRegistry, - samConversionResolver = SamConversionResolverImpl(storageManager, samWithReceiverResolvers = emptyList()) + samConversionResolver = SamConversionResolverImpl(storageManager, samWithReceiverResolvers = emptyList()), + enumEntriesDeserializationSupport = enumEntriesDeserializationSupport, ) } diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/EnumEntriesDeserializationSupportImpl.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/EnumEntriesDeserializationSupportImpl.kt new file mode 100644 index 00000000000..12c1c608ad0 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/EnumEntriesDeserializationSupportImpl.kt @@ -0,0 +1,16 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.resolve.jvm + +import org.jetbrains.kotlin.platform.TargetPlatform +import org.jetbrains.kotlin.platform.jvm.isJvm +import org.jetbrains.kotlin.serialization.deserialization.EnumEntriesDeserializationSupport + +class EnumEntriesDeserializationSupportImpl( + private val platform: TargetPlatform?, +) : EnumEntriesDeserializationSupport { + override fun canSynthesizeEnumEntries(): Boolean = platform.isJvm() +} \ No newline at end of file diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/multiplatform/OptionalAnnotationPackageFragmentProvider.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/multiplatform/OptionalAnnotationPackageFragmentProvider.kt index 0b814b104e6..d28e8ececca 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/multiplatform/OptionalAnnotationPackageFragmentProvider.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/multiplatform/OptionalAnnotationPackageFragmentProvider.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.load.kotlin.PackagePartProvider import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.jvm.EnumEntriesDeserializationSupportImpl import org.jetbrains.kotlin.resolve.jvm.JvmCompilerDeserializationConfiguration import org.jetbrains.kotlin.resolve.sam.SamConversionResolver import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter @@ -61,7 +62,8 @@ class OptionalAnnotationPackageFragmentProvider( notFoundClasses, ContractDeserializer.DEFAULT, extensionRegistryLite = serializerProtocol.extensionRegistry, - samConversionResolver = SamConversionResolver.Empty + samConversionResolver = SamConversionResolver.Empty, + enumEntriesDeserializationSupport = EnumEntriesDeserializationSupportImpl(module.platform), ) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java index 6904667496c..96b4f999c01 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java @@ -135,7 +135,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes this.kind = classLikeInfo.getClassKind(); this.staticScope = kind == ClassKind.ENUM_CLASS ? new StaticScopeForKotlinEnum( - storageManager, this + storageManager, this, /* enumEntriesCanBeUsed = */ true ) : MemberScope.Empty.INSTANCE; this.typeConstructor = new LazyClassTypeConstructor(); diff --git a/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/impl/KlibMetadataModuleDescriptorFactoryImpl.kt b/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/impl/KlibMetadataModuleDescriptorFactoryImpl.kt index d1f45c32493..dbf1ad920eb 100644 --- a/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/impl/KlibMetadataModuleDescriptorFactoryImpl.kt +++ b/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/impl/KlibMetadataModuleDescriptorFactoryImpl.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.library.unresolvedDependencies import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.parentOrNull +import org.jetbrains.kotlin.platform.jvm.isJvm import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration import org.jetbrains.kotlin.resolve.sam.SamConversionResolverImpl import org.jetbrains.kotlin.serialization.deserialization.* @@ -152,6 +153,10 @@ class KlibMetadataModuleDescriptorFactoryImpl( KlibMetadataSerializerProtocol ) + val enumEntriesDeserializationSupport = object : EnumEntriesDeserializationSupport { + override fun canSynthesizeEnumEntries(): Boolean = moduleDescriptor.platform.isJvm() + } + val components = DeserializationComponents( storageManager, moduleDescriptor, @@ -168,7 +173,8 @@ class KlibMetadataModuleDescriptorFactoryImpl( ContractDeserializerImpl(configuration, storageManager), extensionRegistryLite = KlibMetadataSerializerProtocol.extensionRegistry, samConversionResolver = SamConversionResolverImpl(storageManager, samWithReceiverResolvers = emptyList()), - platformDependentTypeTransformer = platformDependentTypeTransformer + platformDependentTypeTransformer = platformDependentTypeTransformer, + enumEntriesDeserializationSupport = enumEntriesDeserializationSupport, ) fragmentsToInitialize.forEach { diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/builtins/jvm/JvmBuiltInsPackageFragmentProvider.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/builtins/jvm/JvmBuiltInsPackageFragmentProvider.kt index 93c56cd61d4..beb55798ed3 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/builtins/jvm/JvmBuiltInsPackageFragmentProvider.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/builtins/jvm/JvmBuiltInsPackageFragmentProvider.kt @@ -52,7 +52,8 @@ class JvmBuiltInsPackageFragmentProvider( additionalClassPartsProvider, platformDependentDeclarationFilter, BuiltInSerializerProtocol.extensionRegistry, kotlinTypeChecker, - samConversionResolver + samConversionResolver, + enumEntriesDeserializationSupport = JvmEnumEntriesDeserializationSupport, ) } diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/DeserializationComponentsForJava.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/DeserializationComponentsForJava.kt index d67c1776124..3d75c4bf8a0 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/DeserializationComponentsForJava.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/DeserializationComponentsForJava.kt @@ -27,11 +27,7 @@ import org.jetbrains.kotlin.descriptors.deserialization.PlatformDependentDeclara import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.incremental.components.LookupTracker -import org.jetbrains.kotlin.load.java.AnnotationTypeQualifierResolver -import org.jetbrains.kotlin.load.java.JavaClassFinder -import org.jetbrains.kotlin.load.java.JavaClassesTracker -import org.jetbrains.kotlin.load.java.JavaModuleAnnotationsProvider -import org.jetbrains.kotlin.load.java.JavaTypeEnhancementState +import org.jetbrains.kotlin.load.java.* import org.jetbrains.kotlin.load.java.components.JavaPropertyInitializerEvaluator import org.jetbrains.kotlin.load.java.components.JavaResolverCache import org.jetbrains.kotlin.load.java.components.SignaturePropagator @@ -82,7 +78,8 @@ class DeserializationComponentsForJava( platformDependentDeclarationFilter = jvmBuiltIns?.customizer ?: PlatformDependentDeclarationFilter.NoPlatformDependent, extensionRegistryLite = JvmProtoBufUtil.EXTENSION_REGISTRY, kotlinTypeChecker = kotlinTypeChecker, samConversionResolver = SamConversionResolverImpl(storageManager, emptyList()), - typeAttributeTranslators = typeAttributeTranslators.translators + typeAttributeTranslators = typeAttributeTranslators.translators, + enumEntriesDeserializationSupport = JvmEnumEntriesDeserializationSupport, ) } diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/StaticScopeForKotlinEnum.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/StaticScopeForKotlinEnum.kt index fd11c437d08..8bde263213a 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/StaticScopeForKotlinEnum.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/StaticScopeForKotlinEnum.kt @@ -31,7 +31,8 @@ import org.jetbrains.kotlin.utils.SmartList // We don't need to track lookups here since this scope used only for introduce special Enum class members class StaticScopeForKotlinEnum( storageManager: StorageManager, - private val containingClass: ClassDescriptor + private val containingClass: ClassDescriptor, + private val enumEntriesCanBeUsed: Boolean, ) : MemberScopeImpl() { init { assert(containingClass.kind == ClassKind.ENUM_CLASS) { "Class should be an enum: $containingClass" } @@ -44,7 +45,12 @@ class StaticScopeForKotlinEnum( } private val properties: List by storageManager.createLazyValue { - listOfNotNull(createEnumEntriesProperty(containingClass)) + if (enumEntriesCanBeUsed) { + // It still might be filtered out later in tower resolve if feature disabled + listOfNotNull(createEnumEntriesProperty(containingClass)) + } else { + emptyList() + } } override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) = functions + properties diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/EnumEntriesDeserializationSupport.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/EnumEntriesDeserializationSupport.kt new file mode 100644 index 00000000000..c3dd0712d54 --- /dev/null +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/EnumEntriesDeserializationSupport.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.serialization.deserialization + +interface EnumEntriesDeserializationSupport { + /** + * Determines whether `Enum.entries` property can be synthesized for enums in this module, + * when this property is not present in compiled code. + * Returns `null` if it's not known. + */ + fun canSynthesizeEnumEntries(): Boolean? + + object Default : EnumEntriesDeserializationSupport { + override fun canSynthesizeEnumEntries(): Boolean? = null + } +} + +object JvmEnumEntriesDeserializationSupport : EnumEntriesDeserializationSupport { + + // In JVM modules "entries" can be called even on enum compiled without this property. + override fun canSynthesizeEnumEntries(): Boolean = true +} \ No newline at end of file diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/context.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/context.kt index ff297615194..8e8eb7708ed 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/context.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/context.kt @@ -55,7 +55,8 @@ class DeserializationComponents( val kotlinTypeChecker: NewKotlinTypeChecker = NewKotlinTypeChecker.Default, val samConversionResolver: SamConversionResolver, val platformDependentTypeTransformer: PlatformDependentTypeTransformer = PlatformDependentTypeTransformer.None, - val typeAttributeTranslators: List = listOf(DefaultTypeAttributeTranslator) + val typeAttributeTranslators: List = listOf(DefaultTypeAttributeTranslator), + val enumEntriesDeserializationSupport: EnumEntriesDeserializationSupport = EnumEntriesDeserializationSupport.Default, ) { val classDeserializer: ClassDeserializer = ClassDeserializer(this) diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt index 5af6b7682c9..ce109d92925 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt @@ -53,10 +53,13 @@ class DeserializedClassDescriptor( ) private val staticScope = - if (kind == ClassKind.ENUM_CLASS) - StaticScopeForKotlinEnum(c.storageManager, this) - else + if (kind == ClassKind.ENUM_CLASS) { + val enumEntriesCanBeUsed = Flags.HAS_ENUM_ENTRIES.get(classProto.flags) || + c.components.enumEntriesDeserializationSupport.canSynthesizeEnumEntries() == true + StaticScopeForKotlinEnum(c.storageManager, this, enumEntriesCanBeUsed) + } else { MemberScope.Empty + } private val typeConstructor = DeserializedClassTypeConstructor() diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/kotlinJavascriptPackageFragmentProvider.kt b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/kotlinJavascriptPackageFragmentProvider.kt index b029c2b68ea..33b9800d904 100644 --- a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/kotlinJavascriptPackageFragmentProvider.kt +++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/kotlinJavascriptPackageFragmentProvider.kt @@ -64,6 +64,10 @@ fun createKotlinJavascriptPackageFragmentProvider( val notFoundClasses = NotFoundClasses(storageManager, module) + val enumEntriesDeserializationSupport = object : EnumEntriesDeserializationSupport { + override fun canSynthesizeEnumEntries(): Boolean = false + } + val components = DeserializationComponents( storageManager, module, @@ -80,7 +84,8 @@ fun createKotlinJavascriptPackageFragmentProvider( ContractDeserializerImpl(configuration, storageManager), platformDependentDeclarationFilter = PlatformDependentDeclarationFilter.NoPlatformDependent, extensionRegistryLite = JsSerializerProtocol.extensionRegistry, - samConversionResolver = SamConversionResolverImpl(storageManager, samWithReceiverResolvers = emptyList()) + samConversionResolver = SamConversionResolverImpl(storageManager, samWithReceiverResolvers = emptyList()), + enumEntriesDeserializationSupport = enumEntriesDeserializationSupport, ) for (packageFragment in packageFragments.filterIsInstance()) {