[JS IR BE] Clean up compiler driver api
This is a preparation step for JS-IR CLI: - CompiledModule was overused. Split it into KlibModuleRef and TranslationResult - Deserialize klib dependencies from klibs itself
This commit is contained in:
@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||
import org.jetbrains.kotlin.js.test.JsIrTestRuntime
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
||||
import java.io.File
|
||||
|
||||
fun buildConfiguration(environment: KotlinCoreEnvironment): CompilerConfiguration {
|
||||
val runtimeConfiguration = environment.configuration.copy()
|
||||
@@ -58,17 +57,15 @@ fun main() {
|
||||
|
||||
|
||||
fun buildKlib(sources: List<String>, outputPath: String) {
|
||||
val result = compile(
|
||||
environment.project,
|
||||
sources.map(::createPsiFile),
|
||||
buildConfiguration(environment),
|
||||
emptyList(),
|
||||
CompilationMode.KLIB_WITH_JS,
|
||||
emptyList(),
|
||||
outputPath
|
||||
compile(
|
||||
project = environment.project,
|
||||
files = sources.map(::createPsiFile),
|
||||
configuration = buildConfiguration(environment),
|
||||
compileMode = CompilationMode.KLIB,
|
||||
immediateDependencies = emptyList(),
|
||||
allDependencies = emptyList(),
|
||||
outputKlibPath = outputPath
|
||||
)
|
||||
|
||||
result.generatedCode?.let { File(outputPath, "result.js").writeText(it) }
|
||||
}
|
||||
|
||||
buildKlib(JsIrTestRuntime.FULL.sources, fullRuntimeKlibPath)
|
||||
|
||||
@@ -121,6 +121,10 @@ abstract class BasicBoxTest(
|
||||
.map { it.module }.distinct()
|
||||
.map { it.name to it }.toMap()
|
||||
|
||||
fun TestModule.allTransitiveDependencies(): Set<String> {
|
||||
return dependencies.toSet() + dependencies.flatMap { modules[it]!!.allTransitiveDependencies() }
|
||||
}
|
||||
|
||||
val orderedModules = DFS.topologicalOrder(modules.values) { module -> module.dependencies.mapNotNull { modules[it] } }
|
||||
|
||||
val testPackage = testFactory.testPackage
|
||||
@@ -131,12 +135,13 @@ abstract class BasicBoxTest(
|
||||
|
||||
val generatedJsFiles = orderedModules.asReversed().mapNotNull { module ->
|
||||
val dependencies = module.dependencies.map { modules[it]?.outputFileName(outputDir) + ".meta.js" }
|
||||
val allDependencies = module.allTransitiveDependencies().map { modules[it]?.outputFileName(outputDir) + ".meta.js" }
|
||||
val friends = module.friends.map { modules[it]?.outputFileName(outputDir) + ".meta.js" }
|
||||
|
||||
val outputFileName = module.outputFileName(outputDir) + ".js"
|
||||
val isMainModule = mainModuleName == module.name
|
||||
generateJavaScriptFile(
|
||||
file.parent, module, outputFileName, dependencies, friends, modules.size > 1,
|
||||
file.parent, module, outputFileName, dependencies, allDependencies, friends, modules.size > 1,
|
||||
!SKIP_SOURCEMAP_REMAPPING.matcher(fileContent).find(),
|
||||
outputPrefixFile, outputPostfixFile, actualMainCallParameters, testPackage, testFunction,
|
||||
runtimeType, isMainModule
|
||||
@@ -314,6 +319,7 @@ abstract class BasicBoxTest(
|
||||
module: TestModule,
|
||||
outputFileName: String,
|
||||
dependencies: List<String>,
|
||||
allDependencies: List<String>,
|
||||
friends: List<String>,
|
||||
multiModule: Boolean,
|
||||
remap: Boolean,
|
||||
@@ -339,7 +345,7 @@ abstract class BasicBoxTest(
|
||||
val psiFiles = createPsiFiles(allSourceFiles.sortedBy { it.canonicalPath }.map { it.canonicalPath })
|
||||
|
||||
val sourceDirs = (testFiles + additionalFiles).map { File(it).parent }.distinct()
|
||||
val config = createConfig(sourceDirs, module, dependencies, friends, multiModule, incrementalData = null)
|
||||
val config = createConfig(sourceDirs, module, dependencies, allDependencies, friends, multiModule, incrementalData = null)
|
||||
val outputFile = File(outputFileName)
|
||||
|
||||
val incrementalData = IncrementalData()
|
||||
@@ -350,7 +356,7 @@ abstract class BasicBoxTest(
|
||||
|
||||
if (incrementalCompilationChecksEnabled && module.hasFilesToRecompile) {
|
||||
checkIncrementalCompilation(
|
||||
sourceDirs, module, kotlinFiles, dependencies, friends, multiModule, remap,
|
||||
sourceDirs, module, kotlinFiles, dependencies, allDependencies, friends, multiModule, remap,
|
||||
outputFile, outputPrefixFile, outputPostfixFile, mainCallParameters, incrementalData, testPackage, testFunction, runtime
|
||||
)
|
||||
}
|
||||
@@ -361,6 +367,7 @@ abstract class BasicBoxTest(
|
||||
module: TestModule,
|
||||
kotlinFiles: List<TestFile>,
|
||||
dependencies: List<String>,
|
||||
allDependencies: List<String>,
|
||||
friends: List<String>,
|
||||
multiModule: Boolean,
|
||||
remap: Boolean,
|
||||
@@ -388,7 +395,7 @@ abstract class BasicBoxTest(
|
||||
.sortedBy { it.canonicalPath }
|
||||
.map { sourceToTranslationUnit[it]!! }
|
||||
|
||||
val recompiledConfig = createConfig(sourceDirs, module, dependencies, friends, multiModule, incrementalData)
|
||||
val recompiledConfig = createConfig(sourceDirs, module, dependencies, allDependencies, friends, multiModule, incrementalData)
|
||||
val recompiledOutputFile = File(outputFile.parentFile, outputFile.nameWithoutExtension + "-recompiled.js")
|
||||
|
||||
translateFiles(
|
||||
@@ -593,7 +600,7 @@ abstract class BasicBoxTest(
|
||||
private fun createPsiFiles(fileNames: List<String>): List<KtFile> = fileNames.map(this::createPsiFile)
|
||||
|
||||
private fun createConfig(
|
||||
sourceDirs: List<String>, module: TestModule, dependencies: List<String>, friends: List<String>,
|
||||
sourceDirs: List<String>, module: TestModule, dependencies: List<String>, allDependencies: List<String>, friends: List<String>,
|
||||
multiModule: Boolean, incrementalData: IncrementalData?
|
||||
): JsConfig {
|
||||
val configuration = environment.configuration.copy()
|
||||
@@ -603,7 +610,14 @@ abstract class BasicBoxTest(
|
||||
configuration.languageVersionSettings = languageVersionSettings
|
||||
}
|
||||
|
||||
configuration.put(JSConfigurationKeys.LIBRARIES, JsConfig.JS_STDLIB + JsConfig.JS_KOTLIN_TEST + dependencies)
|
||||
val libraries = when (targetBackend) {
|
||||
TargetBackend.JS_IR -> dependencies
|
||||
TargetBackend.JS -> JsConfig.JS_STDLIB + JsConfig.JS_KOTLIN_TEST + dependencies
|
||||
else -> error("Unsupported target backend: $targetBackend")
|
||||
}
|
||||
|
||||
configuration.put(JSConfigurationKeys.LIBRARIES, libraries)
|
||||
configuration.put(JSConfigurationKeys.TRANSITIVE_LIBRARIES, allDependencies)
|
||||
configuration.put(JSConfigurationKeys.FRIEND_PATHS, friends)
|
||||
|
||||
configuration.put(CommonConfigurationKeys.MODULE_NAME, module.name.removeSuffix(OLD_MODULE_SUFFIX))
|
||||
|
||||
@@ -5,14 +5,15 @@
|
||||
|
||||
package org.jetbrains.kotlin.js.test
|
||||
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.ir.backend.js.CompilationMode
|
||||
import org.jetbrains.kotlin.ir.backend.js.CompiledModule
|
||||
import org.jetbrains.kotlin.ir.backend.js.KlibModuleRef
|
||||
import org.jetbrains.kotlin.ir.backend.js.TranslationResult
|
||||
import org.jetbrains.kotlin.ir.backend.js.compile
|
||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||
import org.jetbrains.kotlin.js.config.JsConfig
|
||||
import org.jetbrains.kotlin.js.facade.MainCallParameters
|
||||
import org.jetbrains.kotlin.js.facade.TranslationUnit
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
import java.io.File
|
||||
|
||||
@@ -21,8 +22,8 @@ private val defaultRuntimeKlibPath = "js/js.translator/testData/out/klibs/runtim
|
||||
|
||||
private val JS_IR_RUNTIME_MODULE_NAME = "JS_IR_RUNTIME"
|
||||
|
||||
private val fullRuntimeKlib = CompiledModule(JS_IR_RUNTIME_MODULE_NAME, null, null, fullRuntimeKlibPath, emptyList(), true)
|
||||
private val defaultRuntimeKlib = CompiledModule(JS_IR_RUNTIME_MODULE_NAME, null, null, defaultRuntimeKlibPath, emptyList(), true)
|
||||
private val fullRuntimeKlib = KlibModuleRef(JS_IR_RUNTIME_MODULE_NAME, fullRuntimeKlibPath)
|
||||
private val defaultRuntimeKlib = KlibModuleRef(JS_IR_RUNTIME_MODULE_NAME, defaultRuntimeKlibPath)
|
||||
|
||||
abstract class BasicIrBoxTest(
|
||||
pathToTestDir: String,
|
||||
@@ -45,7 +46,7 @@ abstract class BasicIrBoxTest(
|
||||
// TODO Design incremental compilation for IR and add test support
|
||||
override val incrementalCompilationChecksEnabled = false
|
||||
|
||||
private val compilationCache = mutableMapOf<String, CompiledModule>()
|
||||
private val compilationCache = mutableMapOf<String, KlibModuleRef>()
|
||||
|
||||
override fun doTest(filePath: String, expectedResult: String, mainCallParameters: MainCallParameters, coroutinesPackage: String) {
|
||||
compilationCache.clear()
|
||||
@@ -84,11 +85,18 @@ abstract class BasicIrBoxTest(
|
||||
// )
|
||||
// )
|
||||
|
||||
val runtimeKlib = runtimes[runtime]
|
||||
val runtimeKlib = runtimes[runtime]!!
|
||||
|
||||
val dependencyNames = config.configuration[JSConfigurationKeys.LIBRARIES]!!.map { File(it).name }
|
||||
val dependencies = listOfNotNull(runtimeKlib) + dependencyNames.mapNotNull {
|
||||
compilationCache[it]
|
||||
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 = listOf(runtimeKlib) + libraries.map {
|
||||
compilationCache[it] ?: error("Can't find compiled module for dependency $it")
|
||||
}
|
||||
|
||||
val allDependencies = listOf(runtimeKlib) + transitiveLibraries.map {
|
||||
compilationCache[it] ?: error("Can't find compiled module for dependency $it")
|
||||
}
|
||||
|
||||
// config.configuration.put(CommonConfigurationKeys.PHASES_TO_DUMP_STATE, setOf("UnitMaterializationLowering"))
|
||||
@@ -100,21 +108,23 @@ abstract class BasicIrBoxTest(
|
||||
if (!isMainModule) it.replace("_v5.js", "/") else it
|
||||
}
|
||||
|
||||
val result = compile(
|
||||
config.project,
|
||||
filesToCompile,
|
||||
config.configuration,
|
||||
listOf(FqName((testPackage?.let { "$it." } ?: "") + testFunction)),
|
||||
if (isMainModule) CompilationMode.JS_AGAINST_KLIB else CompilationMode.KLIB,
|
||||
dependencies,
|
||||
actualOutputFile
|
||||
val result: TranslationResult = compile(
|
||||
project = config.project,
|
||||
files = filesToCompile,
|
||||
configuration = config.configuration,
|
||||
compileMode = if (isMainModule) CompilationMode.JS else CompilationMode.KLIB,
|
||||
immediateDependencies = dependencies,
|
||||
allDependencies = allDependencies,
|
||||
outputKlibPath = actualOutputFile
|
||||
)
|
||||
|
||||
compilationCache[outputFile.name.replace(".js", ".meta.js")] = result
|
||||
val moduleName = config.configuration.get(CommonConfigurationKeys.MODULE_NAME) as String
|
||||
val module = KlibModuleRef(moduleName, actualOutputFile)
|
||||
|
||||
val generatedCode = result.generatedCode
|
||||
if (generatedCode != null) {
|
||||
val wrappedCode = wrapWithModuleEmulationMarkers(generatedCode, moduleId = config.moduleId, moduleKind = config.moduleKind)
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user