JVM_IR: Add test for compiling against cross-platform Klib
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
<list>
|
||||
<option value=":compiler:generateTests" />
|
||||
<option value=":compiler:tests-java8:generateTests" />
|
||||
<option value=":compiler:tests-against-klib:generateTests" />
|
||||
<option value=":js:js.tests:generateTests" />
|
||||
<option value=":core:descriptors.runtime:generateTests" />
|
||||
</list>
|
||||
|
||||
+2
-1
@@ -513,7 +513,8 @@ tasks {
|
||||
":compiler:test",
|
||||
":compiler:container:test",
|
||||
":compiler:tests-java8:test",
|
||||
":compiler:tests-spec:remoteRunTests"
|
||||
":compiler:tests-spec:remoteRunTests",
|
||||
":compiler:tests-against-klib:test"
|
||||
)
|
||||
dependsOn(":plugins:jvm-abi-gen:test")
|
||||
}
|
||||
|
||||
@@ -102,6 +102,7 @@ sourceSets {
|
||||
|
||||
projectTest(parallel = true) {
|
||||
dependsOn(":dist")
|
||||
|
||||
workingDir = rootDir
|
||||
systemProperty("kotlin.test.script.classpath", testSourceSet.output.classesDirs.joinToString(File.pathSeparator))
|
||||
doFirst {
|
||||
|
||||
+7
@@ -302,6 +302,13 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
|
||||
)
|
||||
var emitJvmTypeAnnotations: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(
|
||||
value = "-Xklib",
|
||||
valueDescription = "<path>",
|
||||
description = "Paths to cross-platform libraries in .klib format"
|
||||
)
|
||||
val klibLibraries: String? by NullableStringFreezableVar(null)
|
||||
|
||||
override fun configureAnalysisFlags(collector: MessageCollector): MutableMap<AnalysisFlag<*>, Any> {
|
||||
val result = super.configureAnalysisFlags(collector)
|
||||
result[JvmAnalysisFlags.strictMetadataVersionSemantics] = strictMetadataVersionSemantics
|
||||
|
||||
@@ -75,6 +75,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
configuration.configureExplicitContentRoots(arguments)
|
||||
configuration.configureStandardLibs(paths, arguments)
|
||||
configuration.configureAdvancedJvmOptions(arguments)
|
||||
configuration.configureKlibPaths(arguments)
|
||||
|
||||
if (arguments.buildFile == null && !arguments.version && !arguments.allowNoSourceFiles &&
|
||||
(arguments.script || arguments.expression != null || arguments.freeArgs.isEmpty())) {
|
||||
|
||||
@@ -138,7 +138,6 @@ fun KotlinCoreEnvironment.registerJavacIfNeeded(
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
fun CompilerConfiguration.configureAdvancedJvmOptions(arguments: K2JVMCompilerArguments) {
|
||||
|
||||
put(JVMConfigurationKeys.PARAMETERS_METADATA, arguments.javaParameters)
|
||||
@@ -199,3 +198,11 @@ fun CompilerConfiguration.configureAdvancedJvmOptions(arguments: K2JVMCompilerAr
|
||||
|
||||
arguments.declarationsOutputPath?.let { put(JVMConfigurationKeys.DECLARATIONS_JSON_PATH, it) }
|
||||
}
|
||||
|
||||
fun CompilerConfiguration.configureKlibPaths(arguments: K2JVMCompilerArguments) {
|
||||
assert(arguments.useIR || arguments.klibLibraries == null) { "Klib libraries can only be used with IR backend" }
|
||||
arguments.klibLibraries?.split(File.pathSeparator.toRegex())
|
||||
?.toTypedArray()
|
||||
?.filterNot { it.isEmpty() }
|
||||
?.let { put(JVMConfigurationKeys.KLIB_PATHS, it) }
|
||||
}
|
||||
@@ -113,4 +113,7 @@ public class JVMConfigurationKeys {
|
||||
|
||||
public static final CompilerConfigurationKey<Boolean> EMIT_JVM_TYPE_ANNOTATIONS =
|
||||
CompilerConfigurationKey.create("Emit JVM type annotations in bytecode");
|
||||
|
||||
public static final CompilerConfigurationKey<List<String>> KLIB_PATHS =
|
||||
CompilerConfigurationKey.create("Paths to .klib libraries");
|
||||
}
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// FILE: klib.kt
|
||||
package fromKlib
|
||||
|
||||
class C {
|
||||
val x = "OK"
|
||||
}
|
||||
fun foo(): String {
|
||||
return C().x
|
||||
}
|
||||
|
||||
// FILE: test.kt
|
||||
import fromKlib.foo
|
||||
|
||||
fun box(): String {
|
||||
return foo()
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCompile
|
||||
import java.io.File
|
||||
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
id("jps-compatible")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile(kotlinStdlib())
|
||||
testCompile(projectTests(":compiler:visualizer"))
|
||||
testCompile(projectTests(":generators:test-generator"))
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
"main" { }
|
||||
"test" { projectDefault() }
|
||||
}
|
||||
|
||||
testsJar {}
|
||||
|
||||
projectTest(parallel = true) {
|
||||
dependsOn(":dist")
|
||||
dependsOn(":kotlin-stdlib-js-ir:generateFullRuntimeKLib")
|
||||
|
||||
workingDir = rootDir
|
||||
systemProperty("kotlin.test.script.classpath", testSourceSet.output.classesDirs.joinToString(File.pathSeparator))
|
||||
}
|
||||
|
||||
val generateTests by generator("org.jetbrains.kotlin.generators.tests.GenerateCompilerTestsAgainstKlibKt")
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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.codegen.ir
|
||||
|
||||
import org.jetbrains.kotlin.cli.AbstractCliTest
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||
import org.jetbrains.kotlin.cli.js.K2JSCompiler
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment.Companion.createForTests
|
||||
import org.jetbrains.kotlin.codegen.AbstractBlackBoxCodegenTest
|
||||
import org.jetbrains.kotlin.codegen.CodegenTestCase
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
import org.jetbrains.kotlin.utils.rethrow
|
||||
import java.io.File
|
||||
import java.nio.file.Paths
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
abstract class AbstractCompileKotlinAgainstKlibTest : AbstractBlackBoxCodegenTest() {
|
||||
lateinit var klibName: String
|
||||
lateinit var outputDir: File
|
||||
|
||||
override fun getBackend() = TargetBackend.JVM_IR
|
||||
|
||||
override fun doMultiFileTest(wholeFile: File, files: List<TestFile>) {
|
||||
outputDir = javaSourcesOutputDirectory
|
||||
klibName = Paths.get(outputDir.toString(), wholeFile.name.toString().removeSuffix(".kt")).toString()
|
||||
|
||||
val classpath: MutableList<File> = ArrayList()
|
||||
classpath.add(KotlinTestUtils.getAnnotationsJar())
|
||||
val configuration = createConfiguration(
|
||||
configurationKind, CodegenTestCase.getJdkKind(files),
|
||||
classpath,
|
||||
listOf(outputDir),
|
||||
files
|
||||
)
|
||||
myEnvironment = createForTests(
|
||||
testRootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES
|
||||
)
|
||||
setupEnvironment(myEnvironment)
|
||||
|
||||
|
||||
// All files but last are Klib's sources.
|
||||
try {
|
||||
compileToKlib(files.dropLast(1))
|
||||
} catch (t: Throwable) {
|
||||
if (!isIgnoredTarget(wholeFile)) {
|
||||
throw t
|
||||
}
|
||||
}
|
||||
super.doMultiFileTest(wholeFile, listOf(files.last()))
|
||||
}
|
||||
|
||||
override fun updateConfiguration(configuration: CompilerConfiguration) {
|
||||
configuration.put(JVMConfigurationKeys.KLIB_PATHS, listOf(klibName + ".klib"))
|
||||
}
|
||||
|
||||
// We need real (as opposed to virtual) files in order to produce a Klib.
|
||||
private fun loadMultiFilesReal(files: List<TestFile>): List<String> {
|
||||
val dir = outputDir
|
||||
return files.map { testFile ->
|
||||
assert(testFile.name.endsWith(".kt"))
|
||||
val ktFile = File(Paths.get(dir.toString(), testFile.name).toString())
|
||||
ktFile.writeText(testFile.content)
|
||||
ktFile.toString()
|
||||
}
|
||||
}
|
||||
|
||||
// For now, while there is no common backend, we generate Klib using
|
||||
// the JS_IR compiler.
|
||||
private fun compileToKlib(files: List<TestFile>) {
|
||||
val sourceFiles = loadMultiFilesReal(files)
|
||||
val (output, exitCode) = AbstractCliTest.executeCompilerGrabOutput(
|
||||
K2JSCompiler(),
|
||||
listOf(
|
||||
"-output", klibName,
|
||||
"-Xir-produce-klib-file",
|
||||
"-libraries", "libraries/stdlib/js-ir/build/fullRuntime/klib/"
|
||||
) + sourceFiles
|
||||
)
|
||||
if (exitCode != ExitCode.OK) {
|
||||
throw Exception(output)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TIMEOUT_SECONDS = 10L
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.codegen.ir;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.TargetBackend;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("compiler/testData/codegen/boxKlib")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class CompileKotlinAgainstKlibTestGenerated extends AbstractCompileKotlinAgainstKlibTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInBoxKlib() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxKlib"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxKlib/simple.kt");
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.generators.tests
|
||||
|
||||
import org.jetbrains.kotlin.codegen.ir.*
|
||||
import org.jetbrains.kotlin.generators.tests.generator.testGroup
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
System.setProperty("java.awt.headless", "true")
|
||||
|
||||
testGroup("compiler/tests-against-klib/tests", "compiler/testData") {
|
||||
testClass<AbstractCompileKotlinAgainstKlibTest> {
|
||||
model("codegen/boxKlib", targetBackend = TargetBackend.JVM_IR)
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
-4
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.codegen.ir.AbstractFirBlackBoxCodegenTest;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil;
|
||||
import org.jetbrains.kotlin.psi.KtFile;
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils;
|
||||
import org.jetbrains.kotlin.test.TargetBackend;
|
||||
import org.jetbrains.kotlin.utils.ExceptionUtilsKt;
|
||||
|
||||
import java.io.File;
|
||||
@@ -33,9 +32,7 @@ public abstract class AbstractBlackBoxCodegenTest extends CodegenTestCase {
|
||||
@NotNull List<TestFile> files,
|
||||
boolean unexpectedBehaviour
|
||||
) throws Exception {
|
||||
boolean isIgnored = InTextDirectivesUtils.isIgnoredTarget(getBackend(), wholeFile) ||
|
||||
(this instanceof AbstractFirBlackBoxCodegenTest &&
|
||||
InTextDirectivesUtils.isDirectiveDefined(FileUtil.loadFile(wholeFile), "IGNORE_BACKEND_FIR: JVM_IR"));
|
||||
boolean isIgnored = isIgnoredTarget(wholeFile);
|
||||
|
||||
compile(files, !isIgnored, false);
|
||||
|
||||
@@ -142,4 +139,15 @@ public abstract class AbstractBlackBoxCodegenTest extends CodegenTestCase {
|
||||
? null
|
||||
: JvmFileClassUtil.getFileClassInfoNoResolve(file).getFacadeClassFqName().asString();
|
||||
}
|
||||
|
||||
protected boolean isIgnoredTarget(@NotNull File wholeFile) {
|
||||
try {
|
||||
return InTextDirectivesUtils.isIgnoredTarget(getBackend(), wholeFile) ||
|
||||
(this instanceof AbstractFirBlackBoxCodegenTest &&
|
||||
InTextDirectivesUtils.isDirectiveDefined(FileUtil.loadFile(wholeFile), "IGNORE_BACKEND_FIR: JVM_IR"));
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw ExceptionUtilsKt.rethrow(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -513,7 +513,6 @@ fun main(args: Array<String>) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
testGroup("compiler/fir/psi2fir/tests", "compiler/fir/psi2fir/testData") {
|
||||
testClass<AbstractRawFirBuilderTestCase> {
|
||||
model("rawBuilder", testMethod = "doRawFirTest")
|
||||
|
||||
+2
@@ -181,6 +181,8 @@ private fun CompilerConfiguration.updateWithCompilerOptions(
|
||||
setupJvmSpecificArguments(compilerArguments)
|
||||
|
||||
configureAdvancedJvmOptions(compilerArguments)
|
||||
|
||||
configureKlibPaths(compilerArguments)
|
||||
}
|
||||
|
||||
private fun ScriptCompilationConfiguration.withUpdatesFromCompilerConfiguration(kotlinCompilerConfiguration: CompilerConfiguration) =
|
||||
|
||||
@@ -114,6 +114,7 @@ include ":kotlin-build-common",
|
||||
":compiler:android-tests",
|
||||
":compiler:tests-common",
|
||||
":compiler:tests-common-jvm6",
|
||||
":compiler:tests-against-klib",
|
||||
":dukat",
|
||||
":js:js.ast",
|
||||
":js:js.serializer",
|
||||
|
||||
Reference in New Issue
Block a user