[JS IR] Move klib resolution from cli into compiler

Simplify CLI -> Compiler API
Clean up code
This commit is contained in:
Roman Artemev
2021-06-17 23:28:16 +03:00
committed by teamcityserver
parent 103e4ef2a5
commit 0a49b24320
9 changed files with 104 additions and 89 deletions
@@ -5,9 +5,7 @@
package org.jetbrains.kotlin.ir.backend.js
import org.jetbrains.kotlin.konan.CompilerVersion
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.library.KotlinAbiVersion
import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.library.KotlinLibraryProperResolverWithAttributes
import org.jetbrains.kotlin.library.UnresolvedLibrary
@@ -37,7 +35,7 @@ class JsLibraryResolver(
}
// TODO: This is a temporary set of library resolver policies for js compiler.
fun jsResolveLibraries(libraries: List<String>, repositories: Collection<String>, logger: Logger): KotlinLibraryResolveResult {
fun jsResolveLibraries(libraries: Collection<String>, repositories: Collection<String>, logger: Logger): KotlinLibraryResolveResult {
val unresolvedLibraries = libraries.map { UnresolvedLibrary(it, null) }
val libraryAbsolutePaths = libraries.map { File(it).absolutePath }
// Configure the resolver to only work with absolute paths for now.
@@ -52,7 +52,7 @@ import org.jetbrains.kotlin.konan.util.KlibMetadataFactories
import org.jetbrains.kotlin.library.*
import org.jetbrains.kotlin.library.impl.BuiltInsPlatform
import org.jetbrains.kotlin.library.impl.buildKotlinLibrary
import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult
import org.jetbrains.kotlin.library.resolver.KotlinResolvedLibrary
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.progress.IncrementalNextRoundException
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
@@ -65,6 +65,8 @@ import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingContextUtils
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.util.DummyLogger
import org.jetbrains.kotlin.util.Logger
import org.jetbrains.kotlin.utils.DFS
import java.io.File
import org.jetbrains.kotlin.konan.file.File as KFile
@@ -92,13 +94,36 @@ private val CompilerConfiguration.expectActualLinker: Boolean
class KotlinFileSerializedData(val metadata: ByteArray, val irData: SerializedIrFile)
private fun IrMessageLogger?.toResolverLogger(): Logger {
if (this == null) return DummyLogger
return object : Logger {
override fun log(message: String) {
report(IrMessageLogger.Severity.INFO, message, null)
}
override fun error(message: String) {
report(IrMessageLogger.Severity.ERROR, message, null)
}
override fun warning(message: String) {
report(IrMessageLogger.Severity.WARNING, message, null)
}
override fun fatal(message: String): Nothing {
report(IrMessageLogger.Severity.ERROR, message, null)
kotlin.error("FATAL ERROR: $message")
}
}
}
fun generateKLib(
project: Project,
files: List<KtFile>,
analyzer: AbstractAnalyzerWithCompilerReport,
configuration: CompilerConfiguration,
allDependencies: KotlinLibraryResolveResult,
friendDependencies: List<KotlinLibrary>,
dependencies: Collection<String>,
friendDependencies: Collection<String>,
irFactory: IrFactory,
outputKlibPath: String,
nopack: Boolean,
@@ -141,8 +166,8 @@ fun generateKLib(
}
val depsDescriptors =
ModulesStructure(project, MainModule.SourceFiles(files), analyzer, configuration, allDependencies, friendDependencies)
ModulesStructure(project, MainModule.SourceFiles(files), analyzer, configuration, dependencies, friendDependencies)
val allDependencies = depsDescriptors.allDependencies
val (psi2IrContext, hasErrors) = runAnalysisAndPreparePsi2Ir(depsDescriptors, irFactory, errorPolicy)
val irBuiltIns = psi2IrContext.irBuiltIns
val functionFactory = IrFunctionFactory(irBuiltIns, psi2IrContext.symbolTable)
@@ -162,7 +187,7 @@ fun generateKLib(
serializedIrFiles?.let { ICData(it, errorPolicy.allowErrors) }
)
sortDependencies(allDependencies.getFullList(), depsDescriptors.descriptors).map {
sortDependencies(allDependencies, depsDescriptors.descriptors).map {
irLinker.deserializeOnlyHeaderModule(depsDescriptors.getModuleDescriptor(it), it)
}
@@ -190,7 +215,7 @@ fun generateKLib(
psi2IrContext.bindingContext,
files,
outputKlibPath,
allDependencies.getFullList(),
allDependencies.map { it.library },
moduleFragment,
expectDescriptorToSymbol,
icData,
@@ -211,8 +236,9 @@ data class IrModuleInfo(
val moduleFragmentToUniqueName: Map<IrModuleFragment, String>,
)
private fun sortDependencies(dependencies: List<KotlinLibrary>, mapping: Map<KotlinLibrary, ModuleDescriptor>): Collection<KotlinLibrary> {
private fun sortDependencies(resolvedDependencies: List<KotlinResolvedLibrary>, mapping: Map<KotlinLibrary, ModuleDescriptor>): Collection<KotlinLibrary> {
val m2l = mapping.map { it.value to it.key }.toMap()
val dependencies = resolvedDependencies.map { it.library }
return DFS.topologicalOrder(dependencies) { m ->
val descriptor = mapping[m] ?: error("No descriptor found for library ${m.libraryName}")
@@ -225,14 +251,15 @@ fun loadIr(
mainModule: MainModule,
analyzer: AbstractAnalyzerWithCompilerReport,
configuration: CompilerConfiguration,
allDependencies: KotlinLibraryResolveResult,
friendDependencies: List<KotlinLibrary>,
dependencies: Collection<String>,
friendDependencies: Collection<String>,
irFactory: IrFactory,
verifySignatures: Boolean
): IrModuleInfo {
val depsDescriptors = ModulesStructure(project, mainModule, analyzer, configuration, allDependencies, friendDependencies)
val depsDescriptors = ModulesStructure(project, mainModule, analyzer, configuration, dependencies, friendDependencies)
val errorPolicy = configuration.get(JSConfigurationKeys.ERROR_TOLERANCE_POLICY) ?: ErrorTolerancePolicy.DEFAULT
val messageLogger = configuration.get(IrMessageLogger.IR_MESSAGE_LOGGER) ?: IrMessageLogger.None
val allDependencies = depsDescriptors.allDependencies
when (mainModule) {
is MainModule.SourceFiles -> {
@@ -247,7 +274,7 @@ fun loadIr(
val moduleFragmentToUniqueName = mutableMapOf<IrModuleFragment, String>()
val irLinker =
JsIrLinker(psi2IrContext.moduleDescriptor, messageLogger, irBuiltIns, symbolTable, functionFactory, feContext, null)
val deserializedModuleFragments = sortDependencies(allDependencies.getFullList(), depsDescriptors.descriptors).map { klib ->
val deserializedModuleFragments = sortDependencies(allDependencies, depsDescriptors.descriptors).map { klib ->
irLinker.deserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(klib), klib).also { moduleFragment ->
klib.manifestProperties.getProperty(KLIB_PROPERTY_JS_OUTPUT_NAME)?.let {
moduleFragmentToUniqueName[moduleFragment] = it
@@ -276,7 +303,9 @@ fun loadIr(
return IrModuleInfo(moduleFragment, deserializedModuleFragments, irBuiltIns, symbolTable, irLinker, moduleFragmentToUniqueName)
}
is MainModule.Klib -> {
val moduleDescriptor = depsDescriptors.getModuleDescriptor(mainModule.lib)
val mainModuleLib = depsDescriptors.allDependencies.find { it.library.libraryFile.canonicalPath == mainModule.libPath }?.library
?: error("No module with ${mainModule.libPath} found")
val moduleDescriptor = depsDescriptors.getModuleDescriptor(mainModuleLib)
val mangler = JsManglerDesc
val signaturer = IdSignatureDescriptor(mangler)
val symbolTable = SymbolTable(signaturer, irFactory)
@@ -289,9 +318,9 @@ fun loadIr(
val moduleFragmentToUniqueName = mutableMapOf<IrModuleFragment, String>()
val deserializedModuleFragments = sortDependencies(allDependencies.getFullList(), depsDescriptors.descriptors).map { klib ->
val deserializedModuleFragments = sortDependencies(allDependencies, depsDescriptors.descriptors).map { klib ->
val strategy =
if (klib == mainModule.lib)
if (klib == mainModuleLib)
DeserializationStrategy.ALL
else
DeserializationStrategy.EXPLICITLY_EXPORTED
@@ -389,7 +418,7 @@ fun getModuleDescriptorByLibrary(current: KotlinLibrary, mapping: Map<String, Mo
sealed class MainModule {
class SourceFiles(val files: List<KtFile>) : MainModule()
class Klib(val lib: KotlinLibrary) : MainModule()
class Klib(val libPath: String) : MainModule()
}
private class ModulesStructure(
@@ -397,17 +426,30 @@ private class ModulesStructure(
private val mainModule: MainModule,
private val analyzer: AbstractAnalyzerWithCompilerReport,
val compilerConfiguration: CompilerConfiguration,
val allDependencies: KotlinLibraryResolveResult,
private val friendDependencies: List<KotlinLibrary>
dependencies: Collection<String>,
friendDependenciesPaths: Collection<String>
) {
val allDependencies = jsResolveLibraries(
dependencies,
compilerConfiguration[JSConfigurationKeys.REPOSITORIES] ?: emptyList(),
compilerConfiguration[IrMessageLogger.IR_MESSAGE_LOGGER].toResolverLogger()
).getFullResolvedList()
val friendDependencies = allDependencies.run {
val friendAbsolutePaths = friendDependenciesPaths.map { File(it).canonicalPath }
filter {
it.library.libraryFile.absolutePath in friendAbsolutePaths
}
}
val moduleDependencies: Map<KotlinLibrary, List<KotlinLibrary>> = run {
val transitives = allDependencies.getFullResolvedList()
val transitives = allDependencies
transitives.associate { klib ->
klib.library to klib.resolvedDependencies.map { d -> d.library }
}.toMap()
}
val builtInsDep = allDependencies.getFullList().find { it.isBuiltIns }
val builtInsDep = allDependencies.find { it.library.isBuiltIns }
class JsFrontEndResult(val moduleDescriptor: ModuleDescriptor, val bindingContext: BindingContext, val hasErrors: Boolean)
@@ -420,8 +462,8 @@ private class ModulesStructure(
files,
project,
compilerConfiguration,
allDependencies.getFullList().map { getModuleDescriptor(it) },
friendDependencies.map { getModuleDescriptor(it) },
allDependencies.map { getModuleDescriptor(it.library) },
friendDependencies.map { getModuleDescriptor(it.library) },
analyzer.targetEnvironment,
thisIsBuiltInsModule = builtInModuleDescriptor == null,
customBuiltInsModule = builtInModuleDescriptor
@@ -477,7 +519,7 @@ private class ModulesStructure(
val builtInModuleDescriptor =
if (builtInsDep != null)
getModuleDescriptor(builtInsDep)
getModuleDescriptor(builtInsDep.library)
else
null // null in case compiling builtInModule itself
}