JS IR: per-module .js generation support
This commit is contained in:
@@ -16,8 +16,17 @@
|
||||
|
||||
package org.jetbrains.kotlin.js.backend.ast
|
||||
|
||||
class JsImportedModule(val externalName: String, var internalName: JsName, val plainReference: JsExpression?) {
|
||||
|
||||
class JsImportedModule @JvmOverloads constructor(
|
||||
val externalName: String,
|
||||
var internalName: JsName,
|
||||
val plainReference: JsExpression?,
|
||||
val relativeRequirePath: Boolean = false
|
||||
) {
|
||||
val key = JsImportedModuleKey(externalName, plainReference?.toString())
|
||||
}
|
||||
|
||||
val JsImportedModule.requireName: String
|
||||
get() = if (relativeRequirePath) "./$externalName.js" else externalName
|
||||
|
||||
data class JsImportedModuleKey(val baseName: String, val plainName: String?)
|
||||
@@ -129,6 +129,7 @@ abstract class BasicBoxTest(
|
||||
val expectActualLinker = EXPECT_ACTUAL_LINKER.matcher(fileContent).find()
|
||||
|
||||
val skipDceDriven = SKIP_DCE_DRIVEN.matcher(fileContent).find()
|
||||
val splitPerModule = SPLIT_PER_MODULE.matcher(fileContent).find()
|
||||
|
||||
TestFileFactoryImpl(coroutinesPackage).use { testFactory ->
|
||||
val inputFiles = TestFiles.createTestFiles(
|
||||
@@ -173,7 +174,7 @@ abstract class BasicBoxTest(
|
||||
testFactory.tmpDir,
|
||||
file.parent, module, outputFileName, dceOutputFileName, pirOutputFileName, dependencies, allDependencies, friends, modules.size > 1,
|
||||
!SKIP_SOURCEMAP_REMAPPING.matcher(fileContent).find(), outputPrefixFile, outputPostfixFile,
|
||||
actualMainCallParameters, testPackage, testFunction, needsFullIrRuntime, isMainModule, expectActualLinker, skipDceDriven
|
||||
actualMainCallParameters, testPackage, testFunction, needsFullIrRuntime, isMainModule, expectActualLinker, skipDceDriven, splitPerModule
|
||||
)
|
||||
|
||||
when {
|
||||
@@ -395,7 +396,8 @@ abstract class BasicBoxTest(
|
||||
needsFullIrRuntime: Boolean,
|
||||
isMainModule: Boolean,
|
||||
expectActualLinker: Boolean,
|
||||
skipDceDriven: Boolean
|
||||
skipDceDriven: Boolean,
|
||||
splitPerModule: Boolean
|
||||
) {
|
||||
val kotlinFiles = module.files.filter { it.fileName.endsWith(".kt") }
|
||||
val testFiles = kotlinFiles.map { it.fileName }
|
||||
@@ -419,7 +421,7 @@ abstract class BasicBoxTest(
|
||||
val incrementalData = IncrementalData()
|
||||
translateFiles(
|
||||
psiFiles.map(TranslationUnit::SourceFile), outputFile, dceOutputFile, pirOutputFile, config, outputPrefixFile, outputPostfixFile,
|
||||
mainCallParameters, incrementalData, remap, testPackage, testFunction, needsFullIrRuntime, isMainModule, skipDceDriven
|
||||
mainCallParameters, incrementalData, remap, testPackage, testFunction, needsFullIrRuntime, isMainModule, skipDceDriven, splitPerModule
|
||||
)
|
||||
|
||||
if (incrementalCompilationChecksEnabled && module.hasFilesToRecompile) {
|
||||
@@ -471,7 +473,7 @@ abstract class BasicBoxTest(
|
||||
|
||||
translateFiles(
|
||||
translationUnits, recompiledOutputFile, recompiledOutputFile, recompiledOutputFile, recompiledConfig, outputPrefixFile, outputPostfixFile,
|
||||
mainCallParameters, incrementalData, remap, testPackage, testFunction, needsFullIrRuntime, false, true
|
||||
mainCallParameters, incrementalData, remap, testPackage, testFunction, needsFullIrRuntime, false, true, false
|
||||
)
|
||||
|
||||
val originalOutput = FileUtil.loadFile(outputFile)
|
||||
@@ -544,7 +546,8 @@ abstract class BasicBoxTest(
|
||||
testFunction: String,
|
||||
needsFullIrRuntime: Boolean,
|
||||
isMainModule: Boolean,
|
||||
skipDceDriven: Boolean
|
||||
skipDceDriven: Boolean,
|
||||
splitPerModule: Boolean
|
||||
) {
|
||||
val translator = K2JSTranslator(config, false)
|
||||
val translationResult = translator.translateUnits(ExceptionThrowingReporter, units, mainCallParameters)
|
||||
@@ -929,6 +932,7 @@ abstract class BasicBoxTest(
|
||||
private val KJS_WITH_FULL_RUNTIME = Pattern.compile("^// *KJS_WITH_FULL_RUNTIME *\$", Pattern.MULTILINE)
|
||||
private val EXPECT_ACTUAL_LINKER = Pattern.compile("^// EXPECT_ACTUAL_LINKER *$", Pattern.MULTILINE)
|
||||
private val SKIP_DCE_DRIVEN = Pattern.compile("^// *SKIP_DCE_DRIVEN *$", Pattern.MULTILINE)
|
||||
private val SPLIT_PER_MODULE = Pattern.compile("^// *SPLIT_PER_MODULE *$", Pattern.MULTILINE)
|
||||
|
||||
@JvmStatic
|
||||
protected val runTestInNashorn = getBoolean("kotlin.js.useNashorn")
|
||||
|
||||
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.js.facade.MainCallParameters
|
||||
import org.jetbrains.kotlin.js.facade.TranslationUnit
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.parsing.parseBoolean
|
||||
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
import org.jetbrains.kotlin.utils.fileUtils.withReplacedExtensionOrNull
|
||||
import java.io.File
|
||||
@@ -56,6 +57,8 @@ abstract class BasicIrBoxTest(
|
||||
|
||||
val runEs6Mode: Boolean = getBoolean("kotlin.js.ir.es6", false)
|
||||
|
||||
val perModule: Boolean = getBoolean("kotlin.js.ir.perModule")
|
||||
|
||||
private val osName: String = System.getProperty("os.name").toLowerCase()
|
||||
|
||||
// TODO Design incremental compilation for IR and add test support
|
||||
@@ -63,8 +66,11 @@ abstract class BasicIrBoxTest(
|
||||
|
||||
private val compilationCache = mutableMapOf<String, String>()
|
||||
|
||||
private val cachedDependencies = mutableMapOf<String, Collection<String>>()
|
||||
|
||||
override fun doTest(filePath: String, expectedResult: String, mainCallParameters: MainCallParameters, coroutinesPackage: String) {
|
||||
compilationCache.clear()
|
||||
cachedDependencies.clear()
|
||||
super.doTest(filePath, expectedResult, mainCallParameters, coroutinesPackage)
|
||||
}
|
||||
|
||||
@@ -86,7 +92,8 @@ abstract class BasicIrBoxTest(
|
||||
testFunction: String,
|
||||
needsFullIrRuntime: Boolean,
|
||||
isMainModule: Boolean,
|
||||
skipDceDriven: Boolean
|
||||
skipDceDriven: Boolean,
|
||||
splitPerModule: Boolean
|
||||
) {
|
||||
val filesToCompile = units.map { (it as TranslationUnit.SourceFile).file }
|
||||
|
||||
@@ -135,18 +142,13 @@ abstract class BasicIrBoxTest(
|
||||
exportedDeclarations = setOf(FqName.fromSegments(listOfNotNull(testPackage, testFunction))),
|
||||
generateFullJs = true,
|
||||
generateDceJs = runIrDce,
|
||||
es6mode = runEs6Mode
|
||||
es6mode = runEs6Mode,
|
||||
multiModule = splitPerModule || perModule
|
||||
)
|
||||
|
||||
val wrappedCode =
|
||||
wrapWithModuleEmulationMarkers(compiledModule.jsCode!!, moduleId = config.moduleId, moduleKind = config.moduleKind)
|
||||
outputFile.write(wrappedCode)
|
||||
compiledModule.jsCode!!.writeTo(outputFile, config)
|
||||
|
||||
compiledModule.dceJsCode?.let { dceJsCode ->
|
||||
val dceWrappedCode =
|
||||
wrapWithModuleEmulationMarkers(dceJsCode, moduleId = config.moduleId, moduleKind = config.moduleKind)
|
||||
dceOutputFile.write(dceWrappedCode)
|
||||
}
|
||||
compiledModule.dceJsCode?.writeTo(dceOutputFile, config)
|
||||
|
||||
if (generateDts) {
|
||||
val dtsFile = outputFile.withReplacedExtensionOrNull("_v5.js", ".d.ts")
|
||||
@@ -166,11 +168,9 @@ abstract class BasicIrBoxTest(
|
||||
mainArguments = mainCallParameters.run { if (shouldBeGenerated()) arguments() else null },
|
||||
exportedDeclarations = setOf(FqName.fromSegments(listOfNotNull(testPackage, testFunction))),
|
||||
dceDriven = true,
|
||||
es6mode = runEs6Mode
|
||||
).jsCode!!.let { pirCode ->
|
||||
val pirWrappedCode = wrapWithModuleEmulationMarkers(pirCode, moduleId = config.moduleId, moduleKind = config.moduleKind)
|
||||
pirOutputFile.write(pirWrappedCode)
|
||||
}
|
||||
es6mode = runEs6Mode,
|
||||
multiModule = splitPerModule || perModule
|
||||
).jsCode!!.writeTo(pirOutputFile, config)
|
||||
}
|
||||
} else {
|
||||
generateKLib(
|
||||
@@ -188,6 +188,23 @@ abstract class BasicIrBoxTest(
|
||||
}
|
||||
}
|
||||
|
||||
private fun JsCode.writeTo(outputFile: File, config: JsConfig) {
|
||||
val wrappedCode =
|
||||
wrapWithModuleEmulationMarkers(mainModule, moduleId = config.moduleId, moduleKind = config.moduleKind)
|
||||
outputFile.write(wrappedCode)
|
||||
|
||||
val dependencyPaths = mutableListOf<String>()
|
||||
|
||||
dependencies.forEach { (moduleId, code) ->
|
||||
val wrappedCode = wrapWithModuleEmulationMarkers(code, config.moduleKind, moduleId)
|
||||
val dependencyPath = outputFile.absolutePath.replace("_v5.js", "-${moduleId}_v5.js")
|
||||
dependencyPaths += dependencyPath
|
||||
File(dependencyPath).write(wrappedCode)
|
||||
}
|
||||
|
||||
cachedDependencies[outputFile.absolutePath] = dependencyPaths
|
||||
}
|
||||
|
||||
override fun dontRunOnSpecificPlatform(targetBackend: TargetBackend): Boolean {
|
||||
if (targetBackend != TargetBackend.JS_IR_ES6) return false
|
||||
if (!runEs6Mode) return false
|
||||
@@ -210,7 +227,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
|
||||
|
||||
testChecker.check(jsFiles, testModuleName, testPackage, testFunction, expectedResult, withModuleSystem)
|
||||
val allFiles = jsFiles.flatMap { file -> cachedDependencies[file]?.let { deps -> deps + file } ?: listOf(file) }
|
||||
testChecker.check(allFiles, testModuleName, testPackage, testFunction, expectedResult, withModuleSystem)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+98
@@ -797,6 +797,104 @@ public class IrBoxJsES6TestGenerated extends AbstractIrBoxJsES6Test {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("js/js.translator/testData/box/crossModuleRefIR")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class CrossModuleRefIR extends AbstractIrBoxJsES6Test {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInCrossModuleRefIR() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/crossModuleRefIR"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
||||
}
|
||||
|
||||
@TestMetadata("callableObjectRef.kt")
|
||||
public void testCallableObjectRef() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/callableObjectRef.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("constructor.kt")
|
||||
public void testConstructor() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/constructor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("export.kt")
|
||||
public void testExport() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/export.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inheritance.kt")
|
||||
public void testInheritance() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/inheritance.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineJsModule.kt")
|
||||
public void testInlineJsModule() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/inlineJsModule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineJsModuleNonIdentifier.kt")
|
||||
public void testInlineJsModuleNonIdentifier() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/inlineJsModuleNonIdentifier.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineJsModulePackage.kt")
|
||||
public void testInlineJsModulePackage() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/inlineJsModulePackage.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineModule.kt")
|
||||
public void testInlineModule() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/inlineModule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineModuleNonIndentifier.kt")
|
||||
public void testInlineModuleNonIndentifier() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/inlineModuleNonIndentifier.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lambda.kt")
|
||||
public void testLambda() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/lambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("object.kt")
|
||||
public void testObject() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/object.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("objectInInlineClosure.kt")
|
||||
public void testObjectInInlineClosure() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/objectInInlineClosure.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("objectIsObject.kt")
|
||||
public void testObjectIsObject() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/objectIsObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("topLevelExtension.kt")
|
||||
public void testTopLevelExtension() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/topLevelExtension.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("topLevelFunction.kt")
|
||||
public void testTopLevelFunction() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/topLevelFunction.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("topLevelMutableProperty.kt")
|
||||
public void testTopLevelMutableProperty() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/topLevelMutableProperty.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("topLevelProperty.kt")
|
||||
public void testTopLevelProperty() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/topLevelProperty.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("js/js.translator/testData/box/dataClass")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+98
@@ -797,6 +797,104 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("js/js.translator/testData/box/crossModuleRefIR")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class CrossModuleRefIR extends AbstractIrBoxJsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInCrossModuleRefIR() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/crossModuleRefIR"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("callableObjectRef.kt")
|
||||
public void testCallableObjectRef() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/callableObjectRef.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("constructor.kt")
|
||||
public void testConstructor() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/constructor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("export.kt")
|
||||
public void testExport() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/export.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inheritance.kt")
|
||||
public void testInheritance() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/inheritance.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineJsModule.kt")
|
||||
public void testInlineJsModule() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/inlineJsModule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineJsModuleNonIdentifier.kt")
|
||||
public void testInlineJsModuleNonIdentifier() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/inlineJsModuleNonIdentifier.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineJsModulePackage.kt")
|
||||
public void testInlineJsModulePackage() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/inlineJsModulePackage.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineModule.kt")
|
||||
public void testInlineModule() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/inlineModule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineModuleNonIndentifier.kt")
|
||||
public void testInlineModuleNonIndentifier() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/inlineModuleNonIndentifier.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lambda.kt")
|
||||
public void testLambda() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/lambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("object.kt")
|
||||
public void testObject() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/object.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("objectInInlineClosure.kt")
|
||||
public void testObjectInInlineClosure() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/objectInInlineClosure.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("objectIsObject.kt")
|
||||
public void testObjectIsObject() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/objectIsObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("topLevelExtension.kt")
|
||||
public void testTopLevelExtension() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/topLevelExtension.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("topLevelFunction.kt")
|
||||
public void testTopLevelFunction() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/topLevelFunction.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("topLevelMutableProperty.kt")
|
||||
public void testTopLevelMutableProperty() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/topLevelMutableProperty.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("topLevelProperty.kt")
|
||||
public void testTopLevelProperty() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/topLevelProperty.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("js/js.translator/testData/box/dataClass")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+98
@@ -797,6 +797,104 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("js/js.translator/testData/box/crossModuleRefIR")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class CrossModuleRefIR extends AbstractBoxJsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInCrossModuleRefIR() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/crossModuleRefIR"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
||||
}
|
||||
|
||||
@TestMetadata("callableObjectRef.kt")
|
||||
public void testCallableObjectRef() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/callableObjectRef.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("constructor.kt")
|
||||
public void testConstructor() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/constructor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("export.kt")
|
||||
public void testExport() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/export.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inheritance.kt")
|
||||
public void testInheritance() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/inheritance.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineJsModule.kt")
|
||||
public void testInlineJsModule() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/inlineJsModule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineJsModuleNonIdentifier.kt")
|
||||
public void testInlineJsModuleNonIdentifier() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/inlineJsModuleNonIdentifier.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineJsModulePackage.kt")
|
||||
public void testInlineJsModulePackage() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/inlineJsModulePackage.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineModule.kt")
|
||||
public void testInlineModule() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/inlineModule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineModuleNonIndentifier.kt")
|
||||
public void testInlineModuleNonIndentifier() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/inlineModuleNonIndentifier.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lambda.kt")
|
||||
public void testLambda() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/lambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("object.kt")
|
||||
public void testObject() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/object.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("objectInInlineClosure.kt")
|
||||
public void testObjectInInlineClosure() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/objectInInlineClosure.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("objectIsObject.kt")
|
||||
public void testObjectIsObject() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/objectIsObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("topLevelExtension.kt")
|
||||
public void testTopLevelExtension() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/topLevelExtension.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("topLevelFunction.kt")
|
||||
public void testTopLevelFunction() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/topLevelFunction.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("topLevelMutableProperty.kt")
|
||||
public void testTopLevelMutableProperty() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/topLevelMutableProperty.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("topLevelProperty.kt")
|
||||
public void testTopLevelProperty() throws Exception {
|
||||
runTest("js/js.translator/testData/box/crossModuleRefIR/topLevelProperty.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("js/js.translator/testData/box/dataClass")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// SPLIT_PER_MODULE
|
||||
// EXPECTED_REACHABLE_NODES: 1289
|
||||
// MODULE: lib
|
||||
// FILE: lib.kt
|
||||
package lib
|
||||
|
||||
object O {
|
||||
operator fun invoke() = "OK"
|
||||
}
|
||||
|
||||
inline fun callO() = O()
|
||||
|
||||
// MODULE: main(lib)
|
||||
// FILE: main.kt
|
||||
package main
|
||||
|
||||
import lib.*
|
||||
|
||||
fun box(): String {
|
||||
val a = O()
|
||||
if (a != "OK") return "fail: simple: $a"
|
||||
|
||||
val b = callO()
|
||||
if (b != "OK") return "fail: inline: $a"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
// SPLIT_PER_MODULE
|
||||
// EXPECTED_REACHABLE_NODES: 1291
|
||||
// MODULE: lib
|
||||
// FILE: lib.kt
|
||||
package lib
|
||||
|
||||
class A(val x: Int) {
|
||||
constructor(a: Int, b: Int) : this(a + b)
|
||||
}
|
||||
|
||||
external class B(x: Int) {
|
||||
constructor(a: Int, b: Int)
|
||||
|
||||
val x: Int
|
||||
}
|
||||
|
||||
// TODO: may be useful after implementing local classes in inline functions
|
||||
/*
|
||||
inline fun foo(p: Int, q: Int, r: Int): Pair<Int, Int> {
|
||||
class C(val x : Int) {
|
||||
constructor(a: Int, b: Int) : this(a + b)
|
||||
}
|
||||
return Pair(C(p).x, C(q, r).x)
|
||||
}
|
||||
*/
|
||||
|
||||
inline fun callPrimaryConstructor(x: Int) = A(x).x
|
||||
|
||||
inline fun callSecondaryConstructor(x: Int, y: Int) = A(x, y).x
|
||||
|
||||
// FILE: lib.js
|
||||
|
||||
function B(x, y) {
|
||||
this.x = x;
|
||||
if (typeof y !== 'undefined') {
|
||||
this.x += y;
|
||||
}
|
||||
}
|
||||
|
||||
// MODULE: main(lib)
|
||||
// FILE: main.kt
|
||||
package main
|
||||
|
||||
import lib.*
|
||||
|
||||
fun box(): String {
|
||||
val a = A(23).x
|
||||
if (a != 23) return "fail: primary constructor: $a"
|
||||
|
||||
val b = A(40, 2).x
|
||||
if (b != 42) return "fail: secondary constructor: $b"
|
||||
|
||||
val c = B(99).x
|
||||
if (c != 99) return "fail: native primary constructor: $c"
|
||||
|
||||
val d = B(100, 11).x
|
||||
if (d != 111) return "fail: native secondary constructor: $d"
|
||||
|
||||
/*
|
||||
val (e, f) = foo(123, 320, 1)
|
||||
if (e != 123) return "fail: local primary constructor: $e"
|
||||
if (f != 321) return "fail: local secondary constructor: $f"
|
||||
*/
|
||||
|
||||
val g = callPrimaryConstructor(55)
|
||||
if (g != 55) return "fail: primary constructor from inline function: $g"
|
||||
|
||||
val h = callSecondaryConstructor(990, 9)
|
||||
if (h != 999) return "fail: secondary constructor from inline function: $h"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// IGNORE_BACKEND: JS
|
||||
// SPLIT_PER_MODULE
|
||||
// RUN_PLAIN_BOX_FUNCTION
|
||||
// EXPECTED_REACHABLE_NODES: 1316
|
||||
|
||||
// MODULE: lib1
|
||||
// FILE: lib1.kt
|
||||
|
||||
@JsExport
|
||||
fun O(): String = "O"
|
||||
|
||||
// MODULE: lib2(lib1)
|
||||
// FILE: lib2.kt
|
||||
|
||||
@JsExport
|
||||
fun K(): String = "K"
|
||||
|
||||
|
||||
// MODULE: main(lib1, lib2)
|
||||
// FILE: main.kt
|
||||
|
||||
@JsExport
|
||||
fun test() = O() + K()
|
||||
|
||||
// FILE: test.js
|
||||
|
||||
function box() {
|
||||
|
||||
if (main.test() != "OK") return "fail 1";
|
||||
|
||||
return kotlin_lib1.O() + kotlin_lib2.K();
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// SPLIT_PER_MODULE
|
||||
// EXPECTED_REACHABLE_NODES: 1292
|
||||
// MODULE: lib
|
||||
// FILE: lib.kt
|
||||
|
||||
package lib
|
||||
|
||||
open class A {
|
||||
fun foo() = 23
|
||||
}
|
||||
|
||||
// MODULE: main(lib)
|
||||
// FILE: main.kt
|
||||
|
||||
package main
|
||||
|
||||
import lib.A
|
||||
|
||||
class B : A() {
|
||||
fun bar() = foo() + 1
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val result = B().bar()
|
||||
if (result != 24) return "fail: $result"
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// SPLIT_PER_MODULE
|
||||
// EXPECTED_REACHABLE_NODES: 1316
|
||||
// MODULE: lib1
|
||||
// FILE: lib1.js
|
||||
define("lib1", [], function() {
|
||||
return function() {
|
||||
return "OK";
|
||||
}
|
||||
})
|
||||
|
||||
// MODULE: lib2(lib1)
|
||||
// FILE: lib2.kt
|
||||
// MODULE_KIND: AMD
|
||||
@JsModule("lib1")
|
||||
external fun foo(): String
|
||||
|
||||
// MODULE: lib3(lib2)
|
||||
// FILE: lib3.kt
|
||||
// MODULE_KIND: AMD
|
||||
inline fun bar() = foo()
|
||||
|
||||
// MODULE: main(lib3)
|
||||
// FILE: main.kt
|
||||
// MODULE_KIND: AMD
|
||||
|
||||
fun box() = bar()
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// SPLIT_PER_MODULE
|
||||
// EXPECTED_REACHABLE_NODES: 1316
|
||||
// MODULE: lib-1
|
||||
// FILE: lib-1.js
|
||||
define("lib-1", [], function() {
|
||||
return function() {
|
||||
return "OK";
|
||||
}
|
||||
})
|
||||
|
||||
// MODULE: lib2(lib-1)
|
||||
// FILE: lib2.kt
|
||||
// MODULE_KIND: AMD
|
||||
@JsModule("lib-1")
|
||||
external fun foo(): String
|
||||
|
||||
// MODULE: lib3(lib2)
|
||||
// FILE: lib3.kt
|
||||
// MODULE_KIND: AMD
|
||||
inline fun bar() = foo()
|
||||
|
||||
// MODULE: main(lib3)
|
||||
// FILE: main.kt
|
||||
// MODULE_KIND: AMD
|
||||
|
||||
fun box() = bar()
|
||||
@@ -0,0 +1,29 @@
|
||||
// SPLIT_PER_MODULE
|
||||
// EXPECTED_REACHABLE_NODES: 1284
|
||||
// MODULE: lib1
|
||||
// FILE: lib1.js
|
||||
define("lib1", [], function() {
|
||||
return {
|
||||
foo: function() {
|
||||
return "OK";
|
||||
}
|
||||
};
|
||||
})
|
||||
|
||||
// MODULE: lib2(lib1)
|
||||
// FILE: lib2.kt
|
||||
// MODULE_KIND: AMD
|
||||
@file:JsModule("lib1")
|
||||
|
||||
external fun foo(): String
|
||||
|
||||
// MODULE: lib3(lib2)
|
||||
// FILE: lib3.kt
|
||||
// MODULE_KIND: AMD
|
||||
inline fun bar() = foo()
|
||||
|
||||
// MODULE: main(lib3)
|
||||
// FILE: main.kt
|
||||
// MODULE_KIND: AMD
|
||||
|
||||
fun box() = bar()
|
||||
@@ -0,0 +1,16 @@
|
||||
// SPLIT_PER_MODULE
|
||||
// EXPECTED_REACHABLE_NODES: 1283
|
||||
// MODULE: lib1
|
||||
// FILE: lib1.kt
|
||||
|
||||
fun foo() = "OK"
|
||||
|
||||
// MODULE: lib2(lib1)
|
||||
// FILE: lib2.kt
|
||||
|
||||
inline fun bar() = foo()
|
||||
|
||||
// MODULE: main(lib1, lib2)
|
||||
// FILE: main.kt
|
||||
|
||||
fun box() = bar()
|
||||
@@ -0,0 +1,16 @@
|
||||
// SPLIT_PER_MODULE
|
||||
// EXPECTED_REACHABLE_NODES: 1283
|
||||
// MODULE: 1
|
||||
// FILE: lib1.kt
|
||||
|
||||
fun foo() = "OK"
|
||||
|
||||
// MODULE: 2(1)
|
||||
// FILE: lib2.kt
|
||||
|
||||
inline fun bar() = foo()
|
||||
|
||||
// MODULE: main(2)
|
||||
// FILE: main.kt
|
||||
|
||||
fun box() = bar()
|
||||
@@ -0,0 +1,19 @@
|
||||
// SPLIT_PER_MODULE
|
||||
// EXPECTED_REACHABLE_NODES: 1283
|
||||
// MODULE: lib
|
||||
// FILE: lib.kt
|
||||
package lib
|
||||
|
||||
fun bar(f: () -> String) = f()
|
||||
|
||||
inline fun foo(): String {
|
||||
return bar { "OK" }
|
||||
}
|
||||
|
||||
// MODULE: main(lib)
|
||||
// FILE: main.kt
|
||||
package main
|
||||
|
||||
import lib.*
|
||||
|
||||
fun box() = foo()
|
||||
@@ -0,0 +1,37 @@
|
||||
// SPLIT_PER_MODULE
|
||||
// EXPECTED_REACHABLE_NODES: 1289
|
||||
// MODULE: lib
|
||||
// FILE: lib.kt
|
||||
package lib
|
||||
|
||||
var log = ""
|
||||
|
||||
object O {
|
||||
init {
|
||||
log += "O.init;"
|
||||
}
|
||||
|
||||
fun result() = "OK"
|
||||
}
|
||||
|
||||
fun getResult(): String {
|
||||
log += "before;"
|
||||
val result = O.result()
|
||||
log += "after;"
|
||||
return result
|
||||
}
|
||||
|
||||
// MODULE: main(lib)
|
||||
// FILE: main.kt
|
||||
package main
|
||||
|
||||
import lib.*
|
||||
|
||||
fun box(): String {
|
||||
val result = getResult()
|
||||
if (result != "OK") return "fail: unexpected result: $result"
|
||||
|
||||
if (log != "before;O.init;after;") return "fail: wrong evaluation order: $log"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// SPLIT_PER_MODULE
|
||||
// EXPECTED_REACHABLE_NODES: 1382
|
||||
// MODULE: lib
|
||||
// FILE: lib.kt
|
||||
package lib
|
||||
|
||||
object O {
|
||||
val result = "OK"
|
||||
|
||||
inline fun foo(): String {
|
||||
val o = object {
|
||||
fun bar() = O
|
||||
}
|
||||
return fetch(o.bar())
|
||||
}
|
||||
}
|
||||
|
||||
fun fetch(o: O) = o.result
|
||||
|
||||
|
||||
// MODULE: main(lib)
|
||||
// FILE: main.kt
|
||||
package main
|
||||
|
||||
import lib.*
|
||||
|
||||
fun box() = O.foo()
|
||||
@@ -0,0 +1,21 @@
|
||||
// SPLIT_PER_MODULE
|
||||
// EXPECTED_REACHABLE_NODES: 1284
|
||||
// MODULE: lib
|
||||
// FILE: lib.kt
|
||||
package lib
|
||||
|
||||
object O
|
||||
|
||||
// MODULE: main(lib)
|
||||
// FILE: main.kt
|
||||
package main
|
||||
|
||||
import lib.*
|
||||
|
||||
fun box(): String {
|
||||
var o: Any = O
|
||||
if (o !is O) return "fail1"
|
||||
if (!(o is O)) return "fail2"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
// SPLIT_PER_MODULE
|
||||
// EXPECTED_REACHABLE_NODES: 1290
|
||||
// MODULE: lib
|
||||
// FILE: lib.kt
|
||||
|
||||
package lib
|
||||
|
||||
class A(val x: Int)
|
||||
|
||||
fun A.foo() = 23 + x
|
||||
|
||||
inline fun A.baz() = 99 + x
|
||||
|
||||
inline fun A.callFoo() = foo()
|
||||
|
||||
inline fun A.buzz(): Int {
|
||||
val o = object {
|
||||
fun f() = 111 + x
|
||||
}
|
||||
return o.f()
|
||||
}
|
||||
|
||||
// MODULE: main(lib)
|
||||
// FILE: main.kt
|
||||
|
||||
package main
|
||||
|
||||
import lib.*
|
||||
|
||||
fun box(): String {
|
||||
val a = A(1).foo()
|
||||
if (a != 24) return "fail: simple function: $a"
|
||||
|
||||
val c = A(1).baz()
|
||||
if (c != 100) return "fail: inline function: $c"
|
||||
|
||||
val d = A(1).buzz()
|
||||
if (d != 112) return "fail: inline function with object expression: $d"
|
||||
|
||||
val e = A(2).callFoo()
|
||||
if (e != 25) return "fail: inline function calling another function: $e"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
// SPLIT_PER_MODULE
|
||||
// EXPECTED_REACHABLE_NODES: 1287
|
||||
// MODULE: lib
|
||||
// FILE: lib.kt
|
||||
|
||||
package lib
|
||||
|
||||
fun foo() = 23
|
||||
|
||||
external fun bar(): Int = definedExternally
|
||||
|
||||
inline fun baz() = 99
|
||||
|
||||
inline fun callFoo() = foo()
|
||||
|
||||
inline fun buzz(): Int {
|
||||
val o = object {
|
||||
fun f() = 111
|
||||
}
|
||||
return o.f()
|
||||
}
|
||||
|
||||
// FILE: lib.js
|
||||
|
||||
function bar() {
|
||||
return 42;
|
||||
}
|
||||
|
||||
// MODULE: main(lib)
|
||||
// FILE: main.kt
|
||||
|
||||
package main
|
||||
|
||||
fun box(): String {
|
||||
val a = lib.foo()
|
||||
if (a != 23) return "fail: simple function: $a"
|
||||
|
||||
val b = lib.bar()
|
||||
if (b != 42) return "fail: native function: $b"
|
||||
|
||||
val c = lib.baz()
|
||||
if (c != 99) return "fail: inline function: $c"
|
||||
|
||||
val d = lib.buzz()
|
||||
if (d != 111) return "fail: inline function with object expression: $d"
|
||||
|
||||
val e = lib.callFoo()
|
||||
if (e != 23) return "fail: inline function calling another function: $e"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// SPLIT_PER_MODULE
|
||||
// EXPECTED_REACHABLE_NODES: 1286
|
||||
// MODULE: lib
|
||||
// FILE: lib.kt
|
||||
package lib
|
||||
|
||||
var foo = 23
|
||||
|
||||
var bar: Int = 42
|
||||
get() = field
|
||||
set(value) {
|
||||
field = value
|
||||
}
|
||||
|
||||
@JsName("faz") var baz = 99
|
||||
|
||||
// MODULE: main(lib)
|
||||
// FILE: lib.kt
|
||||
package main
|
||||
|
||||
import lib.*
|
||||
|
||||
fun box(): String {
|
||||
if (foo != 23) return "fail: simple property initial value: $foo"
|
||||
foo = 24
|
||||
if (foo != 24) return "fail: simple property new value: $foo"
|
||||
|
||||
if (bar != 42) return "fail: property with accessor initial value: $bar"
|
||||
bar = 43
|
||||
if (bar != 43) return "fail: property with accessor new value: $bar"
|
||||
|
||||
if (baz != 99) return "fail: renamed property initial value: $baz"
|
||||
baz = 100
|
||||
if (baz != 100) return "fail: renamed property new value: $baz"
|
||||
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
// SPLIT_PER_MODULE
|
||||
// EXPECTED_REACHABLE_NODES: 1287
|
||||
// MODULE: lib
|
||||
// FILE: lib.kt
|
||||
package lib
|
||||
|
||||
val foo = 23
|
||||
|
||||
val boo: Int
|
||||
get() = 42
|
||||
|
||||
external val bar: Int = definedExternally
|
||||
|
||||
external val far: Int
|
||||
get() = definedExternally
|
||||
|
||||
// TODO: annotations like this are not serialized properly. Uncomment after KT-14529 gets fixed
|
||||
/*
|
||||
val fuzz: Int
|
||||
@JsName("getBuzz") get() = 55
|
||||
*/
|
||||
|
||||
inline fun fetchFoo() = foo
|
||||
|
||||
@JsName("fee")
|
||||
val tee = 2525
|
||||
|
||||
// FILE: lib.js
|
||||
|
||||
var bar = 99
|
||||
var far = 111
|
||||
|
||||
// MODULE: main(lib)
|
||||
// FILE: lib.kt
|
||||
package main
|
||||
|
||||
import lib.*
|
||||
|
||||
fun box(): String {
|
||||
if (foo != 23) return "fail: simple property: $foo"
|
||||
if (boo != 42) return "fail: property with accessor: $boo"
|
||||
if (bar != 99) return "fail: native property: $bar"
|
||||
if (far != 111) return "fail: native property with accessor: $far"
|
||||
//if (fuzz != 55) return "fail: property with JsName on accessor: $fuzz"
|
||||
if (tee != 2525) return "fail: native property with JsName: $tee"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Reference in New Issue
Block a user