[JS IR] save the desired JS output file name in the klib.

This is only usedful for code splitting. The output .js file name
is provided by the build system during the module compilation.
It is desirable to keep the .js output file names same as in old BE,
but calculating those name during the klib -> js phase is tricky.

Thus the desired names are saved in the klib, and used later on.
This commit is contained in:
Anton Bannykh
2020-09-30 13:35:36 +03:00
committed by TeamCityServer
parent 6633a9edc0
commit 7bd9462ffb
7 changed files with 51 additions and 20 deletions
@@ -205,8 +205,8 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
friendDependencies = friendDependencies,
irFactory = PersistentIrFactory(), // TODO IrFactoryImpl?
outputKlibPath = outputFile.path,
nopack = arguments.irProduceKlibDir
)
nopack = arguments.irProduceKlibDir,
jsOutputName = FileUtil.getNameWithoutExtension(outputFile),)
}
if (arguments.irProduceJs) {
@@ -54,7 +54,7 @@ fun compile(
propertyLazyInitialization: Boolean,
legacyPropertyAccess: Boolean = false,
): CompilerResult {
val (moduleFragment: IrModuleFragment, dependencyModules, irBuiltIns, symbolTable, deserializer) =
val (moduleFragment: IrModuleFragment, dependencyModules, irBuiltIns, symbolTable, deserializer, moduleToName) =
loadIr(project, mainModule, analyzer, configuration, allDependencies, friendDependencies, irFactory)
val moduleDescriptor = moduleFragment.descriptor
@@ -109,7 +109,8 @@ fun compile(
fullJs = true,
dceJs = false,
multiModule = multiModule,
relativeRequirePath = relativeRequirePath
relativeRequirePath = relativeRequirePath,
moduleToName = moduleToName,
)
return transformer.generateModule(allModules)
} else {
@@ -120,7 +121,8 @@ fun compile(
fullJs = generateFullJs,
dceJs = generateDceJs,
multiModule = multiModule,
relativeRequirePath = relativeRequirePath
relativeRequirePath = relativeRequirePath,
moduleToName = moduleToName,
)
return transformer.generateModule(allModules)
}
@@ -31,7 +31,8 @@ class IrModuleToJsTransformer(
private val fullJs: Boolean = true,
private val dceJs: Boolean = false,
private val multiModule: Boolean = false,
private val relativeRequirePath: Boolean = false
private val relativeRequirePath: Boolean = false,
private val moduleToName: Map<IrModuleFragment, String> = emptyMap()
) {
private val generateRegionComments = backendContext.configuration.getBoolean(JSConfigurationKeys.GENERATE_REGION_COMMENTS)
@@ -91,7 +92,7 @@ class IrModuleToJsTransformer(
)
val dependencies = others.mapIndexed { index, module ->
val moduleName = sanitizeName(module.safeName)
val moduleName = moduleToName[module] ?: sanitizeName(module.safeName)
val exportedDeclarations = ExportModelGenerator(backendContext).let { module.files.flatMap { file -> it.generateExport(file) } }
@@ -206,7 +207,7 @@ class IrModuleToJsTransformer(
}
val moduleName = declareFreshGlobal(module.safeName)
modules += JsImportedModule(moduleName.ident, moduleName, moduleName.makeRef(), relativeRequirePath)
modules += JsImportedModule(moduleToName[module] ?: moduleName.ident, moduleName, moduleName.makeRef(), relativeRequirePath)
names.forEach {
imports += JsVars(JsVars.JsVar(JsName(it), JsNameRef(it, JsNameRef("\$crossModule\$", moduleName.makeRef()))))
@@ -70,6 +70,7 @@ import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.utils.DFS
import java.io.File
import java.util.*
import org.jetbrains.kotlin.konan.file.File as KFile
val KotlinLibrary.moduleName: String
@@ -104,7 +105,8 @@ fun generateKLib(
friendDependencies: List<KotlinLibrary>,
irFactory: IrFactory,
outputKlibPath: String,
nopack: Boolean
nopack: Boolean,
jsOutputName: String?,
) {
val incrementalDataProvider = configuration.get(JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER)
val errorPolicy = configuration.get(JSConfigurationKeys.ERROR_TOLERANCE_POLICY) ?: ErrorTolerancePolicy.DEFAULT
@@ -194,7 +196,8 @@ fun generateKLib(
icData,
nopack,
perFile = false,
hasErrors
hasErrors,
jsOutputName
)
}
@@ -203,7 +206,8 @@ data class IrModuleInfo(
val allDependencies: List<IrModuleFragment>,
val bultins: IrBuiltIns,
val symbolTable: SymbolTable,
val deserializer: JsIrLinker
val deserializer: JsIrLinker,
val moduleFragmentToUniqueName: Map<IrModuleFragment, String>,
)
private fun sortDependencies(dependencies: List<KotlinLibrary>, mapping: Map<KotlinLibrary, ModuleDescriptor>): Collection<KotlinLibrary> {
@@ -238,9 +242,14 @@ fun loadIr(
val feContext = psi2IrContext.run {
JsIrLinker.JsFePluginContext(moduleDescriptor, symbolTable, typeTranslator, irBuiltIns)
}
val moduleFragmentToUniqueName = mutableMapOf<IrModuleFragment, String>()
val irLinker = JsIrLinker(psi2IrContext.moduleDescriptor, messageLogger, irBuiltIns, symbolTable, functionFactory, feContext, null)
val deserializedModuleFragments = sortDependencies(allDependencies.getFullList(), depsDescriptors.descriptors).map {
irLinker.deserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(it), it)
val deserializedModuleFragments = sortDependencies(allDependencies.getFullList(), depsDescriptors.descriptors).map { klib ->
irLinker.deserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(klib), klib).also { moduleFragment ->
klib.manifestProperties.getProperty(KLIB_PROPERTY_JS_OUTPUT_NAME)?.let {
moduleFragmentToUniqueName[moduleFragment] = it
}
}
}
val moduleFragment = psi2IrContext.generateModuleFragmentWithPlugins(project, mainModule.files, irLinker, messageLogger)
@@ -257,7 +266,7 @@ fun loadIr(
irBuiltIns.knownBuiltins.forEach { it.acceptVoid(mangleChecker) }
return IrModuleInfo(moduleFragment, deserializedModuleFragments, irBuiltIns, symbolTable, irLinker)
return IrModuleInfo(moduleFragment, deserializedModuleFragments, irBuiltIns, symbolTable, irLinker, moduleFragmentToUniqueName)
}
is MainModule.Klib -> {
val moduleDescriptor = depsDescriptors.getModuleDescriptor(mainModule.lib)
@@ -271,14 +280,20 @@ fun loadIr(
val irLinker =
JsIrLinker(null, messageLogger, irBuiltIns, symbolTable, functionFactory, null, null)
val deserializedModuleFragments = sortDependencies(allDependencies.getFullList(), depsDescriptors.descriptors).map {
val moduleFragmentToUniqueName = mutableMapOf<IrModuleFragment, String>()
val deserializedModuleFragments = sortDependencies(allDependencies.getFullList(), depsDescriptors.descriptors).map { klib ->
val strategy =
if (it == mainModule.lib)
DeserializationStrategy.ALL
else
DeserializationStrategy.EXPLICITLY_EXPORTED
irLinker.deserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(it), it, strategy)
irLinker.deserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(klib), klib, strategy).also { moduleFragment ->
klib.manifestProperties.getProperty(KLIB_PROPERTY_JS_OUTPUT_NAME)?.let {
moduleFragmentToUniqueName[moduleFragment] = it
}
}
}
irBuiltIns.functionFactory = functionFactory
@@ -288,7 +303,7 @@ fun loadIr(
ExternalDependenciesGenerator(symbolTable, listOf(irLinker)).generateUnboundSymbolsAsDependencies()
irLinker.postProcess()
return IrModuleInfo(moduleFragment, deserializedModuleFragments, irBuiltIns, symbolTable, irLinker)
return IrModuleInfo(moduleFragment, deserializedModuleFragments, irBuiltIns, symbolTable, irLinker, moduleFragmentToUniqueName)
}
}
}
@@ -475,7 +490,8 @@ fun serializeModuleIntoKlib(
cleanFiles: List<KotlinFileSerializedData>,
nopack: Boolean,
perFile: Boolean,
containsErrorCode: Boolean = false
containsErrorCode: Boolean = false,
jsOutputName: String?,
) {
assert(files.size == moduleFragment.files.size)
@@ -551,6 +567,14 @@ fun serializeModuleIntoKlib(
}
} else null
val properties = Properties().also { p ->
if (jsOutputName != null) {
p.setProperty(KLIB_PROPERTY_JS_OUTPUT_NAME, jsOutputName)
}
if (containsErrorCode) {
p.setProperty(KLIB_PROPERTY_CONTAINS_ERROR_CODE, "true")
}
buildKotlinLibrary(
linkDependencies = dependencies,
ir = fullSerializedIr,
@@ -566,6 +590,8 @@ fun serializeModuleIntoKlib(
)
}
const val KLIB_PROPERTY_JS_OUTPUT_NAME = "jsOutputName"
private fun KlibMetadataIncrementalSerializer.serializeScope(
ktFile: KtFile,
bindingContext: BindingContext,
@@ -491,7 +491,8 @@ class GenerateIrRuntime {
mutableMapOf(),
emptyList(),
true,
perFile
perFile,
null
)
return tmpKlibDir
@@ -188,7 +188,8 @@ abstract class BasicIrBoxTest(
friendDependencies = emptyList(),
irFactory = IrFactoryImpl,
outputKlibPath = actualOutputFile,
nopack = true
nopack = true,
null
)
logger.logFile("Output klib", File(actualOutputFile))