diff --git a/.idea/runConfigurations/Generate_Compiler_Tests.xml b/.idea/runConfigurations/Generate_Compiler_Tests.xml
index 89bc789a6b0..6c72d3e9721 100644
--- a/.idea/runConfigurations/Generate_Compiler_Tests.xml
+++ b/.idea/runConfigurations/Generate_Compiler_Tests.xml
@@ -12,6 +12,7 @@
+
diff --git a/build.gradle.kts b/build.gradle.kts
index a2256426939..a761683d1a7 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -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")
}
diff --git a/compiler/build.gradle.kts b/compiler/build.gradle.kts
index 5359aa8943e..03e0e837691 100644
--- a/compiler/build.gradle.kts
+++ b/compiler/build.gradle.kts
@@ -102,6 +102,7 @@ sourceSets {
projectTest(parallel = true) {
dependsOn(":dist")
+
workingDir = rootDir
systemProperty("kotlin.test.script.classpath", testSourceSet.output.classesDirs.joinToString(File.pathSeparator))
doFirst {
diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt
index 8917c27d985..223edfca474 100644
--- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt
+++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt
@@ -302,6 +302,13 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
)
var emitJvmTypeAnnotations: Boolean by FreezableVar(false)
+ @Argument(
+ value = "-Xklib",
+ valueDescription = "",
+ description = "Paths to cross-platform libraries in .klib format"
+ )
+ val klibLibraries: String? by NullableStringFreezableVar(null)
+
override fun configureAnalysisFlags(collector: MessageCollector): MutableMap, Any> {
val result = super.configureAnalysisFlags(collector)
result[JvmAnalysisFlags.strictMetadataVersionSemantics] = strictMetadataVersionSemantics
diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt
index e6e28fe294a..8df28673458 100644
--- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt
+++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt
@@ -75,6 +75,7 @@ class K2JVMCompiler : CLICompiler() {
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())) {
diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt
index 0fccea89a9a..523f0742c42 100644
--- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt
+++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt
@@ -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) }
+}
\ No newline at end of file
diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java b/compiler/frontend.java/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java
index 593cb7d85f9..8e7a4a6671f 100644
--- a/compiler/frontend.java/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java
+++ b/compiler/frontend.java/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java
@@ -113,4 +113,7 @@ public class JVMConfigurationKeys {
public static final CompilerConfigurationKey EMIT_JVM_TYPE_ANNOTATIONS =
CompilerConfigurationKey.create("Emit JVM type annotations in bytecode");
+
+ public static final CompilerConfigurationKey> KLIB_PATHS =
+ CompilerConfigurationKey.create("Paths to .klib libraries");
}
diff --git a/compiler/testData/codegen/boxKlib/simple.kt b/compiler/testData/codegen/boxKlib/simple.kt
new file mode 100644
index 00000000000..189b568d338
--- /dev/null
+++ b/compiler/testData/codegen/boxKlib/simple.kt
@@ -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()
+}
\ No newline at end of file
diff --git a/compiler/tests-against-klib/build.gradle.kts b/compiler/tests-against-klib/build.gradle.kts
new file mode 100644
index 00000000000..d7c5b15cbd9
--- /dev/null
+++ b/compiler/tests-against-klib/build.gradle.kts
@@ -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")
diff --git a/compiler/tests-against-klib/tests/org/jetbrains/kotlin/codegen/ir/AbstractIrCompileKotlinAgainstKlibTest.kt b/compiler/tests-against-klib/tests/org/jetbrains/kotlin/codegen/ir/AbstractIrCompileKotlinAgainstKlibTest.kt
new file mode 100644
index 00000000000..ff2a5dea9ab
--- /dev/null
+++ b/compiler/tests-against-klib/tests/org/jetbrains/kotlin/codegen/ir/AbstractIrCompileKotlinAgainstKlibTest.kt
@@ -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) {
+ outputDir = javaSourcesOutputDirectory
+ klibName = Paths.get(outputDir.toString(), wholeFile.name.toString().removeSuffix(".kt")).toString()
+
+ val classpath: MutableList = 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): List {
+ 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) {
+ 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
+ }
+}
diff --git a/compiler/tests-against-klib/tests/org/jetbrains/kotlin/codegen/ir/CompileKotlinAgainstKlibTestGenerated.java b/compiler/tests-against-klib/tests/org/jetbrains/kotlin/codegen/ir/CompileKotlinAgainstKlibTestGenerated.java
new file mode 100644
index 00000000000..5b1573a3e95
--- /dev/null
+++ b/compiler/tests-against-klib/tests/org/jetbrains/kotlin/codegen/ir/CompileKotlinAgainstKlibTestGenerated.java
@@ -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");
+ }
+}
diff --git a/compiler/tests-against-klib/tests/org/jetbrains/kotlin/generators/tests/GenerateCompilerTestsAgainstKlib.kt b/compiler/tests-against-klib/tests/org/jetbrains/kotlin/generators/tests/GenerateCompilerTestsAgainstKlib.kt
new file mode 100644
index 00000000000..cd58a264a43
--- /dev/null
+++ b/compiler/tests-against-klib/tests/org/jetbrains/kotlin/generators/tests/GenerateCompilerTestsAgainstKlib.kt
@@ -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) {
+ System.setProperty("java.awt.headless", "true")
+
+ testGroup("compiler/tests-against-klib/tests", "compiler/testData") {
+ testClass {
+ model("codegen/boxKlib", targetBackend = TargetBackend.JVM_IR)
+ }
+ }
+}
diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractBlackBoxCodegenTest.java b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractBlackBoxCodegenTest.java
index edfb6d117f4..d07960878d9 100644
--- a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractBlackBoxCodegenTest.java
+++ b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractBlackBoxCodegenTest.java
@@ -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 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);
+ }
+ }
}
diff --git a/compiler/tests/org/jetbrains/kotlin/generators/tests/GenerateCompilerTests.kt b/compiler/tests/org/jetbrains/kotlin/generators/tests/GenerateCompilerTests.kt
index 167a0c645fb..ed8a9bb04c9 100644
--- a/compiler/tests/org/jetbrains/kotlin/generators/tests/GenerateCompilerTests.kt
+++ b/compiler/tests/org/jetbrains/kotlin/generators/tests/GenerateCompilerTests.kt
@@ -513,7 +513,6 @@ fun main(args: Array) {
}
}
-
testGroup("compiler/fir/psi2fir/tests", "compiler/fir/psi2fir/testData") {
testClass {
model("rawBuilder", testMethod = "doRawFirTest")
diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/compilationContext.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/compilationContext.kt
index 4f4e9c7d914..2ec8f74b79e 100644
--- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/compilationContext.kt
+++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/compilationContext.kt
@@ -181,6 +181,8 @@ private fun CompilerConfiguration.updateWithCompilerOptions(
setupJvmSpecificArguments(compilerArguments)
configureAdvancedJvmOptions(compilerArguments)
+
+ configureKlibPaths(compilerArguments)
}
private fun ScriptCompilationConfiguration.withUpdatesFromCompilerConfiguration(kotlinCompilerConfiguration: CompilerConfiguration) =
diff --git a/settings.gradle b/settings.gradle
index cd355b17b61..fa98f33392a 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -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",