[JS IR] Cleanup pir IC code
This commit is contained in:
@@ -5,13 +5,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.backend.js
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.lower
|
||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity
|
||||
import org.jetbrains.kotlin.ir.backend.js.ic.icCompile
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.generateJsTests
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.moveBodilessDeclarationsToSeparatePlace
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker
|
||||
@@ -20,8 +18,6 @@ import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.TranslationMode
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.NameTables
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFactory
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.StageController
|
||||
import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrFactory
|
||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.noUnboundLeft
|
||||
@@ -53,13 +49,11 @@ fun compile(
|
||||
phaseConfig: PhaseConfig,
|
||||
irFactory: IrFactory,
|
||||
exportedDeclarations: Set<FqName> = emptySet(),
|
||||
dceDriven: Boolean = false,
|
||||
dceRuntimeDiagnostic: RuntimeDiagnostic? = null,
|
||||
es6mode: Boolean = false,
|
||||
propertyLazyInitialization: Boolean,
|
||||
verifySignatures: Boolean = true,
|
||||
baseClassIntoMetadata: Boolean = false,
|
||||
lowerPerModule: Boolean = false,
|
||||
safeExternalBoolean: Boolean = false,
|
||||
safeExternalBooleanDiagnostic: RuntimeDiagnostic? = null,
|
||||
filesToLower: Set<String>? = null,
|
||||
@@ -67,20 +61,7 @@ fun compile(
|
||||
icCompatibleIr2Js: Boolean = false,
|
||||
): LoweredIr {
|
||||
|
||||
if (lowerPerModule) {
|
||||
return icCompile(
|
||||
depsDescriptors,
|
||||
exportedDeclarations,
|
||||
dceRuntimeDiagnostic,
|
||||
es6mode,
|
||||
propertyLazyInitialization,
|
||||
baseClassIntoMetadata,
|
||||
safeExternalBoolean,
|
||||
safeExternalBooleanDiagnostic,
|
||||
)
|
||||
}
|
||||
|
||||
val (moduleFragment: IrModuleFragment, dependencyModules, irBuiltIns, symbolTable, deserializer, _) =
|
||||
val (moduleFragment: IrModuleFragment, dependencyModules, irBuiltIns, symbolTable, deserializer) =
|
||||
loadIr(depsDescriptors, irFactory, verifySignatures, filesToLower, loadFunctionInterfacesIntoStdlib = true)
|
||||
|
||||
return compileIr(
|
||||
@@ -93,12 +74,10 @@ fun compile(
|
||||
deserializer,
|
||||
phaseConfig,
|
||||
exportedDeclarations,
|
||||
dceDriven,
|
||||
dceRuntimeDiagnostic,
|
||||
es6mode,
|
||||
propertyLazyInitialization,
|
||||
baseClassIntoMetadata,
|
||||
lowerPerModule,
|
||||
safeExternalBoolean,
|
||||
safeExternalBooleanDiagnostic,
|
||||
granularity,
|
||||
@@ -116,12 +95,10 @@ fun compileIr(
|
||||
deserializer: JsIrLinker,
|
||||
phaseConfig: PhaseConfig,
|
||||
exportedDeclarations: Set<FqName>,
|
||||
dceDriven: Boolean,
|
||||
dceRuntimeDiagnostic: RuntimeDiagnostic?,
|
||||
es6mode: Boolean,
|
||||
propertyLazyInitialization: Boolean,
|
||||
baseClassIntoMetadata: Boolean,
|
||||
lowerPerModule: Boolean,
|
||||
safeExternalBoolean: Boolean,
|
||||
safeExternalBooleanDiagnostic: RuntimeDiagnostic?,
|
||||
granularity: JsGenerationGranularity,
|
||||
@@ -170,55 +147,13 @@ fun compileIr(
|
||||
// TODO should be done incrementally
|
||||
generateJsTests(context, allModules.last())
|
||||
|
||||
if (dceDriven) {
|
||||
val controller = MutableController(context, pirLowerings)
|
||||
|
||||
check(irFactory is PersistentIrFactory)
|
||||
irFactory.stageController = controller
|
||||
|
||||
controller.currentStage = controller.lowerings.size + 1
|
||||
|
||||
eliminateDeadDeclarations(allModules, context)
|
||||
|
||||
irFactory.stageController = StageController(controller.currentStage)
|
||||
} else {
|
||||
// TODO is this reachable when lowerPerModule == true?
|
||||
if (lowerPerModule) {
|
||||
val controller = WholeWorldStageController()
|
||||
check(irFactory is PersistentIrFactory)
|
||||
irFactory.stageController = controller
|
||||
allModules.forEach {
|
||||
lowerPreservingIcData(it, context, controller)
|
||||
}
|
||||
irFactory.stageController = object : StageController(irFactory.stageController.currentStage) {}
|
||||
} else {
|
||||
(irFactory.stageController as? WholeWorldStageController)?.let {
|
||||
lowerPreservingTags(allModules, context, phaseConfig, it)
|
||||
} ?: jsPhases.invokeToplevel(phaseConfig, context, allModules)
|
||||
}
|
||||
}
|
||||
(irFactory.stageController as? WholeWorldStageController)?.let {
|
||||
lowerPreservingTags(allModules, context, phaseConfig, it)
|
||||
} ?: jsPhases.invokeToplevel(phaseConfig, context, allModules)
|
||||
|
||||
return LoweredIr(context, moduleFragment, allModules)
|
||||
}
|
||||
|
||||
fun lowerPreservingIcData(module: IrModuleFragment, context: JsIrBackendContext, controller: WholeWorldStageController) {
|
||||
// Lower all the things
|
||||
controller.currentStage = 0
|
||||
|
||||
pirLowerings.forEachIndexed { i, lowering ->
|
||||
controller.currentStage = i + 1
|
||||
when (lowering) {
|
||||
is DeclarationLowering ->
|
||||
lowering.declarationTransformer(context).lower(module)
|
||||
is BodyLowering ->
|
||||
lowering.bodyLowering(context).lower(module)
|
||||
is ModuleLowering -> { /*TODO what about other lowerings? */ }
|
||||
}
|
||||
}
|
||||
|
||||
controller.currentStage = pirLowerings.size + 1
|
||||
}
|
||||
|
||||
fun generateJsCode(
|
||||
context: JsIrBackendContext,
|
||||
moduleFragment: IrModuleFragment,
|
||||
|
||||
@@ -5,123 +5,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.backend.js.ic
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.ir.backend.js.MainModule
|
||||
import org.jetbrains.kotlin.ir.backend.js.toByteArray
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import java.io.File
|
||||
import java.io.PrintWriter
|
||||
import java.security.MessageDigest
|
||||
import kotlin.random.Random
|
||||
import kotlin.random.nextULong
|
||||
|
||||
// TODO: Proper version of the compiler (should take changes to lowerings into account)
|
||||
private val compilerVersion = Random.nextULong()
|
||||
|
||||
private fun IcCacheInfo.toICCacheMap(): Map<String, ICCache> {
|
||||
return data.map { it.key to ICCache(PersistentCacheProvider.EMPTY, PersistentCacheConsumer.EMPTY, it.value) }.toMap()
|
||||
}
|
||||
|
||||
// TODO more parameters for lowerings
|
||||
// Returns true if caches were built. False if caches were up-to-date.
|
||||
fun buildCache(
|
||||
cachePath: String,
|
||||
project: Project,
|
||||
mainModule: MainModule.Klib,
|
||||
configuration: CompilerConfiguration,
|
||||
dependencies: Collection<String>,
|
||||
friendDependencies: Collection<String>,
|
||||
exportedDeclarations: Set<FqName> = emptySet(),
|
||||
forceClean: Boolean = false,
|
||||
icCache: IcCacheInfo = IcCacheInfo.EMPTY,
|
||||
): Boolean {
|
||||
val dependencyHashes = dependencies.mapNotNull {
|
||||
val path = File(it).canonicalPath
|
||||
icCache.md5[path]
|
||||
} + compilerVersion
|
||||
|
||||
val md5 = File(mainModule.libPath).md5(dependencyHashes)
|
||||
|
||||
if (!forceClean) {
|
||||
val oldCacheInfo = CacheInfo.load(cachePath)
|
||||
if (oldCacheInfo != null && md5 == oldCacheInfo.flatHash) return false
|
||||
}
|
||||
|
||||
val icDir = File(cachePath)
|
||||
icDir.listFiles { file: File -> file.name.startsWith("ic-") }!!.forEach { it.deleteRecursively() }
|
||||
File(icDir, "info").delete()
|
||||
icDir.mkdirs()
|
||||
|
||||
val icData = prepareSingleLibraryIcCache(project, configuration, mainModule.libPath, dependencies, friendDependencies, exportedDeclarations, icCache.toICCacheMap())
|
||||
|
||||
icData.serializedIcData.writeTo(File(cachePath))
|
||||
|
||||
CacheInfo(cachePath, mainModule.libPath, md5, 0UL).save()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun File.md5(additional: Iterable<ULong> = emptyList()): ULong {
|
||||
val md5 = MessageDigest.getInstance("MD5")
|
||||
|
||||
for (ul in additional) {
|
||||
md5.update(ul.toLong().toByteArray())
|
||||
}
|
||||
|
||||
fun File.process(prefix: String = "") {
|
||||
if (isDirectory) {
|
||||
this.listFiles()!!.sortedBy { it.name }.forEach {
|
||||
md5.update((prefix + it.name).toByteArray())
|
||||
it.process(prefix + it.name + "/")
|
||||
}
|
||||
} else {
|
||||
md5.update(readBytes())
|
||||
}
|
||||
}
|
||||
|
||||
this.process()
|
||||
|
||||
val d = md5.digest()
|
||||
|
||||
return ((d[0].toULong() and 0xFFUL)
|
||||
or ((d[1].toULong() and 0xFFUL) shl 8)
|
||||
or ((d[2].toULong() and 0xFFUL) shl 16)
|
||||
or ((d[3].toULong() and 0xFFUL) shl 24)
|
||||
or ((d[4].toULong() and 0xFFUL) shl 32)
|
||||
or ((d[5].toULong() and 0xFFUL) shl 40)
|
||||
or ((d[6].toULong() and 0xFFUL) shl 48)
|
||||
or ((d[7].toULong() and 0xFFUL) shl 56)
|
||||
)
|
||||
}
|
||||
|
||||
fun checkCaches(
|
||||
dependencies: Collection<String>,
|
||||
cachePaths: List<String>,
|
||||
skipLib: String? = null,
|
||||
): IcCacheInfo {
|
||||
val skipLibPath = File(skipLib).canonicalPath
|
||||
val allLibs = dependencies.map { File(it).canonicalPath }.toSet() - skipLibPath
|
||||
|
||||
val caches = cachePaths.map { CacheInfo.load(it) ?: error("Cannot load IC cache from ${it}") }
|
||||
|
||||
val missedLibs = allLibs - caches.map { it.libPath }
|
||||
if (!missedLibs.isEmpty()) {
|
||||
error("Missing caches for libraries: ${missedLibs}")
|
||||
}
|
||||
|
||||
val result = mutableMapOf<String, SerializedIcData>()
|
||||
val md5 = mutableMapOf<String, ULong>()
|
||||
|
||||
for (c in caches) {
|
||||
if (c.libPath !in allLibs) error("Missing library: ${c.libPath}")
|
||||
|
||||
result[c.libPath] = File(c.path).readIcData()
|
||||
md5[c.libPath] = c.flatHash
|
||||
}
|
||||
|
||||
return IcCacheInfo(result, md5)
|
||||
}
|
||||
|
||||
// TODO md5 hash
|
||||
data class CacheInfo(val path: String, val libPath: String, var flatHash: ULong, var transHash: ULong) {
|
||||
@@ -145,13 +30,3 @@ data class CacheInfo(val path: String, val libPath: String, var flatHash: ULong,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class IcCacheInfo(
|
||||
val data: Map<String, SerializedIcData>,
|
||||
val md5: Map<String, ULong>,
|
||||
) {
|
||||
companion object {
|
||||
val EMPTY = IcCacheInfo(emptyMap(), emptyMap())
|
||||
}
|
||||
}
|
||||
@@ -1,242 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.ir.backend.js.ic
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.backend.common.lower
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.ir.backend.js.*
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.generateJsTests
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.moveBodilessDeclarationsToSeparatePlace
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.path
|
||||
import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrFactory
|
||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||
import org.jetbrains.kotlin.ir.util.KotlinLikeDumpOptions
|
||||
import org.jetbrains.kotlin.ir.util.dumpKotlinLike
|
||||
import org.jetbrains.kotlin.ir.util.noUnboundLeft
|
||||
import org.jetbrains.kotlin.js.config.RuntimeDiagnostic
|
||||
import org.jetbrains.kotlin.library.resolver.KotlinResolvedLibrary
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import java.io.PrintWriter
|
||||
|
||||
fun prepareSingleLibraryIcCache(
|
||||
project: Project,
|
||||
configuration: CompilerConfiguration,
|
||||
libPath: String,
|
||||
dependencies: Collection<String>,
|
||||
friendDependencies: Collection<String> = emptyList(),
|
||||
exportedDeclarations: Set<FqName> = emptySet(),
|
||||
icCache: Map<String, ICCache> = emptyMap(),
|
||||
): ICCache {
|
||||
val irFactory = PersistentIrFactory()
|
||||
val controller = WholeWorldStageController()
|
||||
irFactory.stageController = controller
|
||||
|
||||
val depsDescriptor = ModulesStructure(
|
||||
project,
|
||||
MainModule.Klib(libPath),
|
||||
configuration,
|
||||
dependencies,
|
||||
friendDependencies,
|
||||
true,
|
||||
true,
|
||||
icCache
|
||||
)
|
||||
val (context, deserializer, allModules) = prepareIr(
|
||||
depsDescriptor,
|
||||
exportedDeclarations,
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
irFactory,
|
||||
)
|
||||
|
||||
val moduleFragment = allModules.last()
|
||||
|
||||
moveBodilessDeclarationsToSeparatePlace(context, moduleFragment)
|
||||
|
||||
// generateTests(context, moduleFragment)
|
||||
|
||||
lowerPreservingIcData(moduleFragment, context, controller)
|
||||
|
||||
return ICCache(
|
||||
PersistentCacheProvider.EMPTY,
|
||||
PersistentCacheConsumer.EMPTY,
|
||||
IcSerializer(
|
||||
context.irBuiltIns,
|
||||
context.mapping,
|
||||
irFactory,
|
||||
deserializer,
|
||||
moduleFragment
|
||||
).serializeDeclarations(irFactory.allDeclarations)
|
||||
)
|
||||
}
|
||||
|
||||
private fun KotlinResolvedLibrary.allDependencies(): List<KotlinResolvedLibrary> {
|
||||
val visited = mutableSetOf<KotlinResolvedLibrary>()
|
||||
|
||||
val result = mutableListOf<KotlinResolvedLibrary>()
|
||||
|
||||
fun KotlinResolvedLibrary.dfs() {
|
||||
visited += this
|
||||
|
||||
resolvedDependencies.forEach {
|
||||
if (it !in visited) {
|
||||
it.dfs()
|
||||
result += it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dfs()
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun dumpIr(module: IrModuleFragment, fileName: String) {
|
||||
val dumpOptions = KotlinLikeDumpOptions(printElseAsTrue = true)
|
||||
|
||||
var actual = ""
|
||||
|
||||
for (file in module.files) {
|
||||
actual += file.path + "\n"
|
||||
actual += run {
|
||||
var r = ""
|
||||
|
||||
file.declarations.map { it.dumpKotlinLike(dumpOptions) }.sorted().forEach { r += it }
|
||||
|
||||
r
|
||||
}
|
||||
actual += "\n"
|
||||
}
|
||||
PrintWriter("/home/ab/vcs/kotlin/$fileName.txt").use {
|
||||
it.print(actual)
|
||||
}
|
||||
}
|
||||
|
||||
fun icCompile(
|
||||
depsDescriptor: ModulesStructure,
|
||||
exportedDeclarations: Set<FqName> = emptySet(),
|
||||
dceRuntimeDiagnostic: RuntimeDiagnostic? = null,
|
||||
es6mode: Boolean = false,
|
||||
propertyLazyInitialization: Boolean,
|
||||
baseClassIntoMetadata: Boolean = false,
|
||||
safeExternalBoolean: Boolean = false,
|
||||
safeExternalBooleanDiagnostic: RuntimeDiagnostic? = null,
|
||||
): LoweredIr {
|
||||
|
||||
val irFactory = PersistentIrFactory()
|
||||
val controller = WholeWorldStageController()
|
||||
irFactory.stageController = controller
|
||||
|
||||
val (context, _, allModules, _, loweredIrLoaded) = prepareIr(
|
||||
depsDescriptor,
|
||||
exportedDeclarations,
|
||||
dceRuntimeDiagnostic,
|
||||
es6mode,
|
||||
propertyLazyInitialization,
|
||||
irFactory,
|
||||
baseClassIntoMetadata,
|
||||
safeExternalBoolean,
|
||||
safeExternalBooleanDiagnostic
|
||||
)
|
||||
|
||||
val modulesToLower = allModules.filter { it !in loweredIrLoaded }
|
||||
|
||||
if (!modulesToLower.isEmpty()) {
|
||||
// This won't work incrementally
|
||||
modulesToLower.forEach { module ->
|
||||
moveBodilessDeclarationsToSeparatePlace(context, module)
|
||||
}
|
||||
|
||||
generateJsTests(context, modulesToLower.last())
|
||||
|
||||
modulesToLower.forEach {
|
||||
lowerPreservingIcData(it, context, controller)
|
||||
}
|
||||
}
|
||||
|
||||
// dumpIr(allModules.first(), "simple-dump${if (useStdlibCache) "-actual" else ""}")
|
||||
|
||||
return LoweredIr(context, allModules.last(), allModules)
|
||||
}
|
||||
|
||||
fun lowerPreservingIcData(module: IrModuleFragment, context: JsIrBackendContext, controller: WholeWorldStageController) {
|
||||
// Lower all the things
|
||||
controller.currentStage = 0
|
||||
|
||||
pirLowerings.forEachIndexed { i, lowering ->
|
||||
controller.currentStage = i + 1
|
||||
when (lowering) {
|
||||
is DeclarationLowering ->
|
||||
lowering.declarationTransformer(context).lower(module)
|
||||
is BodyLowering ->
|
||||
lowering.bodyLowering(context).lower(module)
|
||||
else -> TODO("what about other lowerings?")
|
||||
}
|
||||
}
|
||||
|
||||
controller.currentStage = pirLowerings.size + 1
|
||||
}
|
||||
|
||||
private fun prepareIr(
|
||||
depsDescriptor: ModulesStructure,
|
||||
exportedDeclarations: Set<FqName> = emptySet(),
|
||||
dceRuntimeDiagnostic: RuntimeDiagnostic? = null,
|
||||
es6mode: Boolean = false,
|
||||
propertyLazyInitialization: Boolean,
|
||||
irFactory: PersistentIrFactory,
|
||||
baseClassIntoMetadata: Boolean = false,
|
||||
safeExternalBoolean: Boolean = false,
|
||||
safeExternalBooleanDiagnostic: RuntimeDiagnostic? = null,
|
||||
): PreparedIr {
|
||||
val (moduleFragment: IrModuleFragment, dependencyModules, irBuiltIns, symbolTable, deserializer, moduleToName, loweredIrLoaded) =
|
||||
loadIr(depsDescriptor, irFactory, false)
|
||||
|
||||
val moduleDescriptor = moduleFragment.descriptor
|
||||
|
||||
val allModules = when (depsDescriptor.mainModule) {
|
||||
is MainModule.SourceFiles -> dependencyModules + listOf(moduleFragment)
|
||||
is MainModule.Klib -> dependencyModules
|
||||
}
|
||||
|
||||
val context = JsIrBackendContext(
|
||||
moduleDescriptor,
|
||||
irBuiltIns,
|
||||
symbolTable,
|
||||
allModules.first(),
|
||||
exportedDeclarations,
|
||||
depsDescriptor.compilerConfiguration,
|
||||
es6mode = es6mode,
|
||||
dceRuntimeDiagnostic = dceRuntimeDiagnostic,
|
||||
propertyLazyInitialization = propertyLazyInitialization,
|
||||
baseClassIntoMetadata = baseClassIntoMetadata,
|
||||
safeExternalBoolean = safeExternalBoolean,
|
||||
safeExternalBooleanDiagnostic = safeExternalBooleanDiagnostic,
|
||||
mapping = deserializer.mapping,
|
||||
)
|
||||
|
||||
// Load declarations referenced during `context` initialization
|
||||
val irProviders = listOf(deserializer)
|
||||
ExternalDependenciesGenerator(symbolTable, irProviders).generateUnboundSymbolsAsDependencies()
|
||||
|
||||
deserializer.postProcess()
|
||||
symbolTable.noUnboundLeft("Unbound symbols at the end of linker")
|
||||
|
||||
deserializer.loadIcIr { moveBodilessDeclarationsToSeparatePlace(context, it) }
|
||||
|
||||
return PreparedIr(context, deserializer, allModules, moduleToName, loweredIrLoaded)
|
||||
}
|
||||
|
||||
data class PreparedIr(
|
||||
val context: JsIrBackendContext,
|
||||
val linker: JsIrLinker,
|
||||
val allModules: List<IrModuleFragment>,
|
||||
val moduleToName: Map<IrModuleFragment, String>,
|
||||
val loweredIrLoaded: Set<IrModuleFragment>,
|
||||
)
|
||||
@@ -252,7 +252,7 @@ private fun createLinker(
|
||||
val moduleDescriptor = loadedModules.keys.last()
|
||||
val typeTranslator = TypeTranslatorImpl(symbolTable, configuration.languageVersionSettings, moduleDescriptor)
|
||||
val irBuiltIns = IrBuiltInsOverDescriptors(moduleDescriptor.builtIns, typeTranslator, symbolTable)
|
||||
return JsIrLinker(null, logger, irBuiltIns, symbolTable, null, null)
|
||||
return JsIrLinker(null, logger, irBuiltIns, symbolTable, null)
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user