From f989037f7cea6a19bbd56ecb2ba5e6e699dbe0cb Mon Sep 17 00:00:00 2001 From: Pavel Kunyavskiy Date: Wed, 2 Aug 2023 12:24:37 +0200 Subject: [PATCH] [K/N] Mark forward declarations as OptIn if annotation exists ^KT-60841 --- ...libResolvedModuleDescriptorsFactoryImpl.kt | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/impl/KlibResolvedModuleDescriptorsFactoryImpl.kt b/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/impl/KlibResolvedModuleDescriptorsFactoryImpl.kt index f602f2f29cd..2e1d04b0b09 100644 --- a/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/impl/KlibResolvedModuleDescriptorsFactoryImpl.kt +++ b/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/impl/KlibResolvedModuleDescriptorsFactoryImpl.kt @@ -187,22 +187,35 @@ class ForwardDeclarationsPackageFragmentDescriptor( findCinteropClass(supertypeName).defaultType } - private val experimentalAnnotationType by storageManager.createLazyValue { - findCinteropClass(NativeStandardInteropNames.ExperimentalForeignApi).defaultType + /** + * Normally, this can't be null. But it's possible inside IDE, if one uses new IDE with + * old compiler in a project. In that case, IDE would try to generate synthetic declaration + * but would fail to find annotation class. + * + * A better way to do this would be introducing language feature, but unfortunately, we can't + * do it between 1.9.0 and 1.9.20. + */ + private val experimentalAnnotationType by storageManager.createNullableLazyValue { + findCinteropClassOrNull(NativeStandardInteropNames.ExperimentalForeignApi)?.defaultType } - private fun findCinteropClass(name: Name): ClassDescriptor { + private fun findCinteropClass(name: Name): ClassDescriptor = findCinteropClassOrNull(name) ?: + error("Class $name is not found") + + private fun findCinteropClassOrNull(name: Name): ClassDescriptor? { return builtIns.builtInsModule.getPackage(NativeStandardInteropNames.cInteropPackage) .memberScope - .getContributedClassifier(name, NoLookupLocation.FROM_BACKEND) as ClassDescriptor + .getContributedClassifier(name, NoLookupLocation.FROM_BACKEND) as ClassDescriptor? } private fun createDeclaration(name: Name): ClassDescriptor { - val experimentalAnnotation = AnnotationDescriptorImpl( - experimentalAnnotationType, - emptyMap(), - SourceElement.NO_SOURCE - ) + val experimentalAnnotation = experimentalAnnotationType?.let { + AnnotationDescriptorImpl( + it, + emptyMap(), + SourceElement.NO_SOURCE + ) + } return object : ClassDescriptorImpl( this@ForwardDeclarationsPackageFragmentDescriptor, @@ -215,7 +228,7 @@ class ForwardDeclarationsPackageFragmentDescriptor( LockBasedStorageManager.NO_LOCKS ) { override fun isExpect(): Boolean = isExpect - override val annotations: Annotations = Annotations.create(listOf(experimentalAnnotation)) + override val annotations: Annotations = Annotations.create(listOfNotNull(experimentalAnnotation)) }.apply { this.initialize(MemberScope.Empty, emptySet(), null) }