[JS IR BE] Support compilation and tests against klib

This commit is contained in:
Roman Artemev
2019-02-19 22:16:36 +03:00
committed by romanart
parent b99377fd69
commit 079f2534c7
15 changed files with 290 additions and 410 deletions
@@ -56,10 +56,11 @@ object TopDownAnalyzerFacadeForJS {
"Can't simultaneously use custom built-ins module and set current module as built-ins"
}
val projectContext = ProjectContext(project)
val builtIns = if (thisIsBuiltInsModule || customBuiltInsModule != null) {
object : KotlinBuiltIns(projectContext.storageManager) {}
} else {
JsPlatform.builtIns
val builtIns = when {
thisIsBuiltInsModule -> object : KotlinBuiltIns(projectContext.storageManager) {}
customBuiltInsModule != null -> customBuiltInsModule.builtIns
else -> JsPlatform.builtIns
}
val moduleName = configuration[CommonConfigurationKeys.MODULE_NAME]!!
@@ -72,10 +73,6 @@ object TopDownAnalyzerFacadeForJS {
val additionalPackages = mutableListOf<PackageFragmentProvider>()
if (customBuiltInsModule != null) {
builtIns.builtInsModule = customBuiltInsModule
}
if (thisIsBuiltInsModule) {
builtIns.builtInsModule = context.module
additionalPackages += functionInterfacePackageFragmentProvider(context.storageManager, context.module)
@@ -13,13 +13,11 @@ 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.ir.backend.js.CompilationMode
import org.jetbrains.kotlin.ir.backend.js.ModuleType
import org.jetbrains.kotlin.ir.backend.js.compile
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 org.jetbrains.kotlin.test.KotlinTestUtils
import java.io.File
fun buildConfiguration(environment: KotlinCoreEnvironment): CompilerConfiguration {
@@ -42,9 +40,8 @@ fun buildConfiguration(environment: KotlinCoreEnvironment): CompilerConfiguratio
return runtimeConfiguration
}
private val stdKlibFile = File("js/js.translator/testData/out/klibs/stdlib.klib")
private val resultJs = "js/js.translator/testData/out/klibs/result.js"
private val runtimeKlibPath = "js/js.translator/testData/out/klibs/runtime/"
fun main() {
@@ -66,11 +63,8 @@ fun main() {
emptyList(),
CompilationMode.KLIB_WITH_JS,
emptyList(),
null,
ModuleType.TEST_RUNTIME
runtimeKlibPath
)
File(resultJs).writeText(result.generatedCode!!)
// TODO("Write library into $stdKlibFile")
result.generatedCode?.let { File(resultJs).writeText(it) }
}
@@ -5,11 +5,8 @@
package org.jetbrains.kotlin.js.test
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.ir.backend.js.CompilationMode
import org.jetbrains.kotlin.ir.backend.js.ModuleType
import org.jetbrains.kotlin.ir.backend.js.CompiledModule
import org.jetbrains.kotlin.ir.backend.js.compile
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
@@ -17,12 +14,17 @@ 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.KotlinTestUtils
import org.jetbrains.kotlin.test.TargetBackend
import java.io.File
private var runtimeResults = mutableMapOf<JsIrTestRuntime, CompiledModule>()
private val runtimeKlibPath = "js/js.translator/testData/out/klibs/runtime/"
private val JS_IR_RUNTIME_MODULE_NAME = "JS_IR_RUNTIME"
private val runtimeKlib = CompiledModule(JS_IR_RUNTIME_MODULE_NAME, null, null, runtimeKlibPath, emptyList(), true)
abstract class BasicIrBoxTest(
pathToTestDir: String,
testGroupOutputDirPrefix: String,
@@ -80,31 +82,8 @@ abstract class BasicIrBoxTest(
)
)
val runtimeConfiguration = config.configuration.copy()
// TODO: is it right in general? Maybe sometimes we need to compile with newer versions or with additional language features.
runtimeConfiguration.languageVersionSettings = LanguageVersionSettingsImpl(
LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE,
specificFeatures = mapOf(
LanguageFeature.AllowContractsForCustomFunctions to LanguageFeature.State.ENABLED,
LanguageFeature.MultiPlatformProjects to LanguageFeature.State.ENABLED
),
analysisFlags = mapOf(
AnalysisFlags.useExperimental to listOf("kotlin.contracts.ExperimentalContracts", "kotlin.Experimental"),
AnalysisFlags.allowResultReturnType to true
)
)
val runtimeFile = File(runtime.path)
val runtimeResult = runtimeResults.getOrPut(runtime) {
runtimeConfiguration.put(CommonConfigurationKeys.MODULE_NAME, "JS_IR_RUNTIME")
val result = compile(config.project, runtime.sources.map(::createPsiFile), runtimeConfiguration, moduleType = ModuleType.TEST_RUNTIME)
runtimeFile.write(result.generatedCode!!)
result
}
val dependencyNames = config.configuration[JSConfigurationKeys.LIBRARIES]!!.map { File(it).name }
val dependencies = listOf(runtimeResult) + dependencyNames.mapNotNull {
val dependencies = listOf(runtimeKlib) + dependencyNames.mapNotNull {
compilationCache[it]
}
@@ -113,25 +92,26 @@ abstract class BasicIrBoxTest(
// config.configuration.put(CommonConfigurationKeys.PHASES_TO_DUMP_STATE_AFTER, setOf("MultipleCatchesLowering"))
// config.configuration.put(CommonConfigurationKeys.PHASES_TO_VALIDATE, setOf("ALL"))
val actualOutputFile = outputFile.absolutePath.let {
if (!isMainModule) it.replace("_v5.js", "/") else it
}
val result = compile(
config.project,
filesToCompile,
config.configuration,
listOf(FqName((testPackage?.let { "$it." } ?: "") + testFunction)),
CompilationMode.TEST_AGAINST_CACHE,//CompilationMode.TEST_AGAINST_KLIB,
if (isMainModule) CompilationMode.JS_AGAINST_KLIB else CompilationMode.KLIB,
dependencies,
runtimeResult,
moduleType = if (isMainModule) ModuleType.MAIN else ModuleType.SECONDARY
klibPath = actualOutputFile
)
compilationCache[outputFile.name.replace(".js", ".meta.js")] = result
val generatedCode = result.generatedCode
if (generatedCode != null) {
// Prefix to help node.js runner find runtime
val runtimePrefix = "// RUNTIME: [\"${runtimeFile.path}\"]\n"
val wrappedCode = wrapWithModuleEmulationMarkers(generatedCode, moduleId = config.moduleId, moduleKind = config.moduleKind)
outputFile.write(runtimePrefix + wrappedCode)
outputFile.write(wrappedCode)
}
}
@@ -146,7 +126,8 @@ abstract class BasicIrBoxTest(
) {
// TODO: should we do anything special for module systems?
// TODO: return list of js from translateFiles and provide then to this function with other js files
nashornIrJsTestCheckers[runtime]!!.check(jsFiles, testModuleName, null, testFunction, expectedResult, withModuleSystem)
NashornIrJsTestChecker().check(jsFiles, testModuleName, null, testFunction, expectedResult, withModuleSystem)
}
}
@@ -147,20 +147,15 @@ object NashornJsTestChecker : AbstractNashornJsTestChecker() {
}
}
class NashornIrJsTestChecker(private val runtime: JsIrTestRuntime) : AbstractNashornJsTestChecker() {
class NashornIrJsTestChecker : AbstractNashornJsTestChecker() {
override fun createScriptEngineForTest(): ScriptEngine {
val engine = createScriptEngine()
listOf(
listOfNotNull(
BasicBoxTest.TEST_DATA_DIR_PATH + "nashorn-polyfills.js",
"libraries/stdlib/js/src/js/polyfills.js",
runtime.path
"libraries/stdlib/js/src/js/polyfills.js"
).forEach(engine::loadFile)
return engine
}
}
val nashornIrJsTestCheckers = JsIrTestRuntime.values().associate {
it to NashornIrJsTestChecker(it)
}
}