JVM_IR: Add test for compiling against cross-platform Klib
This commit is contained in:
@@ -12,6 +12,7 @@
|
|||||||
<list>
|
<list>
|
||||||
<option value=":compiler:generateTests" />
|
<option value=":compiler:generateTests" />
|
||||||
<option value=":compiler:tests-java8:generateTests" />
|
<option value=":compiler:tests-java8:generateTests" />
|
||||||
|
<option value=":compiler:tests-against-klib:generateTests" />
|
||||||
<option value=":js:js.tests:generateTests" />
|
<option value=":js:js.tests:generateTests" />
|
||||||
<option value=":core:descriptors.runtime:generateTests" />
|
<option value=":core:descriptors.runtime:generateTests" />
|
||||||
</list>
|
</list>
|
||||||
|
|||||||
+2
-1
@@ -513,7 +513,8 @@ tasks {
|
|||||||
":compiler:test",
|
":compiler:test",
|
||||||
":compiler:container:test",
|
":compiler:container:test",
|
||||||
":compiler:tests-java8:test",
|
":compiler:tests-java8:test",
|
||||||
":compiler:tests-spec:remoteRunTests"
|
":compiler:tests-spec:remoteRunTests",
|
||||||
|
":compiler:tests-against-klib:test"
|
||||||
)
|
)
|
||||||
dependsOn(":plugins:jvm-abi-gen:test")
|
dependsOn(":plugins:jvm-abi-gen:test")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ sourceSets {
|
|||||||
|
|
||||||
projectTest(parallel = true) {
|
projectTest(parallel = true) {
|
||||||
dependsOn(":dist")
|
dependsOn(":dist")
|
||||||
|
|
||||||
workingDir = rootDir
|
workingDir = rootDir
|
||||||
systemProperty("kotlin.test.script.classpath", testSourceSet.output.classesDirs.joinToString(File.pathSeparator))
|
systemProperty("kotlin.test.script.classpath", testSourceSet.output.classesDirs.joinToString(File.pathSeparator))
|
||||||
doFirst {
|
doFirst {
|
||||||
|
|||||||
+7
@@ -302,6 +302,13 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
|
|||||||
)
|
)
|
||||||
var emitJvmTypeAnnotations: Boolean by FreezableVar(false)
|
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> {
|
override fun configureAnalysisFlags(collector: MessageCollector): MutableMap<AnalysisFlag<*>, Any> {
|
||||||
val result = super.configureAnalysisFlags(collector)
|
val result = super.configureAnalysisFlags(collector)
|
||||||
result[JvmAnalysisFlags.strictMetadataVersionSemantics] = strictMetadataVersionSemantics
|
result[JvmAnalysisFlags.strictMetadataVersionSemantics] = strictMetadataVersionSemantics
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
|||||||
configuration.configureExplicitContentRoots(arguments)
|
configuration.configureExplicitContentRoots(arguments)
|
||||||
configuration.configureStandardLibs(paths, arguments)
|
configuration.configureStandardLibs(paths, arguments)
|
||||||
configuration.configureAdvancedJvmOptions(arguments)
|
configuration.configureAdvancedJvmOptions(arguments)
|
||||||
|
configuration.configureKlibPaths(arguments)
|
||||||
|
|
||||||
if (arguments.buildFile == null && !arguments.version && !arguments.allowNoSourceFiles &&
|
if (arguments.buildFile == null && !arguments.version && !arguments.allowNoSourceFiles &&
|
||||||
(arguments.script || arguments.expression != null || arguments.freeArgs.isEmpty())) {
|
(arguments.script || arguments.expression != null || arguments.freeArgs.isEmpty())) {
|
||||||
|
|||||||
@@ -138,7 +138,6 @@ fun KotlinCoreEnvironment.registerJavacIfNeeded(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun CompilerConfiguration.configureAdvancedJvmOptions(arguments: K2JVMCompilerArguments) {
|
fun CompilerConfiguration.configureAdvancedJvmOptions(arguments: K2JVMCompilerArguments) {
|
||||||
|
|
||||||
put(JVMConfigurationKeys.PARAMETERS_METADATA, arguments.javaParameters)
|
put(JVMConfigurationKeys.PARAMETERS_METADATA, arguments.javaParameters)
|
||||||
@@ -199,3 +198,11 @@ fun CompilerConfiguration.configureAdvancedJvmOptions(arguments: K2JVMCompilerAr
|
|||||||
|
|
||||||
arguments.declarationsOutputPath?.let { put(JVMConfigurationKeys.DECLARATIONS_JSON_PATH, it) }
|
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 =
|
public static final CompilerConfigurationKey<Boolean> EMIT_JVM_TYPE_ANNOTATIONS =
|
||||||
CompilerConfigurationKey.create("Emit JVM type annotations in bytecode");
|
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.fileClasses.JvmFileClassUtil;
|
||||||
import org.jetbrains.kotlin.psi.KtFile;
|
import org.jetbrains.kotlin.psi.KtFile;
|
||||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils;
|
import org.jetbrains.kotlin.test.InTextDirectivesUtils;
|
||||||
import org.jetbrains.kotlin.test.TargetBackend;
|
|
||||||
import org.jetbrains.kotlin.utils.ExceptionUtilsKt;
|
import org.jetbrains.kotlin.utils.ExceptionUtilsKt;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -33,9 +32,7 @@ public abstract class AbstractBlackBoxCodegenTest extends CodegenTestCase {
|
|||||||
@NotNull List<TestFile> files,
|
@NotNull List<TestFile> files,
|
||||||
boolean unexpectedBehaviour
|
boolean unexpectedBehaviour
|
||||||
) throws Exception {
|
) throws Exception {
|
||||||
boolean isIgnored = InTextDirectivesUtils.isIgnoredTarget(getBackend(), wholeFile) ||
|
boolean isIgnored = isIgnoredTarget(wholeFile);
|
||||||
(this instanceof AbstractFirBlackBoxCodegenTest &&
|
|
||||||
InTextDirectivesUtils.isDirectiveDefined(FileUtil.loadFile(wholeFile), "IGNORE_BACKEND_FIR: JVM_IR"));
|
|
||||||
|
|
||||||
compile(files, !isIgnored, false);
|
compile(files, !isIgnored, false);
|
||||||
|
|
||||||
@@ -142,4 +139,15 @@ public abstract class AbstractBlackBoxCodegenTest extends CodegenTestCase {
|
|||||||
? null
|
? null
|
||||||
: JvmFileClassUtil.getFileClassInfoNoResolve(file).getFacadeClassFqName().asString();
|
: 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") {
|
testGroup("compiler/fir/psi2fir/tests", "compiler/fir/psi2fir/testData") {
|
||||||
testClass<AbstractRawFirBuilderTestCase> {
|
testClass<AbstractRawFirBuilderTestCase> {
|
||||||
model("rawBuilder", testMethod = "doRawFirTest")
|
model("rawBuilder", testMethod = "doRawFirTest")
|
||||||
|
|||||||
+2
@@ -181,6 +181,8 @@ private fun CompilerConfiguration.updateWithCompilerOptions(
|
|||||||
setupJvmSpecificArguments(compilerArguments)
|
setupJvmSpecificArguments(compilerArguments)
|
||||||
|
|
||||||
configureAdvancedJvmOptions(compilerArguments)
|
configureAdvancedJvmOptions(compilerArguments)
|
||||||
|
|
||||||
|
configureKlibPaths(compilerArguments)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ScriptCompilationConfiguration.withUpdatesFromCompilerConfiguration(kotlinCompilerConfiguration: CompilerConfiguration) =
|
private fun ScriptCompilationConfiguration.withUpdatesFromCompilerConfiguration(kotlinCompilerConfiguration: CompilerConfiguration) =
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ include ":kotlin-build-common",
|
|||||||
":compiler:android-tests",
|
":compiler:android-tests",
|
||||||
":compiler:tests-common",
|
":compiler:tests-common",
|
||||||
":compiler:tests-common-jvm6",
|
":compiler:tests-common-jvm6",
|
||||||
|
":compiler:tests-against-klib",
|
||||||
":dukat",
|
":dukat",
|
||||||
":js:js.ast",
|
":js:js.ast",
|
||||||
":js:js.serializer",
|
":js:js.serializer",
|
||||||
|
|||||||
Reference in New Issue
Block a user