diff --git a/compiler/testData/codegen/bytecodeListing/main/suspendMain_before.kt b/compiler/testData/codegen/bytecodeListing/main/suspendMain_before.kt index d1ea8d0fe44..bb783cce828 100644 --- a/compiler/testData/codegen/bytecodeListing/main/suspendMain_before.kt +++ b/compiler/testData/codegen/bytecodeListing/main/suspendMain_before.kt @@ -1,4 +1,6 @@ // !LANGUAGE: -ExtendedMainConvention -ReleaseCoroutines // WITH_RUNTIME +// uses kotlin.coroutines.experimental classes under the hood + suspend fun main(args: Array) {} diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTest.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTest.kt index dcf01861180..7b5968fd050 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTest.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTest.kt @@ -109,13 +109,14 @@ abstract class AbstractDiagnosticsTest : BaseDiagnosticsTest() { val oldModule = modules[testModule]!! val languageVersionSettings = - if (coroutinesPackage.isNotEmpty()) + if (coroutinesPackage.isNotEmpty()) { + val isExperimental = coroutinesPackage == DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME_EXPERIMENTAL.asString() CompilerTestLanguageVersionSettings( DEFAULT_DIAGNOSTIC_TESTS_FEATURES, - if (coroutinesPackage.contains("experimental")) ApiVersion.KOTLIN_1_2 else ApiVersion.KOTLIN_1_3, - if (coroutinesPackage.contains("experimental")) LanguageVersion.KOTLIN_1_2 else LanguageVersion.KOTLIN_1_3 + if (isExperimental) ApiVersion.KOTLIN_1_2 else ApiVersion.KOTLIN_1_3, + if (isExperimental) LanguageVersion.KOTLIN_1_2 else LanguageVersion.KOTLIN_1_3 ) - else loadLanguageVersionSettings(testFilesInModule) + } else loadLanguageVersionSettings(testFilesInModule) languageVersionSettingsByModule[testModule] = languageVersionSettings diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/KotlinMultiFileTestWithJava.java b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/KotlinMultiFileTestWithJava.java index 1e42e3a1a7a..e826babe227 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/KotlinMultiFileTestWithJava.java +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/KotlinMultiFileTestWithJava.java @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime; import org.jetbrains.kotlin.config.CompilerConfiguration; import org.jetbrains.kotlin.config.JVMConfigurationKeys; import org.jetbrains.kotlin.parsing.KotlinParserDefinition; +import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.test.*; import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase; @@ -114,6 +115,11 @@ public abstract class KotlinMultiFileTestWithJava extends KtUsefulTestCase result.add(ForTestCompileRuntime.runtimeJarForTestsWithJdk8()); } + if (DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME_EXPERIMENTAL.asString().equals(coroutinesPackage) || + fileText.contains(DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME_EXPERIMENTAL.asString())) { + result.add(ForTestCompileRuntime.coroutinesCompatForTests()); + } + return result; } 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 d07960878d9..8cfcd2424e6 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractBlackBoxCodegenTest.java +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractBlackBoxCodegenTest.java @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.backend.common.CodegenUtil; import org.jetbrains.kotlin.codegen.ir.AbstractFirBlackBoxCodegenTest; import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil; import org.jetbrains.kotlin.psi.KtFile; +import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.test.InTextDirectivesUtils; import org.jetbrains.kotlin.utils.ExceptionUtilsKt; @@ -67,7 +68,7 @@ public abstract class AbstractBlackBoxCodegenTest extends CodegenTestCase { if (!InTextDirectivesUtils.isDirectiveDefined(FileUtil.loadFile(wholeFile), "CHECK_BYTECODE_LISTING")) return; String suffix = - (coroutinesPackage.contains("experimental") || coroutinesPackage.isEmpty()) + (coroutinesPackage.equals(DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME_EXPERIMENTAL.asString()) || coroutinesPackage.isEmpty()) && InTextDirectivesUtils.isDirectiveDefined(FileUtil.loadFile(wholeFile), "COMMON_COROUTINES_TEST") ? "_1_2" : getBackend().isIR() ? "_ir" : ""; diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractCompileKotlinAgainstKotlinTest.java b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractCompileKotlinAgainstKotlinTest.java index 4911c323b16..67de66e4253 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractCompileKotlinAgainstKotlinTest.java +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractCompileKotlinAgainstKotlinTest.java @@ -86,7 +86,10 @@ public abstract class AbstractCompileKotlinAgainstKotlinTest extends CodegenTest @NotNull private URLClassLoader createGeneratedClassLoader() throws Exception { return new URLClassLoader( - new URL[]{ bDir.toURI().toURL(), aDir.toURI().toURL() }, + new URL[]{ + bDir.toURI().toURL(), aDir.toURI().toURL(), + ForTestCompileRuntime.coroutinesCompatForTests().toURI().toURL() + }, ForTestCompileRuntime.runtimeAndReflectJarClassLoader() ); } diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/CodegenTestCase.java b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/CodegenTestCase.java index e097ce92bd4..0d3aa614f12 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/CodegenTestCase.java +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/CodegenTestCase.java @@ -28,12 +28,15 @@ import org.jetbrains.kotlin.cli.common.output.OutputUtilsKt; import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles; import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment; import org.jetbrains.kotlin.cli.jvm.compiler.NoScopeRecordCliBindingTrace; +import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot; +import org.jetbrains.kotlin.cli.jvm.config.JvmContentRootsKt; import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime; import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.config.*; import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.psi.KtFile; +import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.scripting.definitions.ScriptDependenciesProvider; import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationWrapper; import org.jetbrains.kotlin.test.*; @@ -59,10 +62,7 @@ import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -166,6 +166,7 @@ public abstract class CodegenTestCase extends KtUsefulTestCase { ) { LanguageVersionSettings explicitLanguageVersionSettings = null; boolean disableReleaseCoroutines = false; + boolean includeCompatExperimentalCoroutines = false; List kotlinConfigurationFlags = new ArrayList<>(0); for (TestFile testFile : testFilesWithConfigurationDirectives) { @@ -191,11 +192,16 @@ public abstract class CodegenTestCase extends KtUsefulTestCase { if (!InTextDirectivesUtils.findLinesWithPrefixesRemoved(testFile.content, "// COMMON_COROUTINES_TEST").isEmpty()) { assert !testFile.content.contains("COROUTINES_PACKAGE") : "Must replace COROUTINES_PACKAGE prior to tests compilation"; - if (coroutinesPackage.equals("kotlin.coroutines.experimental")) { + if (DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME_EXPERIMENTAL.asString().equals(coroutinesPackage)) { disableReleaseCoroutines = true; + includeCompatExperimentalCoroutines = true; } } + if (testFile.content.contains(DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME_EXPERIMENTAL.asString())) { + includeCompatExperimentalCoroutines = true; + } + Map directives = KotlinTestUtils.parseDirectives(testFile.content); LanguageVersionSettings fileLanguageVersionSettings = parseLanguageVersionSettings(directives); @@ -213,6 +219,9 @@ public abstract class CodegenTestCase extends KtUsefulTestCase { Collections.emptyMap() ); } + if (includeCompatExperimentalCoroutines) { + JvmContentRootsKt.addJvmClasspathRoot(configuration, ForTestCompileRuntime.coroutinesCompatForTests()); + } if (explicitLanguageVersionSettings != null) { CommonConfigurationKeysKt.setLanguageVersionSettings(configuration, explicitLanguageVersionSettings); @@ -425,6 +434,7 @@ public abstract class CodegenTestCase extends KtUsefulTestCase { if (additionalDependencies != null) { files.addAll(additionalDependencies); } + files.addAll(getExtraDependenciesFromKotlinCompileClasspath()); ScriptDependenciesProvider externalImportsProvider = ScriptDependenciesProvider.Companion.getInstance(myEnvironment.getProject()); @@ -451,6 +461,20 @@ public abstract class CodegenTestCase extends KtUsefulTestCase { } } + private Set getExtraDependenciesFromKotlinCompileClasspath() { + List includeFromCompileClasspath = CollectionsKt.listOf( + ForTestCompileRuntime.coroutinesCompatForTests() + ); + List compileClasspath = + CollectionsKt.map( + CollectionsKt.filterIsInstance( + myEnvironment.getConfiguration().get(CLIConfigurationKeys.CONTENT_ROOTS), + JvmClasspathRoot.class), + JvmClasspathRoot::getFile); + return CollectionsKt.intersect(compileClasspath, includeFromCompileClasspath); + } + + @NotNull protected String generateToText() { return generateToText(null); @@ -699,6 +723,7 @@ public abstract class CodegenTestCase extends KtUsefulTestCase { if (loadAndroidAnnotations) { javaClasspath.add(ForTestCompileRuntime.androidAnnotationsForTests().getPath()); } + javaClasspath.addAll(CollectionsKt.map(getExtraDependenciesFromKotlinCompileClasspath(), File::getPath)); javaClassesOutputDirectory = getJavaClassesOutputDirectory(); compileJava(findJavaSourcesInDirectory(javaSourceDir), javaClasspath, javacOptions, javaClassesOutputDirectory); diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/forTestCompile/ForTestCompileRuntime.java b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/forTestCompile/ForTestCompileRuntime.java index 13d69085b66..9aacf91e1b5 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/forTestCompile/ForTestCompileRuntime.java +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/forTestCompile/ForTestCompileRuntime.java @@ -100,6 +100,11 @@ public class ForTestCompileRuntime { return assertExists(new File("dist/kotlinc/lib/kotlin-annotations-android.jar")); } + @NotNull + public static File coroutinesCompatForTests() { + return assertExists(new File("dist/kotlinc/lib/kotlin-coroutines-experimental-compat.jar")); + } + @NotNull private static File assertExists(@NotNull File file) { if (!file.exists()) { diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/jvm/compiler/AbstractKotlinCompilerIntegrationTest.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/jvm/compiler/AbstractKotlinCompilerIntegrationTest.kt index c858fb3f24a..5109120ace8 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/jvm/compiler/AbstractKotlinCompilerIntegrationTest.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/jvm/compiler/AbstractKotlinCompilerIntegrationTest.kt @@ -59,7 +59,7 @@ abstract class AbstractKotlinCompilerIntegrationTest : TestCaseWithTmpdir() { }, checkKotlinOutput: (String) -> Unit = { actual -> assertEquals(normalizeOutput("" to ExitCode.OK), actual) }, manifest: Manifest? = null, - vararg extraClassPath: File + extraClassPath: List = emptyList() ): File { val sourceDir = File(testDataDirectory, libraryName) val javaFiles = FileUtil.findFilesByMask(JAVA_FILES, sourceDir) @@ -70,7 +70,7 @@ abstract class AbstractKotlinCompilerIntegrationTest : TestCaseWithTmpdir() { val outputDir = if (isJar) File(tmpdir, "output-$libraryName") else destination if (kotlinFiles.isNotEmpty()) { - val output = compileKotlin(libraryName, outputDir, extraClassPath.toList(), K2JVMCompiler(), additionalOptions, expectedFileName = null) + val output = compileKotlin(libraryName, outputDir, extraClassPath, K2JVMCompiler(), additionalOptions, expectedFileName = null) checkKotlinOutput(normalizeOutput(output)) } diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt index 537e9c6bdc3..5afffb0414a 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt @@ -438,7 +438,7 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration fun testReplaceAnnotationClassWithInterface() { val library1 = compileLibrary("library-1") - val usage = compileLibrary("usage", extraClassPath = *arrayOf(library1)) + val usage = compileLibrary("usage", extraClassPath = listOf(library1)) val library2 = compileLibrary("library-2") doTestWithTxt(usage, library2) } @@ -507,7 +507,7 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration val version = intArrayOf(1, 0, 1) // legacy coroutines metadata val options = listOf("-language-version", "1.2", "-Xcoroutines=enable") val library = transformJar( - compileLibrary("library", additionalOptions = options), + compileLibrary("library", additionalOptions = options, extraClassPath = listOf(ForTestCompileRuntime.coroutinesCompatForTests())), { _, bytes -> val (resultBytes, removedCounter) = stripSuspensionMarksToImitateLegacyCompiler( WrongBytecodeVersionTest.transformMetadataInClassFile(bytes) { name, _ -> @@ -518,11 +518,11 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration resultBytes }) compileKotlin( - "source.kt", tmpdir, listOf(library), K2JVMCompiler(), + "source.kt", tmpdir, listOf(library, ForTestCompileRuntime.coroutinesCompatForTests()), K2JVMCompiler(), additionalOptions = options ) val classLoader = URLClassLoader( - arrayOf(library.toURI().toURL(), tmpdir.toURI().toURL()), + arrayOf(library.toURI().toURL(), tmpdir.toURI().toURL(), ForTestCompileRuntime.coroutinesCompatForTests().toURI().toURL()), ForTestCompileRuntime.runtimeJarClassLoader() ) @Suppress("UNCHECKED_CAST") @@ -576,12 +576,13 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration val library = compileLibrary( "library", additionalOptions = listOf("-language-version", "1.2"), - checkKotlinOutput = {} + checkKotlinOutput = {}, + extraClassPath = listOf(ForTestCompileRuntime.coroutinesCompatForTests()) ) compileKotlin( "release.kt", tmpdir, - listOf(library), + listOf(library, ForTestCompileRuntime.coroutinesCompatForTests()), additionalOptions = listOf("-language-version", "1.3", "-api-version", "1.3") ) }