[JS IR BE] Initial support for mudule wrapper generation
This commit is contained in:
@@ -126,6 +126,9 @@ abstract class BasicBoxTest(
|
||||
val testPackage = testFactory.testPackage
|
||||
val testFunction = TEST_FUNCTION
|
||||
|
||||
val mainModuleName = if (TEST_MODULE in modules) TEST_MODULE else DEFAULT_MODULE
|
||||
val mainModule = modules[mainModuleName] ?: error("No module with name \"$mainModuleName\"")
|
||||
|
||||
val generatedJsFiles = orderedModules.asReversed().mapNotNull { module ->
|
||||
val dependencies = module.dependencies.map { modules[it]?.outputFileName(outputDir) + ".meta.js" }
|
||||
val friends = module.friends.map { modules[it]?.outputFileName(outputDir) + ".meta.js" }
|
||||
@@ -135,15 +138,12 @@ abstract class BasicBoxTest(
|
||||
file.parent, module, outputFileName, dependencies, friends, modules.size > 1,
|
||||
!SKIP_SOURCEMAP_REMAPPING.matcher(fileContent).find(),
|
||||
outputPrefixFile, outputPostfixFile, actualMainCallParameters, testPackage, testFunction,
|
||||
runtimeType
|
||||
runtimeType, isMainModule = (mainModuleName == module.name)
|
||||
)
|
||||
|
||||
if (!module.name.endsWith(OLD_MODULE_SUFFIX)) Pair(outputFileName, module) else null
|
||||
}
|
||||
|
||||
val mainModuleName = if (TEST_MODULE in modules) TEST_MODULE else DEFAULT_MODULE
|
||||
val mainModule = modules[mainModuleName] ?: error("No module with name \"$mainModuleName\"")
|
||||
|
||||
val globalCommonFiles = JsTestUtils.getFilesInDirectoryByExtension(COMMON_FILES_DIR_PATH, JavaScript.EXTENSION)
|
||||
val localCommonFile = file.parent + "/" + COMMON_FILES_NAME + JavaScript.DOT_EXTENSION
|
||||
val localCommonFiles = if (File(localCommonFile).exists()) listOf(localCommonFile) else emptyList()
|
||||
@@ -315,7 +315,8 @@ abstract class BasicBoxTest(
|
||||
mainCallParameters: MainCallParameters,
|
||||
testPackage: String?,
|
||||
testFunction: String,
|
||||
runtime: JsIrTestRuntime
|
||||
runtime: JsIrTestRuntime,
|
||||
isMainModule: Boolean
|
||||
) {
|
||||
val kotlinFiles = module.files.filter { it.fileName.endsWith(".kt") }
|
||||
val testFiles = kotlinFiles.map { it.fileName }
|
||||
@@ -337,7 +338,7 @@ abstract class BasicBoxTest(
|
||||
val incrementalData = IncrementalData()
|
||||
translateFiles(
|
||||
psiFiles.map(TranslationUnit::SourceFile), outputFile, config, outputPrefixFile, outputPostfixFile,
|
||||
mainCallParameters, incrementalData, remap, testPackage, testFunction, runtime
|
||||
mainCallParameters, incrementalData, remap, testPackage, testFunction, runtime, isMainModule
|
||||
)
|
||||
|
||||
if (incrementalCompilationChecksEnabled && module.hasFilesToRecompile) {
|
||||
@@ -385,7 +386,7 @@ abstract class BasicBoxTest(
|
||||
|
||||
translateFiles(
|
||||
translationUnits, recompiledOutputFile, recompiledConfig, outputPrefixFile, outputPostfixFile,
|
||||
mainCallParameters, incrementalData, remap, testPackage, testFunction, runtime
|
||||
mainCallParameters, incrementalData, remap, testPackage, testFunction, runtime, false
|
||||
)
|
||||
|
||||
val originalOutput = FileUtil.loadFile(outputFile)
|
||||
@@ -450,7 +451,8 @@ abstract class BasicBoxTest(
|
||||
remap: Boolean,
|
||||
testPackage: String?,
|
||||
testFunction: String,
|
||||
runtime: JsIrTestRuntime
|
||||
runtime: JsIrTestRuntime,
|
||||
isMainModule: Boolean
|
||||
) {
|
||||
val translator = K2JSTranslator(config)
|
||||
val translationResult = translator.translateUnits(ExceptionThrowingReporter, units, mainCallParameters)
|
||||
@@ -467,18 +469,9 @@ abstract class BasicBoxTest(
|
||||
val outputDir = outputFile.parentFile ?: error("Parent file for output file should not be null, outputFilePath: " + outputFile.path)
|
||||
outputFiles.writeAllTo(outputDir)
|
||||
|
||||
if (config.moduleKind == ModuleKind.COMMON_JS) {
|
||||
if (config.moduleKind != ModuleKind.PLAIN) {
|
||||
val content = FileUtil.loadFile(outputFile, true)
|
||||
val wrappedContent = "$KOTLIN_TEST_INTERNAL.beginModule();\n" +
|
||||
"$content\n" +
|
||||
"$KOTLIN_TEST_INTERNAL.endModule(\"${StringUtil.escapeStringCharacters(config.moduleId)}\");"
|
||||
FileUtil.writeToFile(outputFile, wrappedContent)
|
||||
}
|
||||
else if (config.moduleKind == ModuleKind.AMD || config.moduleKind == ModuleKind.UMD) {
|
||||
val content = FileUtil.loadFile(outputFile, true)
|
||||
val wrappedContent = "if (typeof $KOTLIN_TEST_INTERNAL !== \"undefined\") { " +
|
||||
"$KOTLIN_TEST_INTERNAL.setModuleId(\"${StringUtil.escapeStringCharacters(config.moduleId)}\"); }\n" +
|
||||
"$content\n"
|
||||
val wrappedContent = wrapWithModuleEmulationMarkers(content, moduleId = config.moduleId, moduleKind = config.moduleKind)
|
||||
FileUtil.writeToFile(outputFile, wrappedContent)
|
||||
}
|
||||
|
||||
@@ -496,6 +489,28 @@ abstract class BasicBoxTest(
|
||||
checkSourceMap(outputFile, translationResult.program, remap)
|
||||
}
|
||||
|
||||
protected fun wrapWithModuleEmulationMarkers(
|
||||
content: String,
|
||||
moduleKind: ModuleKind,
|
||||
moduleId: String
|
||||
): String {
|
||||
val escapedModuleId = StringUtil.escapeStringCharacters(moduleId)
|
||||
|
||||
return when (moduleKind) {
|
||||
|
||||
ModuleKind.COMMON_JS -> "$KOTLIN_TEST_INTERNAL.beginModule();\n" +
|
||||
"$content\n" +
|
||||
"$KOTLIN_TEST_INTERNAL.endModule(\"$escapedModuleId\");"
|
||||
|
||||
ModuleKind.AMD, ModuleKind.UMD ->
|
||||
"if (typeof $KOTLIN_TEST_INTERNAL !== \"undefined\") { " +
|
||||
"$KOTLIN_TEST_INTERNAL.setModuleId(\"$escapedModuleId\"); }\n" +
|
||||
"$content\n"
|
||||
|
||||
ModuleKind.PLAIN -> content
|
||||
}
|
||||
}
|
||||
|
||||
private fun processJsProgram(program: JsProgram, psiFiles: List<KtFile>) {
|
||||
psiFiles.asSequence()
|
||||
.map { it.text }
|
||||
|
||||
@@ -5,20 +5,21 @@
|
||||
|
||||
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.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.kotlin.ir.backend.js.Result
|
||||
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
|
||||
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, Result>()
|
||||
private var runtimeResults = mutableMapOf<JsIrTestRuntime, CompiledModule>()
|
||||
|
||||
abstract class BasicIrBoxTest(
|
||||
pathToTestDir: String,
|
||||
@@ -41,7 +42,7 @@ abstract class BasicIrBoxTest(
|
||||
// TODO Design incremental compilation for IR and add test support
|
||||
override val incrementalCompilationChecksEnabled = false
|
||||
|
||||
private val compilationCache = mutableMapOf<String, Result>()
|
||||
private val compilationCache = mutableMapOf<String, CompiledModule>()
|
||||
|
||||
override fun doTest(filePath: String, expectedResult: String, mainCallParameters: MainCallParameters, coroutinesPackage: String) {
|
||||
compilationCache.clear()
|
||||
@@ -59,7 +60,8 @@ abstract class BasicIrBoxTest(
|
||||
remap: Boolean,
|
||||
testPackage: String?,
|
||||
testFunction: String,
|
||||
runtime: JsIrTestRuntime
|
||||
runtime: JsIrTestRuntime,
|
||||
isMainModule: Boolean
|
||||
) {
|
||||
val filesToCompile = units
|
||||
.map { (it as TranslationUnit.SourceFile).file }
|
||||
@@ -94,14 +96,15 @@ abstract class BasicIrBoxTest(
|
||||
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)
|
||||
runtimeFile.write(result.generatedCode)
|
||||
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.moduleDescriptor) + dependencyNames.mapNotNull { compilationCache[it]?.moduleDescriptor }
|
||||
val irDependencies = listOf(runtimeResult.moduleFragment) + compilationCache.values.map { it.moduleFragment }
|
||||
val dependencies = listOf(runtimeResult) + dependencyNames.mapNotNull {
|
||||
compilationCache[it]
|
||||
}
|
||||
|
||||
// config.configuration.put(CommonConfigurationKeys.PHASES_TO_DUMP_STATE, setOf("UnitMaterializationLowering"))
|
||||
// config.configuration.put(CommonConfigurationKeys.PHASES_TO_DUMP_STATE_BEFORE, setOf("ReturnableBlockLowering"))
|
||||
@@ -112,18 +115,21 @@ abstract class BasicIrBoxTest(
|
||||
config.project,
|
||||
filesToCompile,
|
||||
config.configuration,
|
||||
FqName((testPackage?.let { "$it." } ?: "") + testFunction),
|
||||
listOf(FqName((testPackage?.let { "$it." } ?: "") + testFunction)),
|
||||
dependencies,
|
||||
irDependencies,
|
||||
runtimeResult.moduleDescriptor as ModuleDescriptorImpl
|
||||
runtimeResult,
|
||||
moduleType = if (isMainModule) ModuleType.MAIN else ModuleType.SECONDARY
|
||||
)
|
||||
|
||||
compilationCache[outputFile.name.replace(".js", ".meta.js")] = result
|
||||
|
||||
// Prefix to help node.js runner find runtime
|
||||
val runtimePrefix = "// RUNTIME: [\"${runtimeFile.path}\"]\n"
|
||||
|
||||
outputFile.write(runtimePrefix + result.generatedCode)
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
override fun runGeneratedCode(
|
||||
@@ -137,7 +143,7 @@ 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, null, null, testFunction, expectedResult, false)
|
||||
nashornIrJsTestCheckers[runtime]!!.check(jsFiles, testModuleName, null, testFunction, expectedResult, withModuleSystem)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1316
|
||||
// MODULE: lib1
|
||||
// FILE: lib1.js
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1316
|
||||
// MODULE: lib-1
|
||||
// FILE: lib-1.js
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1284
|
||||
// MODULE: lib1
|
||||
// FILE: lib1.js
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1283
|
||||
|
||||
// MODULE: lib
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1284
|
||||
// MODULE: lib1
|
||||
// FILE: lib1.kt
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1284
|
||||
// MODULE_KIND: AMD
|
||||
package foo
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1284
|
||||
// MODULE_KIND: AMD
|
||||
package foo
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1286
|
||||
// MODULE_KIND: UMD
|
||||
package foo
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1288
|
||||
// MODULE_KIND: UMD
|
||||
// NO_JS_MODULE_SYSTEM
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1290
|
||||
// MODULE_KIND: AMD
|
||||
// FILE: lib.kt
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1290
|
||||
// FILE: a.kt
|
||||
// MODULE_KIND: UMD
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1284
|
||||
// MODULE_KIND: AMD
|
||||
package foo
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1283
|
||||
// MODULE_KIND: COMMON_JS
|
||||
// FUNCTION_CALLED_TIMES: require count=2
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1282
|
||||
// MODULE: lib
|
||||
// FILE: lib.kt
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1284
|
||||
// MODULE: lib
|
||||
// FILE: lib.kt
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1282
|
||||
// MODULE: lib
|
||||
// FILE: lib.kt
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1289
|
||||
// MODULE: lib
|
||||
// FILE: lib.kt
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1284
|
||||
// MODULE: module-1
|
||||
// FILE: bar.kt
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1284
|
||||
// MODULE: module1
|
||||
// FILE: bar.kt
|
||||
|
||||
js/js.translator/testData/box/multiModuleWrappers/common_js/inlineFromModuleWithNonIdentifierName.kt
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1284
|
||||
// MODULE: #my-libr@ry
|
||||
// FILE: bar.kt
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1285
|
||||
// MODULE: module-1
|
||||
// FILE: bar.kt
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1285
|
||||
// MODULE: module1
|
||||
// FILE: bar.kt
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1286
|
||||
// MODULE: module-1
|
||||
// FILE: bar.kt
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1286
|
||||
// MODULE: module1
|
||||
// FILE: bar.kt
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1284
|
||||
package foo
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// EXPECTED_REACHABLE_NODES: 1288
|
||||
package foo
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
|
||||
var kotlin;
|
||||
var emulatedModules = { kotlin: kotlin };
|
||||
var module = { exports: {} };
|
||||
var currentModuleId;
|
||||
|
||||
+2
-1
@@ -59,4 +59,5 @@ allFiles.forEach(function(path) {
|
||||
})
|
||||
});
|
||||
|
||||
console.log(vm.runInContext("box()", sandbox));
|
||||
// TODO: Support multimodule tests
|
||||
console.log(vm.runInContext("JS_TESTS.box()", sandbox));
|
||||
|
||||
Reference in New Issue
Block a user