[JS IR BE] Migrate JS BE to common klib utils
This commit is contained in:
@@ -225,6 +225,8 @@ extra["compilerModules"] = arrayOf(
|
||||
":compiler:backend.js",
|
||||
":compiler:ir.serialization.common",
|
||||
":compiler:ir.serialization.js",
|
||||
":kotlin-util-io",
|
||||
":kotlin-util-klib",
|
||||
":compiler:backend-common",
|
||||
":compiler:backend",
|
||||
":compiler:plugin-api",
|
||||
|
||||
+5
@@ -114,6 +114,11 @@ class K2JSCompilerArguments : CommonCompilerArguments() {
|
||||
)
|
||||
var irProduceOnly: String? by NullableStringFreezableVar(null)
|
||||
|
||||
@Argument(
|
||||
value = "-Xir-legacy-gradle-plugin-compatibility",
|
||||
description = "Make KLIB generation compatible with legacy gradle plugin"
|
||||
)
|
||||
var irLegacyGradlePluginCompatimbility: Boolean by FreezableVar(false)
|
||||
|
||||
@GradleOption(DefaultValues.BooleanTrueDefault::class)
|
||||
@Argument(value = "-Xtyped-arrays", description = "Translate primitive arrays to JS typed arrays")
|
||||
|
||||
@@ -28,14 +28,12 @@ import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider
|
||||
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer
|
||||
import org.jetbrains.kotlin.ir.backend.js.KlibModuleRef
|
||||
import org.jetbrains.kotlin.ir.backend.js.compile
|
||||
import org.jetbrains.kotlin.ir.backend.js.generateKLib
|
||||
import org.jetbrains.kotlin.ir.backend.js.jsPhases
|
||||
import org.jetbrains.kotlin.ir.backend.js.*
|
||||
import org.jetbrains.kotlin.js.config.EcmaVersion
|
||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||
import org.jetbrains.kotlin.js.config.JsConfig
|
||||
import org.jetbrains.kotlin.js.config.SourceMapSourceEmbedding
|
||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
||||
@@ -44,7 +42,6 @@ import org.jetbrains.kotlin.utils.KotlinPaths
|
||||
import org.jetbrains.kotlin.utils.join
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.util.zip.ZipFile
|
||||
|
||||
enum class ProduceKind {
|
||||
DEFAULT, // Determine what to produce based on js-v1 options
|
||||
@@ -61,68 +58,6 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
return K2JSCompilerArguments()
|
||||
}
|
||||
|
||||
private fun extractKlibFromZip(library: String, messageCollector: MessageCollector): File? {
|
||||
val zipLib = ZipFile(library)
|
||||
val tempDir = createTempDir(File(library).name, "klibjar")
|
||||
tempDir.deleteOnExit()
|
||||
var extractedKlibDir: File? = null
|
||||
for (entry in zipLib.entries()) {
|
||||
if (!entry.isDirectory) {
|
||||
zipLib.getInputStream(entry).use { input ->
|
||||
val outputEntryFile = File(tempDir, entry.name)
|
||||
outputEntryFile.parentFile.mkdirs()
|
||||
outputEntryFile.outputStream().use { output ->
|
||||
input.copyTo(output)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (entry.name.endsWith("KLIB/")) {
|
||||
extractedKlibDir = File(tempDir, entry.name)
|
||||
messageCollector.report(INFO, "Klib $library is extracted into $extractedKlibDir")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return extractedKlibDir
|
||||
}
|
||||
|
||||
private fun loadIrLibrary(library: String, messageCollector: MessageCollector): KlibModuleRef? {
|
||||
val libraryFile = File(library)
|
||||
var klibDir = when {
|
||||
FileUtil.isJarOrZip(libraryFile) -> {
|
||||
extractKlibFromZip(library, messageCollector) ?: return null
|
||||
}
|
||||
!libraryFile.isDirectory -> {
|
||||
messageCollector.report(ERROR, "Klib $library must be a directory")
|
||||
return null
|
||||
}
|
||||
else ->
|
||||
libraryFile
|
||||
}
|
||||
|
||||
var klibFiles = klibDir.listFiles()
|
||||
if (klibFiles.isEmpty()) {
|
||||
messageCollector.report(STRONG_WARNING, "Klib $library directory is empty")
|
||||
return null
|
||||
}
|
||||
|
||||
// Sometines gradle gives us a directory with klib directory inside
|
||||
val klibDirInsideDir = klibFiles.find { it.name.endsWith("KLIB") }
|
||||
if (klibDirInsideDir != null) {
|
||||
klibDir = klibDirInsideDir
|
||||
klibFiles = klibDir.listFiles()
|
||||
}
|
||||
|
||||
val metadataFile = klibFiles.find { it.extension == "klm" }
|
||||
|
||||
if (metadataFile == null) {
|
||||
messageCollector.report(STRONG_WARNING, "No metadata file (.klm) for klib: $klibDir")
|
||||
return null
|
||||
}
|
||||
|
||||
return KlibModuleRef(metadataFile.nameWithoutExtension, klibDir.absolutePath)
|
||||
}
|
||||
|
||||
override fun doExecute(
|
||||
arguments: K2JSCompilerArguments,
|
||||
configuration: CompilerConfiguration,
|
||||
@@ -144,7 +79,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
arguments.pluginOptions,
|
||||
configuration
|
||||
)
|
||||
if (pluginLoadResult != ExitCode.OK) return pluginLoadResult
|
||||
if (pluginLoadResult != OK) return pluginLoadResult
|
||||
|
||||
val libraries: List<String> = configureLibraries(arguments.libraries)
|
||||
val friendLibraries: List<String> = configureLibraries(arguments.friendModules)
|
||||
@@ -204,11 +139,11 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
val mainCallArguments = if (K2JsArgumentConstants.NO_CALL == arguments.main) null else emptyList<String>()
|
||||
|
||||
val loadedLibrariesNames = mutableSetOf<String>()
|
||||
val dependencies = mutableListOf<KlibModuleRef>()
|
||||
val friendDependencies = mutableListOf<KlibModuleRef>()
|
||||
val dependencies = mutableListOf<KotlinLibrary>()
|
||||
val friendDependencies = mutableListOf<KotlinLibrary>()
|
||||
|
||||
for (library in libraries) {
|
||||
val irLib = loadIrLibrary(library, messageCollector) ?: continue
|
||||
val irLib = loadKlib(library)
|
||||
if (irLib.moduleName !in loadedLibrariesNames) {
|
||||
dependencies.add(irLib)
|
||||
loadedLibrariesNames.add(irLib.moduleName)
|
||||
@@ -223,6 +158,24 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
messageCollector.report(ERROR, "Unknown produce kind: ${arguments.irProduceOnly}. Valid values are: js, klib")
|
||||
}
|
||||
|
||||
if (produceKind == ProduceKind.KLIB || (produceKind == ProduceKind.DEFAULT && arguments.metaInfo)) {
|
||||
val outputKlibPath =
|
||||
if (arguments.irLegacyGradlePluginCompatimbility)
|
||||
File(outputFilePath).parent
|
||||
else
|
||||
"$outputFilePath.klib"
|
||||
|
||||
generateKLib(
|
||||
project = config.project,
|
||||
files = sourcesFiles,
|
||||
configuration = config.configuration,
|
||||
allDependencies = dependencies,
|
||||
friendDependencies = friendDependencies,
|
||||
outputKlibPath = outputKlibPath,
|
||||
nopack = arguments.irLegacyGradlePluginCompatimbility
|
||||
)
|
||||
}
|
||||
|
||||
if (produceKind == ProduceKind.JS || produceKind == ProduceKind.DEFAULT) {
|
||||
val phaseConfig = createPhaseConfig(jsPhases, arguments, messageCollector)
|
||||
|
||||
@@ -231,7 +184,6 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
sourcesFiles,
|
||||
configuration,
|
||||
phaseConfig,
|
||||
immediateDependencies = dependencies,
|
||||
allDependencies = dependencies,
|
||||
friendDependencies = friendDependencies,
|
||||
mainArguments = mainCallArguments
|
||||
@@ -240,19 +192,6 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
outputFile.writeText(compiledModule)
|
||||
}
|
||||
|
||||
if (produceKind == ProduceKind.KLIB || (produceKind == ProduceKind.DEFAULT && arguments.metaInfo)) {
|
||||
val outputKlibPath = "$outputFilePath.KLIB"
|
||||
generateKLib(
|
||||
project = config.project,
|
||||
files = sourcesFiles,
|
||||
configuration = config.configuration,
|
||||
immediateDependencies = dependencies,
|
||||
allDependencies = dependencies,
|
||||
friendDependencies = friendDependencies,
|
||||
outputKlibPath = outputKlibPath
|
||||
)
|
||||
}
|
||||
|
||||
return OK
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransf
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.JsMainFunctionDetector
|
||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
fun compile(
|
||||
@@ -20,13 +21,12 @@ fun compile(
|
||||
files: List<KtFile>,
|
||||
configuration: CompilerConfiguration,
|
||||
phaseConfig: PhaseConfig,
|
||||
immediateDependencies: List<KlibModuleRef>,
|
||||
allDependencies: List<KlibModuleRef>,
|
||||
friendDependencies: List<KlibModuleRef>,
|
||||
allDependencies: List<KotlinLibrary>,
|
||||
friendDependencies: List<KotlinLibrary>,
|
||||
mainArguments: List<String>?
|
||||
): String {
|
||||
val (moduleFragment, dependencyModules, irBuiltIns, symbolTable, deserializer) =
|
||||
loadIr(project, files, configuration, immediateDependencies, allDependencies, friendDependencies)
|
||||
loadIr(project, files, configuration, allDependencies, friendDependencies)
|
||||
|
||||
val moduleDescriptor = moduleFragment.descriptor
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ dependencies {
|
||||
// TODO: decouple from backend.common
|
||||
compile(project(":compiler:ir.backend.common"))
|
||||
compile(project(":compiler:ir.tree"))
|
||||
compile(project(":kotlin-util-klib"))
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
|
||||
+1
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.LoggingContext
|
||||
import org.jetbrains.kotlin.backend.common.ir.ir2string
|
||||
import org.jetbrains.kotlin.backend.common.library.CombinedIrFileWriter
|
||||
import org.jetbrains.kotlin.backend.common.library.DeclarationId
|
||||
import org.jetbrains.kotlin.library.SerializedIr
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind.*
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.common.serialization
|
||||
|
||||
class SerializedIr (
|
||||
val module: ByteArray,
|
||||
val combinedDeclarationFilePath: String
|
||||
)
|
||||
@@ -159,7 +159,7 @@ val generateFullRuntimeKLib by task<NoDebugJavaExec> {
|
||||
|
||||
buildKLib(sources = listOf(fullRuntimeSources.outputs.files.singleFile.path),
|
||||
dependencies = emptyList(),
|
||||
outPath = "$buildDir/fullRuntime/klib/JS_IR_RUNTIME.klm",
|
||||
outPath = "$buildDir/fullRuntime/klib",
|
||||
commonSources = listOf("common", "src", "unsigned").map { "$buildDir/fullRuntime/src/libraries/stdlib/$it" }
|
||||
)
|
||||
}
|
||||
@@ -169,7 +169,7 @@ val generateReducedRuntimeKLib by task<NoDebugJavaExec> {
|
||||
|
||||
buildKLib(sources = listOf(reducedRuntimeSources.outputs.files.singleFile.path),
|
||||
dependencies = emptyList(),
|
||||
outPath = "$buildDir/reducedRuntime/klib/JS_IR_RUNTIME.klm",
|
||||
outPath = "$buildDir/reducedRuntime/klib",
|
||||
commonSources = listOf("common", "src", "unsigned").map { "$buildDir/reducedRuntime/src/libraries/stdlib/$it" }
|
||||
)
|
||||
}
|
||||
@@ -183,8 +183,8 @@ val generateKotlinTestKLib by task<NoDebugJavaExec> {
|
||||
|
||||
buildKLib(
|
||||
sources = listOf("$rootDir/libraries/kotlin.test/js/src/main") + kotlinTestCommonSources,
|
||||
dependencies = listOf("${generateFullRuntimeKLib.outputs.files.singleFile.path}/JS_IR_RUNTIME.klm"),
|
||||
outPath = "$buildDir/kotlin.test/klib/kotlin.test.klm",
|
||||
dependencies = listOf("${generateFullRuntimeKLib.outputs.files.singleFile.path}/klib"),
|
||||
outPath = "$buildDir/kotlin.test/klib",
|
||||
commonSources = kotlinTestCommonSources
|
||||
)
|
||||
}
|
||||
|
||||
@@ -7,25 +7,22 @@ package org.jetbrains.kotlin.ir.backend.js
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.backend.common.LoggingContext
|
||||
import org.jetbrains.kotlin.backend.common.serialization.DescriptorTable
|
||||
import org.jetbrains.kotlin.library.impl.buildKoltinLibrary
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.functions.functionInterfacePackageFragmentProvider
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider
|
||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.backend.common.serialization.DescriptorTable
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsDeclarationTable
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrModuleSerializer
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.newJsDescriptorUniqId
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.JsKlibMetadataModuleDescriptor
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.JsKlibMetadataSerializationUtil
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.JsKlibMetadataVersion
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.createJsKlibMetadataPackageFragmentProvider
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
@@ -34,6 +31,11 @@ import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS
|
||||
import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult
|
||||
import org.jetbrains.kotlin.konan.KonanVersionImpl
|
||||
import org.jetbrains.kotlin.konan.MetaVersion
|
||||
import org.jetbrains.kotlin.konan.properties.propertyList
|
||||
import org.jetbrains.kotlin.library.*
|
||||
import org.jetbrains.kotlin.library.impl.createKotlinLibrary
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
@@ -44,28 +46,30 @@ import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.utils.DFS
|
||||
import java.io.File
|
||||
import java.nio.file.Files.move
|
||||
import java.nio.file.Paths
|
||||
import java.nio.file.StandardCopyOption
|
||||
import org.jetbrains.kotlin.konan.file.File as KFile
|
||||
|
||||
data class KlibModuleRef(
|
||||
val moduleName: String,
|
||||
val klibPath: String
|
||||
)
|
||||
|
||||
internal val JS_KLIBRARY_CAPABILITY = ModuleDescriptor.Capability<File>("JS KLIBRARY")
|
||||
internal val moduleHeaderFileName = "module.kji"
|
||||
internal val declarationsDirName = "ir/"
|
||||
val KotlinLibrary.moduleName: String
|
||||
get() = manifestProperties.getProperty(KLIB_PROPERTY_UNIQUE_NAME)
|
||||
|
||||
// Considering library built-ins if it has no dependencies.
|
||||
// All non-built-ins libraries must have built-ins as a dependency.
|
||||
val KotlinLibrary.isBuiltIns: Boolean
|
||||
get() = manifestProperties
|
||||
.propertyList(KLIB_PROPERTY_DEPENDS, escapeInQuotes = true)
|
||||
.isEmpty()
|
||||
|
||||
fun loadKlib(klibPath: String) =
|
||||
createKotlinLibrary(KFile(KFile(klibPath).absolutePath))
|
||||
|
||||
internal val JS_KLIBRARY_CAPABILITY = ModuleDescriptor.Capability<KotlinLibrary>("JS KLIBRARY")
|
||||
|
||||
private val emptyLoggingContext = object : LoggingContext {
|
||||
override var inVerbosePhase = false
|
||||
|
||||
override fun log(message: () -> String) {}
|
||||
}
|
||||
|
||||
private fun metadataFileName(moduleName: String) = "$moduleName.${JsKlibMetadataSerializationUtil.CLASS_METADATA_FILE_EXTENSION}"
|
||||
|
||||
private val CompilerConfiguration.metadataVersion
|
||||
get() = get(CommonConfigurationKeys.METADATA_VERSION) as? JsKlibMetadataVersion ?: JsKlibMetadataVersion.INSTANCE
|
||||
|
||||
@@ -73,12 +77,12 @@ fun generateKLib(
|
||||
project: Project,
|
||||
files: List<KtFile>,
|
||||
configuration: CompilerConfiguration,
|
||||
immediateDependencies: List<KlibModuleRef>,
|
||||
allDependencies: List<KlibModuleRef>,
|
||||
friendDependencies: List<KlibModuleRef>,
|
||||
outputKlibPath: String
|
||||
): KlibModuleRef {
|
||||
val depsDescriptors = ModulesStructure(project, files, configuration, immediateDependencies, allDependencies, friendDependencies)
|
||||
allDependencies: List<KotlinLibrary>,
|
||||
friendDependencies: List<KotlinLibrary>,
|
||||
outputKlibPath: String,
|
||||
nopack: Boolean
|
||||
) {
|
||||
val depsDescriptors = ModulesStructure(project, files, configuration, allDependencies, friendDependencies)
|
||||
|
||||
val psi2IrContext = runAnalysisAndPreparePsi2Ir(depsDescriptors)
|
||||
|
||||
@@ -94,11 +98,10 @@ fun generateKLib(
|
||||
configuration.languageVersionSettings,
|
||||
psi2IrContext.bindingContext,
|
||||
outputKlibPath,
|
||||
immediateDependencies,
|
||||
moduleFragment
|
||||
allDependencies,
|
||||
moduleFragment,
|
||||
nopack
|
||||
)
|
||||
|
||||
return KlibModuleRef(moduleName, outputKlibPath)
|
||||
}
|
||||
|
||||
data class IrModuleInfo(
|
||||
@@ -113,11 +116,10 @@ fun loadIr(
|
||||
project: Project,
|
||||
files: List<KtFile>,
|
||||
configuration: CompilerConfiguration,
|
||||
immediateDependencies: List<KlibModuleRef>,
|
||||
allDependencies: List<KlibModuleRef>,
|
||||
friendDependencies: List<KlibModuleRef>
|
||||
allDependencies: List<KotlinLibrary>,
|
||||
friendDependencies: List<KotlinLibrary>
|
||||
): IrModuleInfo {
|
||||
val depsDescriptors = ModulesStructure(project, files, configuration, immediateDependencies, allDependencies, friendDependencies)
|
||||
val depsDescriptors = ModulesStructure(project, files, configuration, allDependencies, friendDependencies)
|
||||
|
||||
val psi2IrContext = runAnalysisAndPreparePsi2Ir(depsDescriptors)
|
||||
|
||||
@@ -127,7 +129,7 @@ fun loadIr(
|
||||
|
||||
val deserializer = JsIrLinker(moduleDescriptor, emptyLoggingContext, irBuiltIns, symbolTable)
|
||||
|
||||
val deserializedModuleFragments = depsDescriptors.sortedImmediateDependencies.map {
|
||||
val deserializedModuleFragments = allDependencies.map {
|
||||
deserializer.deserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(it))!!
|
||||
}
|
||||
|
||||
@@ -154,16 +156,16 @@ private fun GeneratorContext.generateModuleFragment(files: List<KtFile>, deseria
|
||||
|
||||
|
||||
private fun loadKlibMetadataParts(
|
||||
moduleId: KlibModuleRef
|
||||
moduleId: KotlinLibrary
|
||||
): JsKlibMetadataParts {
|
||||
val metadataFile = File(moduleId.klibPath, metadataFileName(moduleId.moduleName))
|
||||
val serializer = JsKlibMetadataSerializationUtil
|
||||
return serializer.readModuleAsProto(metadataFile.readBytes())
|
||||
return JsKlibMetadataSerializationUtil.readModuleAsProto(moduleId.moduleHeaderData)
|
||||
}
|
||||
|
||||
val ModuleDescriptor.kotlinLibrary get() = this.getCapability(JS_KLIBRARY_CAPABILITY)!!
|
||||
|
||||
private fun loadKlibMetadata(
|
||||
parts: JsKlibMetadataParts,
|
||||
moduleId: KlibModuleRef,
|
||||
moduleId: KotlinLibrary,
|
||||
isBuiltIn: Boolean,
|
||||
lookupTracker: LookupTracker,
|
||||
storageManager: LockBasedStorageManager,
|
||||
@@ -178,7 +180,7 @@ private fun loadKlibMetadata(
|
||||
Name.special("<${moduleId.moduleName}>"),
|
||||
storageManager,
|
||||
builtIns,
|
||||
capabilities = mapOf(JS_KLIBRARY_CAPABILITY to File(moduleId.klibPath))
|
||||
capabilities = mapOf(JS_KLIBRARY_CAPABILITY to moduleId)
|
||||
)
|
||||
if (isBuiltIn) builtIns.builtInsModule = md
|
||||
val currentModuleFragmentProvider = createJsKlibMetadataPackageFragmentProvider(
|
||||
@@ -203,26 +205,21 @@ private class ModulesStructure(
|
||||
private val project: Project,
|
||||
private val files: List<KtFile>,
|
||||
val compilerConfiguration: CompilerConfiguration,
|
||||
immediateDependencies: List<KlibModuleRef>,
|
||||
private val allDependencies: List<KlibModuleRef>,
|
||||
private val friendDependencies: List<KlibModuleRef>
|
||||
private val allDependencies: List<KotlinLibrary>,
|
||||
private val friendDependencies: List<KotlinLibrary>
|
||||
) {
|
||||
private val deserializedModuleParts: Map<KlibModuleRef, JsKlibMetadataParts> =
|
||||
private val deserializedModuleParts: Map<KotlinLibrary, JsKlibMetadataParts> =
|
||||
allDependencies.associateWith { loadKlibMetadataParts(it) }
|
||||
|
||||
fun findModuleByName(name: String): KlibModuleRef =
|
||||
fun findModuleByName(name: String): KotlinLibrary =
|
||||
allDependencies.find { it.moduleName == name } ?: error("Module is not found: $name")
|
||||
|
||||
val moduleDependencies: Map<KlibModuleRef, List<KlibModuleRef>> =
|
||||
val moduleDependencies: Map<KotlinLibrary, List<KotlinLibrary>> =
|
||||
deserializedModuleParts.mapValues { (_, parts) ->
|
||||
parts.importedModules.map(::findModuleByName)
|
||||
}
|
||||
|
||||
val sortedImmediateDependencies: List<KlibModuleRef> =
|
||||
DFS.topologicalOrder(immediateDependencies) { moduleDependencies.getValue(it) }
|
||||
.reversed()
|
||||
|
||||
val builtInsDep = sortedImmediateDependencies.firstOrNull()
|
||||
val builtInsDep = allDependencies.find { it.isBuiltIns }
|
||||
|
||||
fun runAnalysis(): JsAnalysisResult {
|
||||
val analysisResult =
|
||||
@@ -230,7 +227,7 @@ private class ModulesStructure(
|
||||
files,
|
||||
project,
|
||||
compilerConfiguration,
|
||||
sortedImmediateDependencies.map { getModuleDescriptor(it) },
|
||||
allDependencies.map { getModuleDescriptor(it) },
|
||||
friendModuleDescriptors = friendDependencies.map { getModuleDescriptor(it) },
|
||||
thisIsBuiltInsModule = builtInModuleDescriptor == null,
|
||||
customBuiltInsModule = builtInModuleDescriptor
|
||||
@@ -249,9 +246,9 @@ private class ModulesStructure(
|
||||
private val storageManager: LockBasedStorageManager = LockBasedStorageManager("ModulesStructure")
|
||||
private var runtimeModule: ModuleDescriptorImpl? = null
|
||||
|
||||
private val descriptors = mutableMapOf<KlibModuleRef, ModuleDescriptorImpl>()
|
||||
private val descriptors = mutableMapOf<KotlinLibrary, ModuleDescriptorImpl>()
|
||||
|
||||
fun getModuleDescriptor(current: KlibModuleRef): ModuleDescriptorImpl = descriptors.getOrPut(current) {
|
||||
fun getModuleDescriptor(current: KotlinLibrary): ModuleDescriptorImpl = descriptors.getOrPut(current) {
|
||||
val parts = loadKlibMetadataParts(current)
|
||||
val isBuiltIns = parts.importedModules.isEmpty()
|
||||
loadKlibMetadata(
|
||||
@@ -282,8 +279,9 @@ fun serializeModuleIntoKlib(
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
bindingContext: BindingContext,
|
||||
klibPath: String,
|
||||
dependencies: List<KlibModuleRef>,
|
||||
moduleFragment: IrModuleFragment
|
||||
dependencies: List<KotlinLibrary>,
|
||||
moduleFragment: IrModuleFragment,
|
||||
nopack: Boolean
|
||||
) {
|
||||
val declarationTable = JsDeclarationTable(moduleFragment.irBuiltins, DescriptorTable())
|
||||
|
||||
@@ -292,7 +290,7 @@ fun serializeModuleIntoKlib(
|
||||
|
||||
val moduleDescription =
|
||||
JsKlibMetadataModuleDescriptor(moduleName, dependencies.map { it.moduleName }, moduleFragment.descriptor)
|
||||
val serializedData = serializer.serializeMetadata(
|
||||
val serializedMetadata = serializer.serializeMetadata(
|
||||
bindingContext,
|
||||
moduleDescription,
|
||||
languageVersionSettings,
|
||||
@@ -302,19 +300,21 @@ fun serializeModuleIntoKlib(
|
||||
index?.let { newJsDescriptorUniqId(it) }
|
||||
}
|
||||
|
||||
val klibDir = File(klibPath).also {
|
||||
it.deleteRecursively()
|
||||
it.mkdirs()
|
||||
}
|
||||
val abiVersion = KotlinAbiVersion.CURRENT
|
||||
val compilerVersion = KonanVersionImpl(MetaVersion.DEV, 1, 3, 0, -1)
|
||||
val libraryVersion = "JSIR"
|
||||
|
||||
val moduleFile = File(klibDir, moduleHeaderFileName)
|
||||
moduleFile.writeBytes(serializedIr.module)
|
||||
val versions = KonanLibraryVersioning(abiVersion = abiVersion, libraryVersion = libraryVersion, compilerVersion = compilerVersion)
|
||||
|
||||
val irDeclarationDir = File(klibDir, declarationsDirName).also { it.mkdir() }
|
||||
val irCombinedFile = File(irDeclarationDir, "irCombined.knd")
|
||||
move(Paths.get(serializedIr.combinedDeclarationFilePath), Paths.get(irCombinedFile.path), StandardCopyOption.REPLACE_EXISTING)
|
||||
|
||||
File(klibDir, "${moduleDescription.name}.${JsKlibMetadataSerializationUtil.CLASS_METADATA_FILE_EXTENSION}").also {
|
||||
it.writeBytes(serializedData.asByteArray())
|
||||
}
|
||||
buildKoltinLibrary(
|
||||
linkDependencies = dependencies,
|
||||
ir = serializedIr,
|
||||
metadata = serializedMetadata,
|
||||
dataFlowGraph = null,
|
||||
manifestProperties = null,
|
||||
moduleName = moduleName,
|
||||
nopack = nopack,
|
||||
output = klibPath,
|
||||
versions = versions
|
||||
)
|
||||
}
|
||||
|
||||
-1
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.serialization.DescriptorReferenceDeserializer
|
||||
import org.jetbrains.kotlin.backend.common.serialization.DescriptorUniqIdAware
|
||||
import org.jetbrains.kotlin.backend.common.serialization.UniqId
|
||||
import org.jetbrains.kotlin.backend.common.serialization.UniqIdKey
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
|
||||
+5
-15
@@ -6,29 +6,23 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.LoggingContext
|
||||
import org.jetbrains.kotlin.backend.common.library.CombinedIrFileReader
|
||||
import org.jetbrains.kotlin.backend.common.library.DeclarationId
|
||||
import org.jetbrains.kotlin.backend.common.serialization.*
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.ir.backend.js.JS_KLIBRARY_CAPABILITY
|
||||
import org.jetbrains.kotlin.ir.backend.js.moduleHeaderFileName
|
||||
import org.jetbrains.kotlin.ir.backend.js.kotlinLibrary
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import java.io.File
|
||||
|
||||
class JsIrLinker(
|
||||
currentModule: ModuleDescriptor,
|
||||
logger: LoggingContext,
|
||||
builtIns: IrBuiltIns,
|
||||
symbolTable: SymbolTable
|
||||
) : KotlinIrLinker(logger, builtIns, symbolTable, emptyList<ModuleDescriptor>(), null, 0x1_0000_0000L),
|
||||
) : KotlinIrLinker(logger, builtIns, symbolTable, emptyList(), null, 0x1_0000_0000L),
|
||||
DescriptorUniqIdAware by JsDescriptorUniqIdAware {
|
||||
|
||||
private val FUNCTION_INDEX_START: Long = indexAfterKnownBuiltins
|
||||
|
||||
val moduleToReaderMap = mutableMapOf<ModuleDescriptor, CombinedIrFileReader>()
|
||||
|
||||
override fun getPrimitiveTypeOrNull(symbol: IrClassifierSymbol, hasQuestionMark: Boolean) =
|
||||
builtIns.getPrimitiveTypeOrNullByDescriptor(symbol.descriptor, hasQuestionMark)
|
||||
|
||||
@@ -36,15 +30,11 @@ class JsIrLinker(
|
||||
JsDescriptorReferenceDeserializer(currentModule, builtIns, FUNCTION_INDEX_START)
|
||||
|
||||
override fun reader(moduleDescriptor: ModuleDescriptor, uniqId: UniqId): ByteArray {
|
||||
val irFileReader = moduleToReaderMap.getOrPut(moduleDescriptor) {
|
||||
val irFile = File(moduleDescriptor.getCapability(JS_KLIBRARY_CAPABILITY)!!, "ir/irCombined.knd")
|
||||
CombinedIrFileReader(irFile)
|
||||
}
|
||||
return irFileReader.declarationBytes(DeclarationId(uniqId.index, uniqId.isLocal))
|
||||
return moduleDescriptor.kotlinLibrary.irDeclaration(uniqId.index, uniqId.isLocal)
|
||||
}
|
||||
|
||||
override val ModuleDescriptor.irHeader: ByteArray? get() =
|
||||
this.getCapability(JS_KLIBRARY_CAPABILITY)?.let { File(it, moduleHeaderFileName).readBytes() }
|
||||
override val ModuleDescriptor.irHeader: ByteArray?
|
||||
get() = this.kotlinLibrary.irHeader
|
||||
|
||||
override fun declareForwardDeclarations() {
|
||||
// since for `knownBuiltIns` such as FunctionN it is possible to have unbound symbols after deserialization
|
||||
|
||||
+16
-79
@@ -5,10 +5,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata
|
||||
|
||||
import org.jetbrains.kotlin.config.AnalysisFlags
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.library.SerializedMetadata
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -21,27 +20,25 @@ import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.serialization.AnnotationSerializer
|
||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
||||
import org.jetbrains.kotlin.serialization.StringTableImpl
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.util.zip.GZIPInputStream
|
||||
import java.util.zip.GZIPOutputStream
|
||||
|
||||
object JsKlibMetadataSerializationUtil {
|
||||
const val CLASS_METADATA_FILE_EXTENSION: String = "klm"
|
||||
|
||||
fun serializeMetadata(
|
||||
bindingContext: BindingContext,
|
||||
jsDescriptor: JsKlibMetadataModuleDescriptor<ModuleDescriptor>,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
metadataVersion: JsKlibMetadataVersion,
|
||||
declarationTableHandler: ((DeclarationDescriptor) -> JsKlibMetadataProtoBuf.DescriptorUniqId?)
|
||||
declarationTableHandler: (DeclarationDescriptor) -> JsKlibMetadataProtoBuf.DescriptorUniqId?
|
||||
): SerializedMetadata {
|
||||
val libraryProto = JsKlibMetadataProtoBuf.Library.newBuilder()
|
||||
jsDescriptor.imported.forEach { libraryProto.addImportedModule(it) }
|
||||
|
||||
val serializedFragments = HashMap<FqName, ProtoBuf.PackageFragment>()
|
||||
val module = jsDescriptor.data
|
||||
val fragments = mutableListOf<List<ByteArray>>()
|
||||
val fragmentNames = mutableListOf<String>()
|
||||
|
||||
for (fqName in getPackagesFqNames(module).sortedBy { it.asString() }) {
|
||||
val fragment = serializeDescriptors(
|
||||
@@ -55,39 +52,14 @@ object JsKlibMetadataSerializationUtil {
|
||||
}
|
||||
}
|
||||
|
||||
return SerializedMetadata(serializedFragments, jsDescriptor, languageVersionSettings)
|
||||
}
|
||||
|
||||
class SerializedMetadata(
|
||||
private val serializedFragments: Map<FqName, ProtoBuf.PackageFragment>,
|
||||
private val jsDescriptor: JsKlibMetadataModuleDescriptor<ModuleDescriptor>,
|
||||
private val languageVersionSettings: LanguageVersionSettings
|
||||
) {
|
||||
|
||||
fun asByteArray(): ByteArray =
|
||||
ByteArrayOutputStream().apply {
|
||||
GZIPOutputStream(this).use { stream ->
|
||||
serializeHeader(
|
||||
jsDescriptor.data,
|
||||
packageFqName = null,
|
||||
languageVersionSettings = languageVersionSettings
|
||||
).writeDelimitedTo(stream)
|
||||
asLibrary().writeTo(stream)
|
||||
}
|
||||
}.toByteArray()
|
||||
|
||||
private fun asLibrary(): JsKlibMetadataProtoBuf.Library {
|
||||
jsDescriptor.imported
|
||||
val builder = JsKlibMetadataProtoBuf.Library.newBuilder()
|
||||
|
||||
jsDescriptor.imported.forEach { builder.addImportedModule(it) }
|
||||
|
||||
for ((_, fragment) in serializedFragments.entries.sortedBy { (fqName, _) -> fqName.asString() }) {
|
||||
builder.addPackageFragment(fragment)
|
||||
}
|
||||
|
||||
return builder.build()
|
||||
for ((fqName, fragment) in serializedFragments.entries.sortedBy { (fqName, _) -> fqName.asString() }) {
|
||||
libraryProto.addPackageFragment(fragment)
|
||||
fragments.add(listOf(fragment.toByteArray()))
|
||||
fragmentNames.add(fqName.asString())
|
||||
}
|
||||
|
||||
val libraryAsByteArray = libraryProto.build().toByteArray()
|
||||
return SerializedMetadata(libraryAsByteArray, fragments, fragmentNames)
|
||||
}
|
||||
|
||||
fun serializeDescriptors(
|
||||
@@ -174,38 +146,6 @@ object JsKlibMetadataSerializationUtil {
|
||||
private fun ProtoBuf.PackageFragment.isEmpty(): Boolean =
|
||||
class_Count == 0 && `package`.let { it.functionCount == 0 && it.propertyCount == 0 && it.typeAliasCount == 0 }
|
||||
|
||||
fun serializeHeader(
|
||||
module: ModuleDescriptor, packageFqName: FqName?, languageVersionSettings: LanguageVersionSettings
|
||||
): JsKlibMetadataProtoBuf.Header {
|
||||
val header = JsKlibMetadataProtoBuf.Header.newBuilder()
|
||||
|
||||
if (packageFqName != null) {
|
||||
header.packageFqName = packageFqName.asString()
|
||||
}
|
||||
|
||||
if (languageVersionSettings.isPreRelease()) {
|
||||
header.flags = 1
|
||||
}
|
||||
|
||||
val experimentalAnnotationFqNames = languageVersionSettings.getFlag(AnalysisFlags.experimental)
|
||||
if (experimentalAnnotationFqNames.isNotEmpty()) {
|
||||
val stringTable = StringTableImpl()
|
||||
for (fqName in experimentalAnnotationFqNames) {
|
||||
val descriptor = module.resolveClassByFqName(FqName(fqName), NoLookupLocation.FOR_ALREADY_TRACKED) ?: continue
|
||||
header.addAnnotation(ProtoBuf.Annotation.newBuilder().apply {
|
||||
id = stringTable.getFqNameIndex(descriptor)
|
||||
})
|
||||
}
|
||||
val (strings, qualifiedNames) = stringTable.buildProto()
|
||||
header.strings = strings
|
||||
header.qualifiedNames = qualifiedNames
|
||||
}
|
||||
|
||||
// TODO: write JS code binary version
|
||||
|
||||
return header.build()
|
||||
}
|
||||
|
||||
private fun getPackagesFqNames(module: ModuleDescriptor): Set<FqName> {
|
||||
return mutableSetOf<FqName>().apply {
|
||||
getSubPackagesFqNames(module.getPackage(FqName.ROOT), this)
|
||||
@@ -228,11 +168,8 @@ object JsKlibMetadataSerializationUtil {
|
||||
|
||||
@JvmStatic
|
||||
fun readModuleAsProto(metadata: ByteArray): JsKlibMetadataParts {
|
||||
val (header, content) = GZIPInputStream(ByteArrayInputStream(metadata)).use { stream ->
|
||||
JsKlibMetadataProtoBuf.Header.parseDelimitedFrom(stream, JsKlibMetadataSerializerProtocol.extensionRegistry) to
|
||||
JsKlibMetadataProtoBuf.Library.parseFrom(stream, JsKlibMetadataSerializerProtocol.extensionRegistry)
|
||||
}
|
||||
|
||||
val header = JsKlibMetadataProtoBuf.Header.parseFrom(metadata, JsKlibMetadataSerializerProtocol.extensionRegistry)
|
||||
val content = JsKlibMetadataProtoBuf.Library.parseFrom(metadata, JsKlibMetadataSerializerProtocol.extensionRegistry)
|
||||
return JsKlibMetadataParts(header, content.packageFragmentList, content.importedModuleList)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-11
@@ -5,8 +5,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata
|
||||
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite
|
||||
import org.jetbrains.kotlin.serialization.SerializerExtensionProtocol
|
||||
|
||||
@@ -24,12 +22,4 @@ object JsKlibMetadataSerializerProtocol : SerializerExtensionProtocol(
|
||||
JsKlibMetadataProtoBuf.parameterAnnotation,
|
||||
JsKlibMetadataProtoBuf.typeAnnotation,
|
||||
JsKlibMetadataProtoBuf.typeParameterAnnotation
|
||||
) {
|
||||
fun getKjsmFilePath(packageFqName: FqName): String {
|
||||
val shortName = if (packageFqName.isRoot) Name.identifier("root-package") else packageFqName.shortName()
|
||||
|
||||
return packageFqName.child(shortName).asString().replace('.', '/') +
|
||||
"." +
|
||||
JsKlibMetadataSerializationUtil.CLASS_METADATA_FILE_EXTENSION
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.config.*
|
||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.isCommonSource
|
||||
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
||||
@@ -58,10 +59,10 @@ fun buildKLib(
|
||||
moduleName: String,
|
||||
sources: List<String>,
|
||||
outputPath: String,
|
||||
dependencies: List<KlibModuleRef>,
|
||||
dependencies: List<KotlinLibrary>,
|
||||
commonSources: List<String>
|
||||
): KlibModuleRef {
|
||||
return generateKLib(
|
||||
) {
|
||||
generateKLib(
|
||||
project = environment.project,
|
||||
files = sources.map { source ->
|
||||
val file = createPsiFile(source)
|
||||
@@ -71,10 +72,10 @@ fun buildKLib(
|
||||
file
|
||||
},
|
||||
configuration = buildConfiguration(environment, moduleName),
|
||||
immediateDependencies = dependencies,
|
||||
allDependencies = dependencies,
|
||||
friendDependencies = emptyList(),
|
||||
outputKlibPath = outputPath
|
||||
outputKlibPath = outputPath,
|
||||
nopack = true
|
||||
)
|
||||
}
|
||||
|
||||
@@ -114,12 +115,10 @@ fun main(args: Array<String>) {
|
||||
|
||||
val name = outputPath.takeLastWhile { it != '/' }
|
||||
|
||||
if (!name.endsWith(".klm")) error("invalid output file name")
|
||||
|
||||
val dependencyKLibs = dependencies.map {
|
||||
val file = File(it)
|
||||
KlibModuleRef(file.name.dropLast(4), file.parent)
|
||||
loadKlib(file.path)
|
||||
}
|
||||
|
||||
buildKLib(name.dropLast(4), listOfKtFilesFrom(inputFiles), File(outputPath).parent, dependencyKLibs, listOfKtFilesFrom(commonSources))
|
||||
buildKLib(name.dropLast(4), listOfKtFilesFrom(inputFiles), outputPath, dependencyKLibs, listOfKtFilesFrom(commonSources))
|
||||
}
|
||||
|
||||
+2
@@ -3,6 +3,8 @@ where advanced options include:
|
||||
-Xfriend-modules=<path> Paths to friend modules
|
||||
-Xfriend-modules-disabled Disable internal declaration export
|
||||
-Xir Use IR backend
|
||||
-Xir-legacy-gradle-plugin-compatibility
|
||||
Make KLIB generation compatible with legacy gradle plugin
|
||||
-Xir-produce-only={ klib, js } Type of output to produce. Overrides -meta-info argument.
|
||||
-Xtyped-arrays Translate primitive arrays to JS typed arrays
|
||||
-Xallow-kotlin-package Allow compiling code in package 'kotlin' and allow not requiring kotlin.stdlib in module-info
|
||||
|
||||
@@ -139,7 +139,7 @@ internal fun zippedKotlinLibraryChecks(klibFile: File) {
|
||||
check(klibFile.isFile) { "Expected $klibFile to be a regular file." }
|
||||
|
||||
val extension = klibFile.extension
|
||||
check(extension.isEmpty() || extension == KLIB_FILE_EXTENSION) {
|
||||
check(extension.isEmpty() || extension == KLIB_FILE_EXTENSION || extension == "jar") {
|
||||
"KLIB path has unexpected extension: $klibFile"
|
||||
}
|
||||
}
|
||||
@@ -85,7 +85,7 @@ class KoltinLibraryWriterImpl(
|
||||
|
||||
) : BaseWriter by base, MetadataWriter by metadata, IrWriter by ir, KotlinLibraryWriter
|
||||
|
||||
internal fun buildKoltinLibrary(
|
||||
fun buildKoltinLibrary(
|
||||
linkDependencies: List<KotlinLibrary>,
|
||||
metadata: SerializedMetadata,
|
||||
ir: SerializedIr,
|
||||
|
||||
@@ -17,12 +17,14 @@
|
||||
package org.jetbrains.kotlin.utils
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import java.io.*
|
||||
import java.util.*
|
||||
import java.util.jar.Attributes
|
||||
import java.util.jar.JarFile
|
||||
import java.util.jar.Manifest
|
||||
import java.util.zip.ZipFile
|
||||
|
||||
object LibraryUtils {
|
||||
private val LOG = Logger.getInstance(LibraryUtils::class.java)
|
||||
@@ -65,6 +67,26 @@ object LibraryUtils {
|
||||
return checkAttributeValue(library, TITLE_KOTLIN_JAVASCRIPT_STDLIB, Attributes.Name.IMPLEMENTATION_TITLE)
|
||||
}
|
||||
|
||||
private fun isZippedKlib(candidate: File): Boolean {
|
||||
if (candidate.extension == "klib") return true
|
||||
var manifestFound = false
|
||||
var irFound = false
|
||||
for (entry in ZipFile(candidate).entries()) {
|
||||
if (entry.name == "manifest") manifestFound = true
|
||||
if (entry.name == "ir/") irFound = true
|
||||
}
|
||||
return manifestFound && irFound
|
||||
}
|
||||
|
||||
fun isKotlinJavascriptIrLibrary(candidate: File): Boolean {
|
||||
return when {
|
||||
FileUtil.isJarOrZip(candidate) -> isZippedKlib(candidate)
|
||||
!File(candidate, "manifest").isFile -> false
|
||||
!File(candidate, "ir").isDirectory -> false
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
|
||||
private fun getManifestFromJar(library: File): Manifest? {
|
||||
if (!library.canRead()) return null
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.js.test
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||
import org.jetbrains.kotlin.backend.common.phaser.toPhaseMap
|
||||
import org.jetbrains.kotlin.ir.backend.js.KlibModuleRef
|
||||
import org.jetbrains.kotlin.ir.backend.js.loadKlib
|
||||
import org.jetbrains.kotlin.ir.backend.js.compile
|
||||
import org.jetbrains.kotlin.ir.backend.js.generateKLib
|
||||
import org.jetbrains.kotlin.ir.backend.js.jsPhases
|
||||
@@ -18,9 +18,9 @@ import org.jetbrains.kotlin.js.facade.TranslationUnit
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
import java.io.File
|
||||
|
||||
private val fullRuntimeKlib = KlibModuleRef("JS_IR_RUNTIME", "compiler/ir/serialization.js/build/fullRuntime/klib")
|
||||
private val defaultRuntimeKlib = KlibModuleRef("JS_IR_RUNTIME", "compiler/ir/serialization.js/build/reducedRuntime/klib")
|
||||
private val kotlinTestKLib = KlibModuleRef("kotlin.test", "compiler/ir/serialization.js/build/kotlin.test/klib")
|
||||
private val fullRuntimeKlib = loadKlib("compiler/ir/serialization.js/build/fullRuntime/klib")
|
||||
private val defaultRuntimeKlib = loadKlib("compiler/ir/serialization.js/build/reducedRuntime/klib")
|
||||
private val kotlinTestKLib = loadKlib("compiler/ir/serialization.js/build/kotlin.test/klib")
|
||||
|
||||
abstract class BasicIrBoxTest(
|
||||
pathToTestDir: String,
|
||||
@@ -43,7 +43,7 @@ abstract class BasicIrBoxTest(
|
||||
// TODO Design incremental compilation for IR and add test support
|
||||
override val incrementalCompilationChecksEnabled = false
|
||||
|
||||
private val compilationCache = mutableMapOf<String, KlibModuleRef>()
|
||||
private val compilationCache = mutableMapOf<String, String>()
|
||||
|
||||
override fun doTest(filePath: String, expectedResult: String, mainCallParameters: MainCallParameters, coroutinesPackage: String) {
|
||||
compilationCache.clear()
|
||||
@@ -73,16 +73,10 @@ abstract class BasicIrBoxTest(
|
||||
|
||||
val runtimeKlibs = if (needsFullIrRuntime) listOf(fullRuntimeKlib, kotlinTestKLib) else listOf(defaultRuntimeKlib)
|
||||
|
||||
val libraries = config.configuration[JSConfigurationKeys.LIBRARIES]!!.map { File(it).name }
|
||||
val transitiveLibraries = config.configuration[JSConfigurationKeys.TRANSITIVE_LIBRARIES]!!.map { File(it).name }
|
||||
|
||||
// TODO: Add proper depencencies
|
||||
val dependencies = runtimeKlibs + libraries.map {
|
||||
compilationCache[it] ?: error("Can't find compiled module for dependency $it")
|
||||
}
|
||||
|
||||
val allDependencies = runtimeKlibs + transitiveLibraries.map {
|
||||
compilationCache[it] ?: error("Can't find compiled module for dependency $it")
|
||||
loadKlib(compilationCache[it] ?: error("Can't find compiled module for dependency $it"))
|
||||
}
|
||||
|
||||
val actualOutputFile = outputFile.absolutePath.let {
|
||||
@@ -112,7 +106,6 @@ abstract class BasicIrBoxTest(
|
||||
files = filesToCompile,
|
||||
configuration = config.configuration,
|
||||
phaseConfig = phaseConfig,
|
||||
immediateDependencies = dependencies,
|
||||
allDependencies = allDependencies,
|
||||
friendDependencies = emptyList(),
|
||||
mainArguments = mainCallParameters.run { if (shouldBeGenerated()) arguments() else null }
|
||||
@@ -122,17 +115,17 @@ abstract class BasicIrBoxTest(
|
||||
outputFile.write(wrappedCode)
|
||||
|
||||
} else {
|
||||
val module = generateKLib(
|
||||
generateKLib(
|
||||
project = config.project,
|
||||
files = filesToCompile,
|
||||
configuration = config.configuration,
|
||||
immediateDependencies = dependencies,
|
||||
allDependencies = allDependencies,
|
||||
friendDependencies = emptyList(),
|
||||
outputKlibPath = actualOutputFile
|
||||
outputKlibPath = actualOutputFile,
|
||||
nopack = true
|
||||
)
|
||||
|
||||
compilationCache[outputFile.name.replace(".js", ".meta.js")] = module
|
||||
compilationCache[outputFile.name.replace(".js", ".meta.js")] = actualOutputFile
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -563,8 +563,7 @@ open class Kotlin2JsCompile : AbstractKotlinCompile<K2JSCompilerArguments>(), Ko
|
||||
|
||||
private val libraryFilter: (File) -> Boolean
|
||||
get() = if ("-Xir" in kotlinOptions.freeCompilerArgs) {
|
||||
// TODO: Detect IR libraries
|
||||
{ true }
|
||||
LibraryUtils::isKotlinJavascriptIrLibrary
|
||||
} else {
|
||||
LibraryUtils::isKotlinJavascriptLibrary
|
||||
}
|
||||
@@ -578,6 +577,7 @@ open class Kotlin2JsCompile : AbstractKotlinCompile<K2JSCompilerArguments>(), Ko
|
||||
if ("-Xir" in args.freeArgs) {
|
||||
logger.kotlinDebug("Using JS IR backend")
|
||||
incremental = false
|
||||
args.freeArgs += "-Xir-legacy-gradle-plugin-compatibility"
|
||||
}
|
||||
|
||||
val dependencies = compileClasspath
|
||||
|
||||
Reference in New Issue
Block a user