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 cf620d2d55b..5b7ac637a9b 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 @@ -5,6 +5,7 @@ import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataMo import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl +import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.storage.StorageManager @@ -29,23 +30,25 @@ interface KlibResolvedModuleDescriptorsFactory { storageManager: StorageManager, builtIns: KotlinBuiltIns?, languageVersionSettings: LanguageVersionSettings, - customAction: ((KotlinLibrary, ModuleDescriptorImpl) -> Unit)? = null, + friendModuleFiles: Set, + includedLibraryFiles: Set, additionalDependencyModules: Iterable ): KotlinResolvedModuleDescriptors } class KotlinResolvedModuleDescriptors( + /** + * The list of modules each representing an individual Kotlin/Native library. All modules + * in this list have properly installed dependencies, i.e. module has all necessary dependencies + * on other modules plus a dependency on the [forwardDeclarationsModule]. + */ + val resolvedDescriptors: List, - /** - * The list of modules each representing an individual Kotlin/Native library. All modules - * in this list have properly installed dependencies, i.e. module has all necessary dependencies - * on other modules plus a dependency on the [forwardDeclarationsModule]. - */ - val resolvedDescriptors: List, + /** + * This is a module which "contains" forward declarations. + * Note: this module should be unique per compilation and should always be the last dependency of any module. + */ + val forwardDeclarationsModule: ModuleDescriptorImpl, - /** - * This is a module which "contains" forward declarations. - * Note: this module should be unique per compilation and should always be the last dependency of any module. - */ - val forwardDeclarationsModule: ModuleDescriptorImpl + val friendModules: Set ) 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 0c9fbfd913c..bd192b71f6d 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 @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.descriptors.konan.KlibModuleOrigin import org.jetbrains.kotlin.descriptors.konan.SyntheticModulesOrigin import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation +import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.util.profile import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.metadata.PackageAccessHandler @@ -37,14 +38,19 @@ class KlibResolvedModuleDescriptorsFactoryImpl( storageManager: StorageManager, builtIns: KotlinBuiltIns?, languageVersionSettings: LanguageVersionSettings, - customAction: ((KotlinLibrary, ModuleDescriptorImpl) -> Unit)?, + friendModuleFiles: Set, + includedLibraryFiles: Set, additionalDependencyModules: Iterable ): KotlinResolvedModuleDescriptors { val moduleDescriptors = mutableListOf() + @Suppress("NAME_SHADOWING") var builtIns = builtIns + val friendModuleDescriptors = mutableSetOf() + val includedLibraryDescriptors = mutableSetOf() + // Build module descriptors. resolvedLibraries.forEach { library, packageAccessHandler -> profile("Loading ${library.libraryName}") { @@ -56,7 +62,10 @@ class KlibResolvedModuleDescriptorsFactoryImpl( builtIns = moduleDescriptor.builtIns moduleDescriptors.add(moduleDescriptor) - customAction?.invoke(library, moduleDescriptor) + if (friendModuleFiles.contains(library.libraryFile)) + friendModuleDescriptors.add(moduleDescriptor) + if (includedLibraryFiles.contains(library.libraryFile)) + includedLibraryDescriptors.add(moduleDescriptor) } } @@ -64,14 +73,17 @@ class KlibResolvedModuleDescriptorsFactoryImpl( // Set inter-dependencies between module descriptors, add forwarding declarations module. for (module in moduleDescriptors) { - // Yes, just to all of them. + val friends = additionalDependencyModules.toMutableSet() + if (module in includedLibraryDescriptors) + friends.addAll(friendModuleDescriptors) module.setDependencies( + // Yes, just to all of them. moduleDescriptors + additionalDependencyModules + forwardDeclarationsModule, - additionalDependencyModules.toSet() + friends ) } - return KotlinResolvedModuleDescriptors(moduleDescriptors, forwardDeclarationsModule) + return KotlinResolvedModuleDescriptors(moduleDescriptors, forwardDeclarationsModule, friendModuleDescriptors) } fun createForwardDeclarationsModule( diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/PsiToIr.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/PsiToIr.kt index d394f78c045..3ca8f0efef9 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/PsiToIr.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/PsiToIr.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.ir.linkage.IrDeserializer import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.acceptVoid +import org.jetbrains.kotlin.library.uniqueName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator @@ -94,7 +95,14 @@ internal fun Context.psiToIr( get() = generatorContext.irBuiltIns } - val friendModules = emptyMap>() // TODO: provide friend modules + val friendModules = config.resolvedLibraries.getFullList() + .filter { it.libraryFile in config.friendModuleFiles } + .map { it.uniqueName } + + val friendModulesMap = ( + listOf(moduleDescriptor.name.asStringStripSpecialMarkers()) + + config.resolve.includedLibraries.map { it.uniqueName } + ).associateWith { friendModules } KonanIrLinker( moduleDescriptor, @@ -102,7 +110,7 @@ internal fun Context.psiToIr( messageLogger, generatorContext.irBuiltIns, symbolTable, - friendModules, + friendModulesMap, forwardDeclarationsModuleDescriptor, stubGenerator, irProviderForCEnumsAndCStructs, 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 1caca4843c5..ecd4d8009da 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 @@ -6,60 +6,49 @@ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.analyzer.AnalysisResult -import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.functions.functionInterfacePackageFragmentProvider import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns import org.jetbrains.kotlin.config.CommonConfigurationKeys -import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.container.get import org.jetbrains.kotlin.context.ModuleContext import org.jetbrains.kotlin.context.MutableModuleContextImpl import org.jetbrains.kotlin.context.ProjectContext import org.jetbrains.kotlin.descriptors.PackageFragmentProvider -import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.descriptors.konan.CurrentKlibModuleOrigin import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib -import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.util.KlibMetadataFactories -import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.metadata.NativeTypeTransformer import org.jetbrains.kotlin.library.metadata.NullFlexibleTypeDeserializer -import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.extensions.AnalysisHandlerExtension import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory -import org.jetbrains.kotlin.serialization.konan.KotlinResolvedModuleDescriptors -import org.jetbrains.kotlin.storage.StorageManager internal object TopDownAnalyzerFacadeForKonan { + private val nativeFactories = KlibMetadataFactories(::KonanBuiltIns, NullFlexibleTypeDeserializer, NativeTypeTransformer()) + fun analyzeFiles(files: Collection, context: Context): AnalysisResult { val config = context.config val moduleName = Name.special("<${config.moduleId}>") val projectContext = ProjectContext(config.project, "TopDownAnalyzer for Konan") - val module = NativeFactories.DefaultDescriptorFactory.createDescriptorAndNewBuiltIns( + val module = nativeFactories.DefaultDescriptorFactory.createDescriptorAndNewBuiltIns( moduleName, projectContext.storageManager, origin = CurrentKlibModuleOrigin) val moduleContext = MutableModuleContextImpl(module, projectContext) - val resolvedDependencies = ResolvedDependencies( - config.resolvedLibraries, - projectContext.storageManager, - module.builtIns, - config.languageVersionSettings, - config.friendModuleFiles, - module - ) + val resolvedModuleDescriptors = nativeFactories.DefaultResolvedDescriptorsFactory.createResolved( + config.resolvedLibraries, projectContext.storageManager, module.builtIns, config.languageVersionSettings, + config.friendModuleFiles, config.resolve.includedLibraries.map { it.libraryFile }.toSet(), listOf(module)) val additionalPackages = mutableListOf() if (!module.isNativeStdlib()) { - val dependencies = listOf(module) + resolvedDependencies.moduleDescriptors.resolvedDescriptors + resolvedDependencies.moduleDescriptors.forwardDeclarationsModule - module.setDependencies(dependencies, resolvedDependencies.friends) + val dependencies = listOf(module) + resolvedModuleDescriptors.resolvedDescriptors + resolvedModuleDescriptors.forwardDeclarationsModule + module.setDependencies(dependencies, resolvedModuleDescriptors.friendModules) } else { - assert (resolvedDependencies.moduleDescriptors.resolvedDescriptors.isEmpty()) + assert(resolvedModuleDescriptors.resolvedDescriptors.isEmpty()) moduleContext.setDependencies(module) // [K][Suspend]FunctionN belong to stdlib. additionalPackages += functionInterfacePackageFragmentProvider(projectContext.storageManager, module) @@ -122,34 +111,3 @@ internal object TopDownAnalyzerFacadeForKonan { } } } - -private class ResolvedDependencies( - resolvedLibraries: KotlinLibraryResolveResult, - storageManager: StorageManager, - builtIns: KotlinBuiltIns, - specifics: LanguageVersionSettings, - friendModuleFiles: Set, - currentModuleDescriptor: ModuleDescriptorImpl -) { - - val moduleDescriptors: KotlinResolvedModuleDescriptors - val friends: Set - - init { - - val collectedFriends = mutableListOf() - - val customAction: (KotlinLibrary, ModuleDescriptorImpl) -> Unit = { library, moduleDescriptor -> - if (friendModuleFiles.contains(library.libraryFile)) { - collectedFriends.add(moduleDescriptor) - } - } - - this.moduleDescriptors = NativeFactories.DefaultResolvedDescriptorsFactory.createResolved( - resolvedLibraries, storageManager, builtIns, specifics, customAction, listOf(currentModuleDescriptor)) - - this.friends = collectedFriends.toSet() - } -} - -val NativeFactories = KlibMetadataFactories(::KonanBuiltIns, NullFlexibleTypeDeserializer, NativeTypeTransformer()) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeCompilerArgBuilder.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeCompilerArgBuilder.kt index 837ee2ae3c0..c54d60b6c33 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeCompilerArgBuilder.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeCompilerArgBuilder.kt @@ -77,6 +77,7 @@ internal fun buildKotlinNativeBinaryLinkerArgs( target: KonanTarget, outputKind: CompilerOutputKind, libraries: List, + friendModule: FileCollection, languageSettings: LanguageSettings, enableEndorsedLibs: Boolean, @@ -111,6 +112,11 @@ internal fun buildKotlinNativeBinaryLinkerArgs( exportLibraries.forEach { add("-Xexport-library=${it.absolutePath}") } includeLibraries.forEach { add("-Xinclude=${it.absolutePath}") } + + val friends = friendModule.files + if (friends.isNotEmpty()) { + addArg("-friend-modules", friends.joinToString(File.pathSeparator) { it.absolutePath }) + } } private fun buildKotlinNativeMainArgs( diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt index 84b975a6081..e31cbd800bd 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt @@ -168,6 +168,11 @@ abstract class AbstractKotlinNativeCompile