JS IR: split compilation and deserialization
This commit is contained in:
+4
-11
@@ -9,15 +9,14 @@ import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
|||||||
import org.jetbrains.kotlin.backend.common.atMostOne
|
import org.jetbrains.kotlin.backend.common.atMostOne
|
||||||
import org.jetbrains.kotlin.backend.common.ir.Ir
|
import org.jetbrains.kotlin.backend.common.ir.Ir
|
||||||
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
|
||||||
import org.jetbrains.kotlin.backend.js.JsDeclarationFactory
|
import org.jetbrains.kotlin.backend.js.JsDeclarationFactory
|
||||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.SourceManager
|
import org.jetbrains.kotlin.ir.SourceManager
|
||||||
@@ -43,12 +42,11 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
|||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
|
||||||
class JsIrBackendContext(
|
class JsIrBackendContext(
|
||||||
val module: ModuleDescriptorImpl,
|
val module: ModuleDescriptor,
|
||||||
override val irBuiltIns: IrBuiltIns,
|
override val irBuiltIns: IrBuiltIns,
|
||||||
val symbolTable: SymbolTable,
|
val symbolTable: SymbolTable,
|
||||||
irModuleFragment: IrModuleFragment,
|
irModuleFragment: IrModuleFragment,
|
||||||
override val configuration: CompilerConfiguration,
|
override val configuration: CompilerConfiguration
|
||||||
val phaseConfig: PhaseConfig
|
|
||||||
) : CommonBackendContext {
|
) : CommonBackendContext {
|
||||||
|
|
||||||
override val builtIns = module.builtIns
|
override val builtIns = module.builtIns
|
||||||
@@ -83,8 +81,7 @@ class JsIrBackendContext(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val sharedVariablesManager =
|
override val sharedVariablesManager = JsSharedVariablesManager(irBuiltIns, implicitDeclarationFile)
|
||||||
JsSharedVariablesManager(irBuiltIns, implicitDeclarationFile)
|
|
||||||
override val declarationFactory = JsDeclarationFactory()
|
override val declarationFactory = JsDeclarationFactory()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -226,10 +223,6 @@ class JsIrBackendContext(
|
|||||||
val newThrowableSymbol = symbolTable.referenceSimpleFunction(getJsInternalFunction("newThrowable"))
|
val newThrowableSymbol = symbolTable.referenceSimpleFunction(getJsInternalFunction("newThrowable"))
|
||||||
|
|
||||||
val throwISEymbol = symbolTable.referenceSimpleFunction(getFunctions(kotlinPackageFqn.child(Name.identifier("THROW_ISE"))).single())
|
val throwISEymbol = symbolTable.referenceSimpleFunction(getFunctions(kotlinPackageFqn.child(Name.identifier("THROW_ISE"))).single())
|
||||||
val throwNPESymbol = ir.symbols.ThrowNullPointerException
|
|
||||||
val throwCCESymbol = ir.symbols.ThrowTypeCastException
|
|
||||||
val throwNWBESymbol = ir.symbols.ThrowNoWhenBranchMatchedException
|
|
||||||
val throwUPAESymbol = ir.symbols.ThrowUninitializedPropertyAccessException
|
|
||||||
|
|
||||||
val coroutineImplLabelPropertyGetter by lazy { ir.symbols.coroutineImpl.getPropertyGetter("state")!!.owner }
|
val coroutineImplLabelPropertyGetter by lazy { ir.symbols.coroutineImpl.getPropertyGetter("state")!!.owner }
|
||||||
val coroutineImplLabelPropertySetter by lazy { ir.symbols.coroutineImpl.getPropertySetter("state")!!.owner }
|
val coroutineImplLabelPropertySetter by lazy { ir.symbols.coroutineImpl.getPropertySetter("state")!!.owner }
|
||||||
|
|||||||
@@ -6,173 +6,31 @@
|
|||||||
package org.jetbrains.kotlin.ir.backend.js
|
package org.jetbrains.kotlin.ir.backend.js
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import org.jetbrains.kotlin.backend.common.LoggingContext
|
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
|
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
|
||||||
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.CompilerConfiguration
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
|
||||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
|
||||||
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.backend.js.transformers.irToJs.IrModuleToJsTransformer
|
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransformer
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
|
||||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
|
||||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||||
import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
|
|
||||||
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
|
|
||||||
|
|
||||||
sealed class TranslationResult {
|
|
||||||
class CompiledJsCode(val jsCode: String) : TranslationResult()
|
|
||||||
|
|
||||||
object CompiledKlib : TranslationResult()
|
|
||||||
}
|
|
||||||
|
|
||||||
data class KlibModuleRef(
|
|
||||||
val moduleName: String,
|
|
||||||
val klibPath: String
|
|
||||||
)
|
|
||||||
|
|
||||||
enum class CompilationMode {
|
|
||||||
KLIB,
|
|
||||||
JS
|
|
||||||
}
|
|
||||||
|
|
||||||
internal val JS_KLIBRARY_CAPABILITY = ModuleDescriptor.Capability<File>("JS KLIBRARY")
|
|
||||||
internal val moduleHeaderFileName = "module.kji"
|
|
||||||
internal val declarationsDirName = "ir/"
|
|
||||||
private val logggg = object : LoggingContext {
|
|
||||||
override var inVerbosePhase: Boolean
|
|
||||||
get() = TODO("not implemented")
|
|
||||||
set(_) {}
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
fun compile(
|
fun compile(
|
||||||
project: Project,
|
project: Project,
|
||||||
files: List<KtFile>,
|
files: List<KtFile>,
|
||||||
configuration: CompilerConfiguration,
|
configuration: CompilerConfiguration,
|
||||||
phaseConfig: PhaseConfig,
|
phaseConfig: PhaseConfig,
|
||||||
compileMode: CompilationMode,
|
|
||||||
immediateDependencies: List<KlibModuleRef>,
|
immediateDependencies: List<KlibModuleRef>,
|
||||||
allDependencies: List<KlibModuleRef>,
|
allDependencies: List<KlibModuleRef>
|
||||||
outputKlibPath: String
|
): String {
|
||||||
): TranslationResult {
|
val (moduleFragment, dependencyModules, irBuiltIns, symbolTable, deserializer) =
|
||||||
|
loadIr(project, files, configuration, immediateDependencies, allDependencies)
|
||||||
|
|
||||||
val deserializedModuleParts: Map<KlibModuleRef, JsKlibMetadataParts> =
|
val moduleDescriptor = moduleFragment.descriptor
|
||||||
allDependencies.associateWith { loadKlibMetadataParts(it) }
|
|
||||||
|
|
||||||
fun findModuleByName(name: String): KlibModuleRef =
|
val context = JsIrBackendContext(moduleDescriptor, irBuiltIns, symbolTable, moduleFragment, configuration)
|
||||||
allDependencies.find { it.moduleName == name } ?: error("Module is not found: $name")
|
|
||||||
|
|
||||||
val moduleDependencies: Map<KlibModuleRef, List<KlibModuleRef>> =
|
// Load declarations referenced during `context` initialization
|
||||||
deserializedModuleParts.mapValues { (_, parts) ->
|
dependencyModules.forEach {
|
||||||
parts.importedModules.map(::findModuleByName)
|
|
||||||
}
|
|
||||||
|
|
||||||
val sortedImmediateDependencies: List<KlibModuleRef> =
|
|
||||||
DFS.topologicalOrder(immediateDependencies) { moduleDependencies.getValue(it) }
|
|
||||||
.reversed()
|
|
||||||
|
|
||||||
val depsDescriptors = ModulesStructure(
|
|
||||||
LookupTracker.DO_NOTHING,
|
|
||||||
configuration.metadataVersion,
|
|
||||||
configuration.languageVersionSettings,
|
|
||||||
moduleDependencies
|
|
||||||
)
|
|
||||||
|
|
||||||
val builtInsDep = sortedImmediateDependencies.firstOrNull()
|
|
||||||
val builtInModuleDescriptor =
|
|
||||||
if (builtInsDep != null)
|
|
||||||
depsDescriptors.getModuleDescriptor(builtInsDep)
|
|
||||||
else
|
|
||||||
null // null in case compiling builtInModule itself
|
|
||||||
|
|
||||||
val analysisResult =
|
|
||||||
TopDownAnalyzerFacadeForJS.analyzeFiles(
|
|
||||||
files,
|
|
||||||
project,
|
|
||||||
configuration,
|
|
||||||
sortedImmediateDependencies.map { depsDescriptors.getModuleDescriptor(it) },
|
|
||||||
friendModuleDescriptors = emptyList(),
|
|
||||||
thisIsBuiltInsModule = builtInModuleDescriptor == null,
|
|
||||||
customBuiltInsModule = builtInModuleDescriptor
|
|
||||||
)
|
|
||||||
|
|
||||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
|
||||||
TopDownAnalyzerFacadeForJS.checkForErrors(files, analysisResult.bindingContext)
|
|
||||||
|
|
||||||
val moduleDescriptor = analysisResult.moduleDescriptor as ModuleDescriptorImpl
|
|
||||||
val symbolTable = SymbolTable()
|
|
||||||
|
|
||||||
val psi2IrTranslator = Psi2IrTranslator(configuration.languageVersionSettings)
|
|
||||||
val psi2IrContext = psi2IrTranslator.createGeneratorContext(moduleDescriptor, analysisResult.bindingContext, symbolTable)
|
|
||||||
val irBuiltIns = psi2IrContext.irBuiltIns
|
|
||||||
|
|
||||||
val deserializer = JsIrLinker(moduleDescriptor, logggg, irBuiltIns, symbolTable)
|
|
||||||
|
|
||||||
val deserializedModuleFragments = sortedImmediateDependencies.map {
|
|
||||||
val moduleFile = File(it.klibPath, moduleHeaderFileName)
|
|
||||||
deserializer.deserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(it))!!
|
|
||||||
}
|
|
||||||
|
|
||||||
val moduleFragment = psi2IrTranslator.generateModuleFragment(psi2IrContext, files, deserializer)
|
|
||||||
|
|
||||||
if (compileMode == CompilationMode.KLIB) {
|
|
||||||
deserializedModuleFragments.forEach {
|
|
||||||
ExternalDependenciesGenerator(it.descriptor, symbolTable, irBuiltIns).generateUnboundSymbolsAsDependencies()
|
|
||||||
}
|
|
||||||
deserializedModuleFragments.forEach { it.patchDeclarationParents() }
|
|
||||||
val moduleName = configuration.get(CommonConfigurationKeys.MODULE_NAME) as String
|
|
||||||
serializeModuleIntoKlib(
|
|
||||||
moduleName,
|
|
||||||
configuration.metadataVersion,
|
|
||||||
configuration.languageVersionSettings,
|
|
||||||
psi2IrContext.symbolTable,
|
|
||||||
psi2IrContext.bindingContext,
|
|
||||||
outputKlibPath,
|
|
||||||
immediateDependencies,
|
|
||||||
moduleFragment
|
|
||||||
)
|
|
||||||
|
|
||||||
return TranslationResult.CompiledKlib
|
|
||||||
}
|
|
||||||
|
|
||||||
val context = JsIrBackendContext(moduleDescriptor, irBuiltIns, symbolTable, moduleFragment, configuration, phaseConfig)
|
|
||||||
|
|
||||||
deserializedModuleFragments.forEach {
|
|
||||||
ExternalDependenciesGenerator(
|
ExternalDependenciesGenerator(
|
||||||
it.descriptor,
|
it.descriptor,
|
||||||
symbolTable,
|
symbolTable,
|
||||||
@@ -182,136 +40,21 @@ fun compile(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check the order
|
// TODO: check the order
|
||||||
val irFiles = deserializedModuleFragments.flatMap { it.files } + moduleFragment.files
|
val irFiles = dependencyModules.flatMap { it.files } + moduleFragment.files
|
||||||
|
|
||||||
moduleFragment.files.clear()
|
moduleFragment.files.clear()
|
||||||
moduleFragment.files += irFiles
|
moduleFragment.files += irFiles
|
||||||
|
|
||||||
|
// TODO Why is this needed?
|
||||||
ExternalDependenciesGenerator(
|
ExternalDependenciesGenerator(
|
||||||
moduleDescriptor = context.module,
|
moduleDescriptor = moduleDescriptor,
|
||||||
symbolTable = context.symbolTable,
|
symbolTable = symbolTable,
|
||||||
irBuiltIns = context.irBuiltIns
|
irBuiltIns = irBuiltIns
|
||||||
).generateUnboundSymbolsAsDependencies()
|
).generateUnboundSymbolsAsDependencies()
|
||||||
moduleFragment.patchDeclarationParents()
|
moduleFragment.patchDeclarationParents()
|
||||||
|
|
||||||
jsPhases.invokeToplevel(context.phaseConfig, context, moduleFragment)
|
jsPhases.invokeToplevel(phaseConfig, context, moduleFragment)
|
||||||
|
|
||||||
val jsProgram = moduleFragment.accept(IrModuleToJsTransformer(context), null)
|
val jsProgram = moduleFragment.accept(IrModuleToJsTransformer(context), null)
|
||||||
return TranslationResult.CompiledJsCode(jsProgram.toString())
|
return jsProgram.toString()
|
||||||
}
|
|
||||||
|
|
||||||
private fun loadKlibMetadataParts(
|
|
||||||
moduleId: KlibModuleRef
|
|
||||||
): JsKlibMetadataParts {
|
|
||||||
val metadataFile = File(moduleId.klibPath, metadataFileName(moduleId.moduleName))
|
|
||||||
val serializer = JsKlibMetadataSerializationUtil
|
|
||||||
return serializer.readModuleAsProto(metadataFile.readBytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun loadKlibMetadata(
|
|
||||||
parts: JsKlibMetadataParts,
|
|
||||||
moduleId: KlibModuleRef,
|
|
||||||
isBuiltIn: Boolean,
|
|
||||||
lookupTracker: LookupTracker,
|
|
||||||
storageManager: LockBasedStorageManager,
|
|
||||||
metadataVersion: JsKlibMetadataVersion,
|
|
||||||
languageVersionSettings: LanguageVersionSettings,
|
|
||||||
builtinsModule: ModuleDescriptorImpl?,
|
|
||||||
dependencies: List<ModuleDescriptorImpl>
|
|
||||||
): ModuleDescriptorImpl {
|
|
||||||
assert(isBuiltIn == (builtinsModule === null))
|
|
||||||
val builtIns = builtinsModule?.builtIns ?: object : KotlinBuiltIns(storageManager) {}
|
|
||||||
val md = ModuleDescriptorImpl(Name.special("<${moduleId.moduleName}>"), storageManager, builtIns,
|
|
||||||
capabilities = mapOf(JS_KLIBRARY_CAPABILITY to File(moduleId.klibPath)))
|
|
||||||
if (isBuiltIn) builtIns.builtInsModule = md
|
|
||||||
val currentModuleFragmentProvider = createJsKlibMetadataPackageFragmentProvider(
|
|
||||||
storageManager, md, parts.header, parts.body, metadataVersion,
|
|
||||||
CompilerDeserializationConfiguration(languageVersionSettings),
|
|
||||||
lookupTracker
|
|
||||||
)
|
|
||||||
|
|
||||||
val packageFragmentProvider = if (isBuiltIn) {
|
|
||||||
val functionFragmentProvider = functionInterfacePackageFragmentProvider(storageManager, md)
|
|
||||||
CompositePackageFragmentProvider(listOf(functionFragmentProvider, currentModuleFragmentProvider))
|
|
||||||
} else currentModuleFragmentProvider
|
|
||||||
|
|
||||||
md.initialize(packageFragmentProvider)
|
|
||||||
md.setDependencies(listOf(md) + dependencies)
|
|
||||||
|
|
||||||
return md
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class ModulesStructure(
|
|
||||||
private val lookupTracker: LookupTracker,
|
|
||||||
private val metadataVersion: JsKlibMetadataVersion,
|
|
||||||
private val languageVersionSettings: LanguageVersionSettings,
|
|
||||||
private val moduleDependencies: Map<KlibModuleRef, List<KlibModuleRef>>
|
|
||||||
) {
|
|
||||||
private val storageManager: LockBasedStorageManager = LockBasedStorageManager("ModulesStructure")
|
|
||||||
private var runtimeModule: ModuleDescriptorImpl? = null
|
|
||||||
|
|
||||||
private val descriptors = mutableMapOf<KlibModuleRef, ModuleDescriptorImpl>()
|
|
||||||
|
|
||||||
fun getModuleDescriptor(current: KlibModuleRef): ModuleDescriptorImpl = descriptors.getOrPut(current) {
|
|
||||||
val parts = loadKlibMetadataParts(current)
|
|
||||||
val isBuiltIns = parts.importedModules.isEmpty()
|
|
||||||
loadKlibMetadata(
|
|
||||||
parts,
|
|
||||||
current,
|
|
||||||
isBuiltIns,
|
|
||||||
lookupTracker,
|
|
||||||
storageManager,
|
|
||||||
metadataVersion,
|
|
||||||
languageVersionSettings,
|
|
||||||
runtimeModule,
|
|
||||||
moduleDependencies.getValue(current).map { getModuleDescriptor(it) }
|
|
||||||
).also {
|
|
||||||
if (isBuiltIns) runtimeModule = it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun serializeModuleIntoKlib(
|
|
||||||
moduleName: String,
|
|
||||||
metadataVersion: JsKlibMetadataVersion,
|
|
||||||
languageVersionSettings: LanguageVersionSettings,
|
|
||||||
symbolTable: SymbolTable,
|
|
||||||
bindingContext: BindingContext,
|
|
||||||
klibPath: String,
|
|
||||||
dependencies: List<KlibModuleRef>,
|
|
||||||
moduleFragment: IrModuleFragment
|
|
||||||
) {
|
|
||||||
val declarationTable = JsDeclarationTable(moduleFragment.irBuiltins, DescriptorTable())
|
|
||||||
|
|
||||||
val serializedIr = JsIrModuleSerializer(logggg, declarationTable).serializedIrModule(moduleFragment)
|
|
||||||
val serializer = JsKlibMetadataSerializationUtil
|
|
||||||
|
|
||||||
val moduleDescription =
|
|
||||||
JsKlibMetadataModuleDescriptor(moduleName, dependencies.map { it.moduleName }, moduleFragment.descriptor)
|
|
||||||
val serializedData = serializer.serializeMetadata(
|
|
||||||
bindingContext,
|
|
||||||
moduleDescription,
|
|
||||||
languageVersionSettings,
|
|
||||||
metadataVersion
|
|
||||||
) { declarationDescriptor ->
|
|
||||||
val index = declarationTable.descriptorTable.get(declarationDescriptor)
|
|
||||||
index?.let { newJsDescriptorUniqId(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
val klibDir = File(klibPath).also {
|
|
||||||
it.deleteRecursively()
|
|
||||||
it.mkdirs()
|
|
||||||
}
|
|
||||||
|
|
||||||
val moduleFile = File(klibDir, moduleHeaderFileName)
|
|
||||||
moduleFile.writeBytes(serializedIr.module)
|
|
||||||
|
|
||||||
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())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,298 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. 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.ir.backend.js
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import org.jetbrains.kotlin.backend.common.LoggingContext
|
||||||
|
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.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
|
||||||
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
|
import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS
|
||||||
|
import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
|
||||||
|
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
|
||||||
|
|
||||||
|
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/"
|
||||||
|
private val logggg = object : LoggingContext {
|
||||||
|
override var inVerbosePhase: Boolean
|
||||||
|
get() = TODO("not implemented")
|
||||||
|
set(_) {}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
fun generateKLib(
|
||||||
|
project: Project,
|
||||||
|
files: List<KtFile>,
|
||||||
|
configuration: CompilerConfiguration,
|
||||||
|
immediateDependencies: List<KlibModuleRef>,
|
||||||
|
allDependencies: List<KlibModuleRef>,
|
||||||
|
outputKlibPath: String
|
||||||
|
): KlibModuleRef {
|
||||||
|
val depsDescriptors = ModulesStructure(project, files, configuration, immediateDependencies, allDependencies)
|
||||||
|
|
||||||
|
val analysisResult = depsDescriptors.runAnalysis()
|
||||||
|
|
||||||
|
val psi2IrTranslator = Psi2IrTranslator(configuration.languageVersionSettings)
|
||||||
|
val psi2IrContext = psi2IrTranslator.createGeneratorContext(analysisResult.moduleDescriptor, analysisResult.bindingContext)
|
||||||
|
|
||||||
|
val moduleFragment = psi2IrTranslator.generateModuleFragment(psi2IrContext, files)
|
||||||
|
|
||||||
|
val moduleName = configuration[CommonConfigurationKeys.MODULE_NAME]!!
|
||||||
|
serializeModuleIntoKlib(
|
||||||
|
moduleName,
|
||||||
|
configuration.metadataVersion,
|
||||||
|
configuration.languageVersionSettings,
|
||||||
|
psi2IrContext.bindingContext,
|
||||||
|
outputKlibPath,
|
||||||
|
immediateDependencies,
|
||||||
|
moduleFragment
|
||||||
|
)
|
||||||
|
|
||||||
|
return KlibModuleRef(moduleName, outputKlibPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
data class IrModuleInfo(
|
||||||
|
val module: IrModuleFragment,
|
||||||
|
val allDependencies: List<IrModuleFragment>,
|
||||||
|
val bultins: IrBuiltIns,
|
||||||
|
val symbolTable: SymbolTable,
|
||||||
|
val deserializer: JsIrLinker
|
||||||
|
)
|
||||||
|
|
||||||
|
fun loadIr(
|
||||||
|
project: Project,
|
||||||
|
files: List<KtFile>,
|
||||||
|
configuration: CompilerConfiguration,
|
||||||
|
immediateDependencies: List<KlibModuleRef>,
|
||||||
|
allDependencies: List<KlibModuleRef>
|
||||||
|
): IrModuleInfo {
|
||||||
|
val depsDescriptors = ModulesStructure(project, files, configuration, immediateDependencies, allDependencies)
|
||||||
|
|
||||||
|
val analysisResult = depsDescriptors.runAnalysis()
|
||||||
|
|
||||||
|
val moduleDescriptor = analysisResult.moduleDescriptor
|
||||||
|
|
||||||
|
val symbolTable = SymbolTable()
|
||||||
|
|
||||||
|
val psi2IrTranslator = Psi2IrTranslator(configuration.languageVersionSettings)
|
||||||
|
val psi2IrContext = psi2IrTranslator.createGeneratorContext(moduleDescriptor, analysisResult.bindingContext, symbolTable)
|
||||||
|
val irBuiltIns = psi2IrContext.irBuiltIns
|
||||||
|
|
||||||
|
val deserializer = JsIrLinker(moduleDescriptor, logggg, irBuiltIns, symbolTable)
|
||||||
|
|
||||||
|
val deserializedModuleFragments = depsDescriptors.sortedImmediateDependencies.map {
|
||||||
|
val moduleFile = File(it.klibPath, moduleHeaderFileName)
|
||||||
|
deserializer.deserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(it))!!
|
||||||
|
}
|
||||||
|
|
||||||
|
val moduleFragment = psi2IrTranslator.generateModuleFragment(psi2IrContext, files, deserializer)
|
||||||
|
|
||||||
|
return IrModuleInfo(moduleFragment, deserializedModuleFragments, irBuiltIns, symbolTable, deserializer)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadKlibMetadataParts(
|
||||||
|
moduleId: KlibModuleRef
|
||||||
|
): JsKlibMetadataParts {
|
||||||
|
val metadataFile = File(moduleId.klibPath, metadataFileName(moduleId.moduleName))
|
||||||
|
val serializer = JsKlibMetadataSerializationUtil
|
||||||
|
return serializer.readModuleAsProto(metadataFile.readBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadKlibMetadata(
|
||||||
|
parts: JsKlibMetadataParts,
|
||||||
|
moduleId: KlibModuleRef,
|
||||||
|
isBuiltIn: Boolean,
|
||||||
|
lookupTracker: LookupTracker,
|
||||||
|
storageManager: LockBasedStorageManager,
|
||||||
|
metadataVersion: JsKlibMetadataVersion,
|
||||||
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
|
builtinsModule: ModuleDescriptorImpl?,
|
||||||
|
dependencies: List<ModuleDescriptorImpl>
|
||||||
|
): ModuleDescriptorImpl {
|
||||||
|
assert(isBuiltIn == (builtinsModule === null))
|
||||||
|
val builtIns = builtinsModule?.builtIns ?: object : KotlinBuiltIns(storageManager) {}
|
||||||
|
val md = ModuleDescriptorImpl(Name.special("<${moduleId.moduleName}>"), storageManager, builtIns,
|
||||||
|
capabilities = mapOf(JS_KLIBRARY_CAPABILITY to File(moduleId.klibPath)))
|
||||||
|
if (isBuiltIn) builtIns.builtInsModule = md
|
||||||
|
val currentModuleFragmentProvider = createJsKlibMetadataPackageFragmentProvider(
|
||||||
|
storageManager, md, parts.header, parts.body, metadataVersion,
|
||||||
|
CompilerDeserializationConfiguration(languageVersionSettings),
|
||||||
|
lookupTracker
|
||||||
|
)
|
||||||
|
|
||||||
|
val packageFragmentProvider = if (isBuiltIn) {
|
||||||
|
val functionFragmentProvider = functionInterfacePackageFragmentProvider(storageManager, md)
|
||||||
|
CompositePackageFragmentProvider(listOf(functionFragmentProvider, currentModuleFragmentProvider))
|
||||||
|
} else currentModuleFragmentProvider
|
||||||
|
|
||||||
|
md.initialize(packageFragmentProvider)
|
||||||
|
md.setDependencies(listOf(md) + dependencies)
|
||||||
|
|
||||||
|
return md
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ModulesStructure(
|
||||||
|
private val project: Project,
|
||||||
|
private val files: List<KtFile>,
|
||||||
|
private val compilerConfiguration: CompilerConfiguration,
|
||||||
|
immediateDependencies: List<KlibModuleRef>,
|
||||||
|
private val allDependencies: List<KlibModuleRef>
|
||||||
|
) {
|
||||||
|
private val deserializedModuleParts: Map<KlibModuleRef, JsKlibMetadataParts> =
|
||||||
|
allDependencies.associateWith { loadKlibMetadataParts(it) }
|
||||||
|
|
||||||
|
fun findModuleByName(name: String): KlibModuleRef =
|
||||||
|
allDependencies.find { it.moduleName == name } ?: error("Module is not found: $name")
|
||||||
|
|
||||||
|
val moduleDependencies: Map<KlibModuleRef, List<KlibModuleRef>> =
|
||||||
|
deserializedModuleParts.mapValues { (_, parts) ->
|
||||||
|
parts.importedModules.map(::findModuleByName)
|
||||||
|
}
|
||||||
|
|
||||||
|
val sortedImmediateDependencies: List<KlibModuleRef> =
|
||||||
|
DFS.topologicalOrder(immediateDependencies) { moduleDependencies.getValue(it) }
|
||||||
|
.reversed()
|
||||||
|
|
||||||
|
val builtInsDep = sortedImmediateDependencies.firstOrNull()
|
||||||
|
|
||||||
|
fun runAnalysis(): JsAnalysisResult {
|
||||||
|
val analysisResult =
|
||||||
|
TopDownAnalyzerFacadeForJS.analyzeFiles(
|
||||||
|
files,
|
||||||
|
project,
|
||||||
|
compilerConfiguration,
|
||||||
|
sortedImmediateDependencies.map { getModuleDescriptor(it) },
|
||||||
|
friendModuleDescriptors = emptyList(),
|
||||||
|
thisIsBuiltInsModule = builtInModuleDescriptor == null,
|
||||||
|
customBuiltInsModule = builtInModuleDescriptor
|
||||||
|
)
|
||||||
|
|
||||||
|
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||||
|
TopDownAnalyzerFacadeForJS.checkForErrors(files, analysisResult.bindingContext)
|
||||||
|
|
||||||
|
return analysisResult
|
||||||
|
}
|
||||||
|
|
||||||
|
private val lookupTracker: LookupTracker = LookupTracker.DO_NOTHING
|
||||||
|
private val metadataVersion: JsKlibMetadataVersion = compilerConfiguration.metadataVersion
|
||||||
|
private val languageVersionSettings: LanguageVersionSettings = compilerConfiguration.languageVersionSettings
|
||||||
|
|
||||||
|
private val storageManager: LockBasedStorageManager = LockBasedStorageManager("ModulesStructure")
|
||||||
|
private var runtimeModule: ModuleDescriptorImpl? = null
|
||||||
|
|
||||||
|
private val descriptors = mutableMapOf<KlibModuleRef, ModuleDescriptorImpl>()
|
||||||
|
|
||||||
|
fun getModuleDescriptor(current: KlibModuleRef): ModuleDescriptorImpl = descriptors.getOrPut(current) {
|
||||||
|
val parts = loadKlibMetadataParts(current)
|
||||||
|
val isBuiltIns = parts.importedModules.isEmpty()
|
||||||
|
loadKlibMetadata(
|
||||||
|
parts,
|
||||||
|
current,
|
||||||
|
isBuiltIns,
|
||||||
|
lookupTracker,
|
||||||
|
storageManager,
|
||||||
|
metadataVersion,
|
||||||
|
languageVersionSettings,
|
||||||
|
runtimeModule,
|
||||||
|
moduleDependencies.getValue(current).map { getModuleDescriptor(it) }
|
||||||
|
).also {
|
||||||
|
if (isBuiltIns) runtimeModule = it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val builtInModuleDescriptor =
|
||||||
|
if (builtInsDep != null)
|
||||||
|
getModuleDescriptor(builtInsDep)
|
||||||
|
else
|
||||||
|
null // null in case compiling builtInModule itself
|
||||||
|
}
|
||||||
|
|
||||||
|
fun serializeModuleIntoKlib(
|
||||||
|
moduleName: String,
|
||||||
|
metadataVersion: JsKlibMetadataVersion,
|
||||||
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
|
bindingContext: BindingContext,
|
||||||
|
klibPath: String,
|
||||||
|
dependencies: List<KlibModuleRef>,
|
||||||
|
moduleFragment: IrModuleFragment
|
||||||
|
) {
|
||||||
|
val declarationTable = JsDeclarationTable(moduleFragment.irBuiltins, DescriptorTable())
|
||||||
|
|
||||||
|
val serializedIr = JsIrModuleSerializer(logggg, declarationTable).serializedIrModule(moduleFragment)
|
||||||
|
val serializer = JsKlibMetadataSerializationUtil
|
||||||
|
|
||||||
|
val moduleDescription =
|
||||||
|
JsKlibMetadataModuleDescriptor(moduleName, dependencies.map { it.moduleName }, moduleFragment.descriptor)
|
||||||
|
val serializedData = serializer.serializeMetadata(
|
||||||
|
bindingContext,
|
||||||
|
moduleDescription,
|
||||||
|
languageVersionSettings,
|
||||||
|
metadataVersion
|
||||||
|
) { declarationDescriptor ->
|
||||||
|
val index = declarationTable.descriptorTable.get(declarationDescriptor)
|
||||||
|
index?.let { newJsDescriptorUniqId(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
val klibDir = File(klibPath).also {
|
||||||
|
it.deleteRecursively()
|
||||||
|
it.mkdirs()
|
||||||
|
}
|
||||||
|
|
||||||
|
val moduleFile = File(klibDir, moduleHeaderFileName)
|
||||||
|
moduleFile.writeBytes(serializedIr.module)
|
||||||
|
|
||||||
|
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())
|
||||||
|
}
|
||||||
|
}
|
||||||
-1
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.backend.common.library.CombinedIrFileReader
|
|||||||
import org.jetbrains.kotlin.backend.common.library.DeclarationId
|
import org.jetbrains.kotlin.backend.common.library.DeclarationId
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.*
|
import org.jetbrains.kotlin.backend.common.serialization.*
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
|
||||||
import org.jetbrains.kotlin.ir.backend.js.JS_KLIBRARY_CAPABILITY
|
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.moduleHeaderFileName
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||||
|
|||||||
@@ -9,14 +9,10 @@ import com.intellij.openapi.Disposable
|
|||||||
import com.intellij.openapi.vfs.StandardFileSystems
|
import com.intellij.openapi.vfs.StandardFileSystems
|
||||||
import com.intellij.openapi.vfs.VirtualFileManager
|
import com.intellij.openapi.vfs.VirtualFileManager
|
||||||
import com.intellij.psi.PsiManager
|
import com.intellij.psi.PsiManager
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
|
||||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||||
import org.jetbrains.kotlin.config.*
|
import org.jetbrains.kotlin.config.*
|
||||||
import org.jetbrains.kotlin.ir.backend.js.CompilationMode
|
import org.jetbrains.kotlin.ir.backend.js.generateKLib
|
||||||
import org.jetbrains.kotlin.ir.backend.js.compile
|
|
||||||
import org.jetbrains.kotlin.ir.backend.js.jsPhases
|
|
||||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||||
import org.jetbrains.kotlin.js.test.JsIrTestRuntime
|
import org.jetbrains.kotlin.js.test.JsIrTestRuntime
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
@@ -60,13 +56,10 @@ fun main() {
|
|||||||
|
|
||||||
|
|
||||||
fun buildKlib(sources: List<String>, outputPath: String) {
|
fun buildKlib(sources: List<String>, outputPath: String) {
|
||||||
val configuration = buildConfiguration(environment)
|
generateKLib(
|
||||||
compile(
|
|
||||||
project = environment.project,
|
project = environment.project,
|
||||||
files = sources.map(::createPsiFile),
|
files = sources.map(::createPsiFile),
|
||||||
configuration = configuration,
|
configuration = buildConfiguration(environment),
|
||||||
phaseConfig = configuration.get(CLIConfigurationKeys.PHASE_CONFIG) ?: PhaseConfig(jsPhases),
|
|
||||||
compileMode = CompilationMode.KLIB,
|
|
||||||
immediateDependencies = emptyList(),
|
immediateDependencies = emptyList(),
|
||||||
allDependencies = emptyList(),
|
allDependencies = emptyList(),
|
||||||
outputKlibPath = outputPath
|
outputKlibPath = outputPath
|
||||||
|
|||||||
@@ -109,25 +109,30 @@ abstract class BasicIrBoxTest(
|
|||||||
if (!isMainModule) it.replace("_v5.js", "/") else it
|
if (!isMainModule) it.replace("_v5.js", "/") else it
|
||||||
}
|
}
|
||||||
|
|
||||||
val result: TranslationResult = compile(
|
if (isMainModule) {
|
||||||
project = config.project,
|
val jsCode = compile(
|
||||||
files = filesToCompile,
|
project = config.project,
|
||||||
configuration = config.configuration,
|
files = filesToCompile,
|
||||||
phaseConfig = config.configuration.get(CLIConfigurationKeys.PHASE_CONFIG) ?: PhaseConfig(jsPhases),
|
configuration = config.configuration,
|
||||||
compileMode = if (isMainModule) CompilationMode.JS else CompilationMode.KLIB,
|
phaseConfig = config.configuration.get(CLIConfigurationKeys.PHASE_CONFIG) ?: PhaseConfig(jsPhases),
|
||||||
immediateDependencies = dependencies,
|
immediateDependencies = dependencies,
|
||||||
allDependencies = allDependencies,
|
allDependencies = allDependencies
|
||||||
outputKlibPath = actualOutputFile
|
)
|
||||||
)
|
|
||||||
|
|
||||||
val moduleName = config.configuration.get(CommonConfigurationKeys.MODULE_NAME) as String
|
val wrappedCode = wrapWithModuleEmulationMarkers(jsCode, moduleId = config.moduleId, moduleKind = config.moduleKind)
|
||||||
val module = KlibModuleRef(moduleName, actualOutputFile)
|
|
||||||
|
|
||||||
compilationCache[outputFile.name.replace(".js", ".meta.js")] = module
|
|
||||||
|
|
||||||
if (result is TranslationResult.CompiledJsCode) {
|
|
||||||
val wrappedCode = wrapWithModuleEmulationMarkers(result.jsCode, moduleId = config.moduleId, moduleKind = config.moduleKind)
|
|
||||||
outputFile.write(wrappedCode)
|
outputFile.write(wrappedCode)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
val module = generateKLib(
|
||||||
|
project = config.project,
|
||||||
|
files = filesToCompile,
|
||||||
|
configuration = config.configuration,
|
||||||
|
immediateDependencies = dependencies,
|
||||||
|
allDependencies = allDependencies,
|
||||||
|
outputKlibPath = actualOutputFile
|
||||||
|
)
|
||||||
|
|
||||||
|
compilationCache[outputFile.name.replace(".js", ".meta.js")] = module
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user