[K/N][gradle] Supported friend modules for two stage compilation
Fixes https://youtrack.jetbrains.com/issue/KT-49248
This commit is contained in:
+15
-12
@@ -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<File>,
|
||||
includedLibraryFiles: Set<File>,
|
||||
additionalDependencyModules: Iterable<ModuleDescriptorImpl>
|
||||
): 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<ModuleDescriptorImpl>,
|
||||
|
||||
/**
|
||||
* 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<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,
|
||||
|
||||
/**
|
||||
* 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<ModuleDescriptorImpl>
|
||||
)
|
||||
|
||||
+17
-5
@@ -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<File>,
|
||||
includedLibraryFiles: Set<File>,
|
||||
additionalDependencyModules: Iterable<ModuleDescriptorImpl>
|
||||
): KotlinResolvedModuleDescriptors {
|
||||
|
||||
val moduleDescriptors = mutableListOf<ModuleDescriptorImpl>()
|
||||
|
||||
@Suppress("NAME_SHADOWING")
|
||||
var builtIns = builtIns
|
||||
|
||||
val friendModuleDescriptors = mutableSetOf<ModuleDescriptorImpl>()
|
||||
val includedLibraryDescriptors = mutableSetOf<ModuleDescriptorImpl>()
|
||||
|
||||
// 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(
|
||||
|
||||
+10
-2
@@ -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<String, Collection<String>>() // 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,
|
||||
|
||||
+9
-51
@@ -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<KtFile>, 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<PackageFragmentProvider>()
|
||||
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<File>,
|
||||
currentModuleDescriptor: ModuleDescriptorImpl
|
||||
) {
|
||||
|
||||
val moduleDescriptors: KotlinResolvedModuleDescriptors
|
||||
val friends: Set<ModuleDescriptorImpl>
|
||||
|
||||
init {
|
||||
|
||||
val collectedFriends = mutableListOf<ModuleDescriptorImpl>()
|
||||
|
||||
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())
|
||||
|
||||
+6
@@ -77,6 +77,7 @@ internal fun buildKotlinNativeBinaryLinkerArgs(
|
||||
target: KonanTarget,
|
||||
outputKind: CompilerOutputKind,
|
||||
libraries: List<File>,
|
||||
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(
|
||||
|
||||
+6
-4
@@ -168,6 +168,11 @@ abstract class AbstractKotlinNativeCompile<T : KotlinCommonToolOptions, K : Kotl
|
||||
else objects.fileCollection()
|
||||
}
|
||||
|
||||
@get:Classpath
|
||||
protected val friendModule: FileCollection by project.provider {
|
||||
project.files(compilation.friendPaths)
|
||||
}
|
||||
|
||||
@Deprecated("For native tasks use 'libraries' instead", ReplaceWith("libraries"))
|
||||
override fun getClasspath(): FileCollection = libraries
|
||||
override fun setClasspath(configuration: FileCollection?) {
|
||||
@@ -354,10 +359,6 @@ constructor(
|
||||
private val commonSourcesTree: FileTree
|
||||
get() = commonSources.asFileTree
|
||||
|
||||
|
||||
private val friendModule: FileCollection by project.provider {
|
||||
project.files(compilation.friendPaths)
|
||||
}
|
||||
// endregion.
|
||||
|
||||
// region Language settings imported from a SourceSet.
|
||||
@@ -634,6 +635,7 @@ constructor(
|
||||
konanTarget,
|
||||
outputKind,
|
||||
libraries.files.filterKlibsPassedToCompiler(),
|
||||
friendModule,
|
||||
languageSettings,
|
||||
enableEndorsedLibs,
|
||||
localKotlinOptions,
|
||||
|
||||
Reference in New Issue
Block a user