Native: make forward declarations `expect` in metadata compilations
If we are compiling metadata, make synthetic forward declarations
`expect`, because otherwise `getFirstClassifierDiscriminateHeaders`
would prefer it over a "real" `expect` declaration from a commonized
interop library, which would ruin the whole idea of using synthetic
forward declarations only when no proper definitions are found.
diff --git a/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/KlibResolvedModuleDescriptorsFactory.kt b/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/KlibResolvedModuleDescriptorsFactory.kt
index 5b7ac63..7f0fb20 100644
--- a/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/KlibResolvedModuleDescriptorsFactory.kt
+++ b/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/KlibResolvedModuleDescriptorsFactory.kt
@@ -32,7 +32,8 @@
languageVersionSettings: LanguageVersionSettings,
friendModuleFiles: Set<File>,
includedLibraryFiles: Set<File>,
- additionalDependencyModules: Iterable<ModuleDescriptorImpl>
+ additionalDependencyModules: Iterable<ModuleDescriptorImpl>,
+ isForMetadataCompilation: Boolean,
): KotlinResolvedModuleDescriptors
}
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 9fc38a8..7b8c4ac 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
@@ -190,6 +190,7 @@
} ?: provider
}
+ // Used from IDEA plugin.
fun createForwardDeclarationHackPackagePartProvider(
storageManager: StorageManager,
module: ModuleDescriptorImpl
@@ -200,7 +201,8 @@
module,
fqName,
Name.identifier(supertypeName),
- classKind
+ classKind,
+ isExpect = true
)
val packageFragmentProvider = PackageFragmentProviderImpl(
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 bd192b7..dbf038b 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
@@ -40,7 +40,8 @@
languageVersionSettings: LanguageVersionSettings,
friendModuleFiles: Set<File>,
includedLibraryFiles: Set<File>,
- additionalDependencyModules: Iterable<ModuleDescriptorImpl>
+ additionalDependencyModules: Iterable<ModuleDescriptorImpl>,
+ isForMetadataCompilation: Boolean,
): KotlinResolvedModuleDescriptors {
val moduleDescriptors = mutableListOf<ModuleDescriptorImpl>()
@@ -69,7 +70,20 @@
}
}
- val forwardDeclarationsModule = createForwardDeclarationsModule(builtIns, storageManager)
+ val forwardDeclarationsModule = createForwardDeclarationsModule(
+ builtIns,
+ storageManager,
+ // If we are compiling metadata, make synthetic forward declarations `expect`,
+ // because otherwise `getFirstClassifierDiscriminateHeaders` would prefer it over a
+ // "real" `expect` declaration from a commonized interop library, which would ruin
+ // the whole idea of using synthetic forward declarations only when no proper definitions
+ // are found.
+ //
+ // If we are compiling for the actual native platform, continue using non-expect
+ // forward declarations (to prevent getting non-actualized expects into the backend,
+ // and to prevent related klib signature changes).
+ isExpect = isForMetadataCompilation,
+ )
// Set inter-dependencies between module descriptors, add forwarding declarations module.
for (module in moduleDescriptors) {
@@ -88,7 +102,8 @@
fun createForwardDeclarationsModule(
builtIns: KotlinBuiltIns?,
- storageManager: StorageManager
+ storageManager: StorageManager,
+ isExpect: Boolean
): ModuleDescriptorImpl {
val module = createDescriptorOptionalBuiltsIns(FORWARD_DECLARATIONS_MODULE_NAME, storageManager, builtIns, SyntheticModulesOrigin)
@@ -99,7 +114,8 @@
module,
fqName,
Name.identifier(supertypeName),
- classKind
+ classKind,
+ isExpect
)
val packageFragmentProvider = PackageFragmentProviderImpl(
@@ -150,7 +166,8 @@
module: ModuleDescriptor,
fqName: FqName,
supertypeName: Name,
- classKind: ClassKind
+ classKind: ClassKind,
+ isExpect: Boolean
) : PackageFragmentDescriptorImpl(module, fqName) {
private val memberScope = object : MemberScopeImpl() {
@@ -166,7 +183,7 @@
}
private fun createDeclaration(name: Name): ClassDescriptor {
- return ClassDescriptorImpl(
+ return object : ClassDescriptorImpl(
this@ForwardDeclarationsPackageFragmentDescriptor,
name,
Modality.FINAL,
@@ -175,7 +192,9 @@
SourceElement.NO_SOURCE,
false,
LockBasedStorageManager.NO_LOCKS
- ).apply {
+ ) {
+ override fun isExpect(): Boolean = isExpect
+ }.apply {
this.initialize(MemberScope.Empty, emptySet(), null)
}
}
diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/TopDownAnalyzerFacadeForKonan.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/TopDownAnalyzerFacadeForKonan.kt
index ecd4d80..ea4b10c 100644
--- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/TopDownAnalyzerFacadeForKonan.kt
+++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/TopDownAnalyzerFacadeForKonan.kt
@@ -41,7 +41,8 @@
val resolvedModuleDescriptors = nativeFactories.DefaultResolvedDescriptorsFactory.createResolved(
config.resolvedLibraries, projectContext.storageManager, module.builtIns, config.languageVersionSettings,
- config.friendModuleFiles, config.resolve.includedLibraries.map { it.libraryFile }.toSet(), listOf(module))
+ config.friendModuleFiles, config.resolve.includedLibraries.map { it.libraryFile }.toSet(), listOf(module),
+ isForMetadataCompilation = config.metadataKlib)
val additionalPackages = mutableListOf<PackageFragmentProvider>()
if (!module.isNativeStdlib()) {