Tests: add CompileKotlinAgainstCustomBinariesTest for K2

This is needed because after changing default language version to 2.0,
we still need to test many scenarios from this test in K1.

Move K1-specific tests to OldCompileKotlinAgainstCustomBinariesTest, and
K2-specific tests to FirCompileKotlinAgainstCustomBinariesTest.

Mute failing K2 tests via `muteForK2`. It will throw exception if the
muted test will suddenly start passing.
This commit is contained in:
Alexander Udalov
2023-08-01 18:25:23 +02:00
committed by Space Team
parent 21c7325dbe
commit 54c7466074
26 changed files with 271 additions and 117 deletions
@@ -0,0 +1,8 @@
error: pre-release classes were found in dependencies. Remove them from the classpath, recompile with a release compiler or use '-Xskip-prerelease-check' to suppress errors
compiler/testData/compileKotlinAgainstCustomBinaries/againstFirWithUnstableAbi/source.kt:4:5: error: class 'lib.AKt' is compiled by a pre-release version of Kotlin and cannot be loaded by this version of the compiler
get { Box("OK").value }
^
compiler/testData/compileKotlinAgainstCustomBinaries/againstFirWithUnstableAbi/source.kt:4:11: error: class 'lib.Box' is compiled by a pre-release version of Kotlin and cannot be loaded by this version of the compiler
get { Box("OK").value }
^
COMPILATION_ERROR
@@ -0,0 +1,10 @@
compiler/testData/compileKotlinAgainstCustomBinaries/anonymousObjectTypeMetadata/anonymousObjectTypeMetadata.kt:11:10: error: cannot access 'val o3: Any': it is private in file
val e1 = o3
^
compiler/testData/compileKotlinAgainstCustomBinaries/anonymousObjectTypeMetadata/anonymousObjectTypeMetadata.kt:12:12: error: cannot access 'val o7: Any': it is private in 'lib/W'
val e2 = w.o7
^
compiler/testData/compileKotlinAgainstCustomBinaries/anonymousObjectTypeMetadata/anonymousObjectTypeMetadata.kt:13:12: error: cannot access 'val o10: Any': it is private in 'lib/O'
val e3 = O.o10
^
COMPILATION_ERROR
@@ -0,0 +1,10 @@
compiler/testData/compileKotlinAgainstCustomBinaries/anonymousObjectTypeMetadataKlib/anonymousObjectTypeMetadata.kt:11:10: error: cannot access 'val o3: Any': it is private in file
val e1 = o3
^
compiler/testData/compileKotlinAgainstCustomBinaries/anonymousObjectTypeMetadataKlib/anonymousObjectTypeMetadata.kt:12:12: error: cannot access 'val o7: Any': it is private in 'lib/W'
val e2 = w.o7
^
compiler/testData/compileKotlinAgainstCustomBinaries/anonymousObjectTypeMetadataKlib/anonymousObjectTypeMetadata.kt:13:12: error: cannot access 'val o10: Any': it is private in 'lib/O'
val e3 = O.o10
^
COMPILATION_ERROR
@@ -0,0 +1,4 @@
compiler/testData/compileKotlinAgainstCustomBinaries/classfileWithoutConstructors/shouldNotCompile.kt:6:9: error: resolution to the classifier 'class TopLevelKt : Any' is not appropriate here.
TopLevelKt() // error here
^
COMPILATION_ERROR
@@ -1,2 +1,2 @@
warning: compiler flag -Xuse-k2 is deprecated; please use "-language-version 2.0" instead warning: deprecated compiler flag -Xuse-k2 is redundant because of "-language-version 2.0" and should be removed
OK OK
@@ -0,0 +1,19 @@
compiler/testData/compileKotlinAgainstCustomBinaries/internalFromForeignModule/source.kt:3:21: error: cannot access 'interface InternalInterface : Any': it is internal in file
private fun test(i: InternalInterface): InternalTypealias {
^
compiler/testData/compileKotlinAgainstCustomBinaries/internalFromForeignModule/source.kt:3:41: error: cannot access 'typealias InternalTypealias = InternalInterface': it is internal in file
private fun test(i: InternalInterface): InternalTypealias {
^
compiler/testData/compileKotlinAgainstCustomBinaries/internalFromForeignModule/source.kt:4:19: error: cannot access 'fun internalMemberFun(): Unit': it is internal in 'a/PublicClass'
PublicClass().internalMemberFun()
^
compiler/testData/compileKotlinAgainstCustomBinaries/internalFromForeignModule/source.kt:5:17: error: cannot access 'companion object Companion : Any': it is internal in 'a/PublicClass'
PublicClass.Companion
^
compiler/testData/compileKotlinAgainstCustomBinaries/internalFromForeignModule/source.kt:7:5: error: cannot access 'fun internalFun(s: String): String': it is internal in file
internalFun(internalVal)
^
compiler/testData/compileKotlinAgainstCustomBinaries/internalFromForeignModule/source.kt:7:17: error: cannot access 'val internalVal: String': it is internal in file
internalFun(internalVal)
^
COMPILATION_ERROR
@@ -0,0 +1,7 @@
compiler/testData/compileKotlinAgainstCustomBinaries/prohibitNestedClassesByDollarName/main.kt:6:10: error: unresolved reference: Outer$Nested
test.`Outer$Nested`()
^
compiler/testData/compileKotlinAgainstCustomBinaries/prohibitNestedClassesByDollarName/main.kt:9:10: error: unresolved reference: JavaOuter$JavaNested
test.`JavaOuter$JavaNested`()
^
COMPILATION_ERROR
@@ -0,0 +1,11 @@
warning: ATTENTION!
This build uses unsafe internal compiler arguments:
-XXLanguage:+AllowSealedInheritorsInDifferentFilesOfSamePackage
-XXLanguage:+SealedInterfaces
This mode is not recommended for production use,
as no stability/compatibility guarantees are given on
compiler or generated code. Use it at your own risk!
OK
@@ -148,7 +148,7 @@ abstract class AbstractKotlinCompilerIntegrationTest : TestCaseWithTmpdir() {
) )
} }
protected fun compileKotlin( protected open fun compileKotlin(
fileName: String, fileName: String,
output: File, output: File,
classpath: List<File> = emptyList(), classpath: List<File> = emptyList(),
@@ -17,15 +17,10 @@ import org.jetbrains.kotlin.cli.transformMetadataInClassFile
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
import org.jetbrains.kotlin.config.JvmTarget import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.LanguageVersion import org.jetbrains.kotlin.config.LanguageVersion
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
import org.jetbrains.kotlin.incremental.LocalFileKotlinClass import org.jetbrains.kotlin.incremental.LocalFileKotlinClass
import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion
import org.jetbrains.kotlin.metadata.jvm.deserialization.ModuleMapping import org.jetbrains.kotlin.metadata.jvm.deserialization.ModuleMapping
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils.isObject
import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil
import org.jetbrains.kotlin.test.ConfigurationKind import org.jetbrains.kotlin.test.ConfigurationKind
import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.MockLibraryUtil import org.jetbrains.kotlin.test.MockLibraryUtil
@@ -42,29 +37,44 @@ import java.util.jar.JarFile
import java.util.zip.ZipOutputStream import java.util.zip.ZipOutputStream
import kotlin.experimental.xor import kotlin.experimental.xor
class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegrationTest() { abstract class AbstractCompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegrationTest() {
abstract val languageVersion: LanguageVersion
override val testDataPath: String override val testDataPath: String
get() = "compiler/testData/compileKotlinAgainstCustomBinaries/" get() = "compiler/testData/compileKotlinAgainstCustomBinaries/"
private fun analyzeFileToPackageView(vararg extraClassPath: File): PackageViewDescriptor { // Compiles Kotlin sources with the language version used in this test, unless language version is explicitly overridden.
val environment = createEnvironment(extraClassPath.toList()) // If this is the FIR test (so language version is >= 2.0), uses the ".fir.txt" file to check compilation result if it's present.
// Note that it also has effect if invoked from `compileLibrary`.
val ktFile = KotlinTestUtils.loadKtFile(environment.project, getTestDataFileWithExtension("kt")) override fun compileKotlin(
val result = JvmResolveUtil.analyzeAndCheckForErrors(ktFile, environment) fileName: String,
output: File,
return result.moduleDescriptor.getPackage(LoadDescriptorUtil.TEST_PACKAGE_FQNAME).also { classpath: List<File>,
assertFalse("Failed to find package: " + LoadDescriptorUtil.TEST_PACKAGE_FQNAME, it.isEmpty()) compiler: CLICompiler<*>,
} additionalOptions: List<String>,
expectedFileName: String?,
additionalSources: List<String>,
): Pair<String, ExitCode> {
val options =
if ("-language-version" in additionalOptions) additionalOptions
else additionalOptions + listOf("-language-version", languageVersion.versionString)
val expectedFirFile = expectedFileName?.replace(".txt", ".fir.txt")?.let { File(testDataDirectory, it) }
return super.compileKotlin(
fileName, output, classpath, compiler, options,
if (expectedFirFile != null && languageVersion.usesK2 && expectedFirFile.exists()) expectedFirFile.name else expectedFileName,
additionalSources
)
} }
private fun createEnvironment(extraClassPath: List<File>): KotlinCoreEnvironment { protected open fun muteForK2(test: () -> Unit) {
test()
}
protected fun createEnvironment(extraClassPath: List<File>): KotlinCoreEnvironment {
val configuration = KotlinTestUtils.newConfiguration(ConfigurationKind.ALL, TestJdkKind.MOCK_JDK, *extraClassPath.toTypedArray()) val configuration = KotlinTestUtils.newConfiguration(ConfigurationKind.ALL, TestJdkKind.MOCK_JDK, *extraClassPath.toTypedArray())
return KotlinCoreEnvironment.createForTests(testRootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES) return KotlinCoreEnvironment.createForTests(testRootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
} }
private fun analyzeAndGetAllDescriptors(vararg extraClassPath: File): Collection<DeclarationDescriptor> =
DescriptorUtils.getAllDescriptors(analyzeFileToPackageView(*extraClassPath).memberScope)
private fun doTestBrokenLibrary(libraryName: String, vararg pathsToDelete: String, additionalOptions: List<String> = emptyList()) { private fun doTestBrokenLibrary(libraryName: String, vararg pathsToDelete: String, additionalOptions: List<String> = emptyList()) {
// This function compiles a library, then deletes one class file and attempts to compile a Kotlin source against // This function compiles a library, then deletes one class file and attempts to compile a Kotlin source against
// this broken library. The expected result is an error message from the compiler // this broken library. The expected result is an error message from the compiler
@@ -122,42 +132,32 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
fun testRawTypes() { // Fixed in the LV2.0 branch.
fun testRawTypes() = muteForK2 {
compileKotlin("main.kt", tmpdir, listOf(compileLibrary("library"))) compileKotlin("main.kt", tmpdir, listOf(compileLibrary("library")))
} }
fun testDuplicateObjectInBinaryAndSources() {
val allDescriptors = analyzeAndGetAllDescriptors(compileLibrary("library"))
assertEquals(allDescriptors.toString(), 2, allDescriptors.size)
for (descriptor in allDescriptors) {
assertTrue("Wrong name: $descriptor", descriptor.name.asString() == "Lol")
assertTrue("Should be an object: $descriptor", isObject(descriptor))
}
}
fun testBrokenJarWithNoClassForObject() {
val brokenJar = copyJarFileWithoutEntry(compileLibrary("library"), "test/Lol.class")
val allDescriptors = analyzeAndGetAllDescriptors(brokenJar)
assertEmpty("No descriptors should be found: $allDescriptors", allDescriptors)
}
fun testSameLibraryTwiceInClasspath() { fun testSameLibraryTwiceInClasspath() {
compileKotlin("source.kt", tmpdir, listOf(compileLibrary("library-1"), compileLibrary("library-2"))) compileKotlin("source.kt", tmpdir, listOf(compileLibrary("library-1"), compileLibrary("library-2")))
} }
fun testMissingEnumReferencedInAnnotationArgument() { // KT-60778 K2: implement MISSING_DEPENDENCY_CLASS(_SUPERCLASS) errors
fun testMissingEnumReferencedInAnnotationArgument() = muteForK2 {
doTestBrokenLibrary("library", "a/E.class") doTestBrokenLibrary("library", "a/E.class")
} }
fun testIncompleteHierarchyInJava() { // KT-60778 K2: implement MISSING_DEPENDENCY_CLASS(_SUPERCLASS) errors
fun testIncompleteHierarchyInJava() = muteForK2 {
doTestBrokenLibrary("library", "test/Super.class") doTestBrokenLibrary("library", "test/Super.class")
} }
fun testIncompleteHierarchyInKotlin() { // KT-60778 K2: implement MISSING_DEPENDENCY_CLASS(_SUPERCLASS) errors
fun testIncompleteHierarchyInKotlin() = muteForK2 {
doTestBrokenLibrary("library", "test/Super.class") doTestBrokenLibrary("library", "test/Super.class")
} }
fun testIncompleteHierarchyMissingInterface() { // KT-60778 K2: implement MISSING_DEPENDENCY_CLASS(_SUPERCLASS) errors
fun testIncompleteHierarchyMissingInterface() = muteForK2 {
doTestBrokenLibrary("library", "test/A.class") doTestBrokenLibrary("library", "test/A.class")
} }
@@ -165,7 +165,8 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
doTestBrokenLibrary("library", "test/Super.class") doTestBrokenLibrary("library", "test/Super.class")
} }
fun testMissingStaticClass() { // KT-60778 K2: implement MISSING_DEPENDENCY_CLASS(_SUPERCLASS) errors
fun testMissingStaticClass() = muteForK2 {
doTestBrokenLibrary("library", "test/C\$D.class") doTestBrokenLibrary("library", "test/C\$D.class")
} }
@@ -173,7 +174,8 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
doTestBrokenLibrary("library", "test/Super.class") doTestBrokenLibrary("library", "test/Super.class")
} }
fun testIncompleteHierarchyWithExtendedCompilerChecks() { // KT-60778 K2: implement MISSING_DEPENDENCY_CLASS(_SUPERCLASS) errors
fun testIncompleteHierarchyWithExtendedCompilerChecks() = muteForK2 {
doTestBrokenLibrary( doTestBrokenLibrary(
"library", "library",
"test/Super.class", "test/Super.class",
@@ -181,15 +183,18 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
) )
} }
fun testIncompleteHierarchyErrorPositions() { // KT-60778 K2: implement MISSING_DEPENDENCY_CLASS(_SUPERCLASS) errors
fun testIncompleteHierarchyErrorPositions() = muteForK2 {
doTestBrokenLibrary("library", "test/Super.class") doTestBrokenLibrary("library", "test/Super.class")
} }
fun testIncompleteHierarchyOfEnclosingClass() { // KT-60778 K2: implement MISSING_DEPENDENCY_CLASS(_SUPERCLASS) errors
fun testIncompleteHierarchyOfEnclosingClass() = muteForK2 {
doTestBrokenLibrary("library", "test/Super.class") doTestBrokenLibrary("library", "test/Super.class")
} }
fun testMissingDependencySimple() { // KT-60778 K2: implement MISSING_DEPENDENCY_CLASS(_SUPERCLASS) errors
fun testMissingDependencySimple() = muteForK2 {
doTestBrokenLibrary("library", "a/A.class") doTestBrokenLibrary("library", "a/A.class")
} }
@@ -197,11 +202,13 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
doTestBrokenLibrary("library", "my/Some.class", additionalOptions = listOf("-Xuse-javac", "-Xcompile-java")) doTestBrokenLibrary("library", "my/Some.class", additionalOptions = listOf("-Xuse-javac", "-Xcompile-java"))
} }
fun testComputeSupertypeWithMissingDependency() { // KT-60778 K2: implement MISSING_DEPENDENCY_CLASS(_SUPERCLASS) errors
fun testComputeSupertypeWithMissingDependency() = muteForK2 {
doTestBrokenLibrary("library", "a/A.class") doTestBrokenLibrary("library", "a/A.class")
} }
fun testMissingDependencyDifferentCases() { // KT-60778 K2: implement MISSING_DEPENDENCY_CLASS(_SUPERCLASS) errors
fun testMissingDependencyDifferentCases() = muteForK2 {
doTestBrokenLibrary("library", "a/A.class") doTestBrokenLibrary("library", "a/A.class")
} }
@@ -209,7 +216,8 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
doTestBrokenLibrary("library", "a/A\$Anno.class") doTestBrokenLibrary("library", "a/A\$Anno.class")
} }
fun testMissingDependencyConflictingLibraries() { // KT-60778 K2: implement MISSING_DEPENDENCY_CLASS(_SUPERCLASS) errors
fun testMissingDependencyConflictingLibraries() = muteForK2 {
val library1 = copyJarFileWithoutEntry( val library1 = copyJarFileWithoutEntry(
compileLibrary("library1"), compileLibrary("library1"),
"a/A.class", "a/A\$Inner.class", "a/AA.class", "a/AA\$Inner.class", "a/A.class", "a/A\$Inner.class", "a/AA.class", "a/AA\$Inner.class",
@@ -223,11 +231,13 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
compileKotlin("source.kt", tmpdir, listOf(library1, library2)) compileKotlin("source.kt", tmpdir, listOf(library1, library2))
} }
fun testMissingDependencyJava() { // KT-60778 K2: implement MISSING_DEPENDENCY_CLASS(_SUPERCLASS) errors
fun testMissingDependencyJava() = muteForK2 {
doTestBrokenLibrary("library", "test/Bar.class") doTestBrokenLibrary("library", "test/Bar.class")
} }
fun testMissingDependencyJavaConflictingLibraries() { // KT-60778 K2: implement MISSING_DEPENDENCY_CLASS(_SUPERCLASS) errors
fun testMissingDependencyJavaConflictingLibraries() = muteForK2 {
val library1 = copyJarFileWithoutEntry(compileLibrary("library1"), "test/A.class", "test/A\$Inner.class") val library1 = copyJarFileWithoutEntry(compileLibrary("library1"), "test/A.class", "test/A\$Inner.class")
val library2 = copyJarFileWithoutEntry(compileLibrary("library2"), "test/A.class", "test/A\$Inner.class") val library2 = copyJarFileWithoutEntry(compileLibrary("library2"), "test/A.class", "test/A\$Inner.class")
compileKotlin("source.kt", tmpdir, listOf(library1, library2)) compileKotlin("source.kt", tmpdir, listOf(library1, library2))
@@ -263,11 +273,13 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
doTestPreReleaseKotlinLibrary(K2JVMCompiler(), "library", tmpdir, "-Xallow-unstable-dependencies", "-Xskip-prerelease-check") doTestPreReleaseKotlinLibrary(K2JVMCompiler(), "library", tmpdir, "-Xallow-unstable-dependencies", "-Xskip-prerelease-check")
} }
fun testWrongMetadataVersion() { // KT-60795 K2: missing INCOMPATIBLE_CLASS and corresponding CLI error
fun testWrongMetadataVersion() = muteForK2 {
doTestKotlinLibraryWithWrongMetadataVersion("library", null) doTestKotlinLibraryWithWrongMetadataVersion("library", null)
} }
fun testWrongMetadataVersionBadMetadata() { // KT-60795 K2: missing INCOMPATIBLE_CLASS and corresponding CLI error
fun testWrongMetadataVersionBadMetadata() = muteForK2 {
doTestKotlinLibraryWithWrongMetadataVersion("library", { name, value -> doTestKotlinLibraryWithWrongMetadataVersion("library", { name, value ->
if (JvmAnnotationNames.METADATA_DATA_FIELD_NAME == name) { if (JvmAnnotationNames.METADATA_DATA_FIELD_NAME == name) {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
@@ -279,38 +291,40 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
}) })
} }
fun testWrongMetadataVersionBadMetadata2() { // KT-60795 K2: missing INCOMPATIBLE_CLASS and corresponding CLI error
fun testWrongMetadataVersionBadMetadata2() = muteForK2 {
doTestKotlinLibraryWithWrongMetadataVersion("library", { name, _ -> doTestKotlinLibraryWithWrongMetadataVersion("library", { name, _ ->
if (JvmAnnotationNames.METADATA_STRINGS_FIELD_NAME == name) arrayOf<String>() else null if (JvmAnnotationNames.METADATA_STRINGS_FIELD_NAME == name) arrayOf<String>() else null
}) })
} }
fun testWrongMetadataVersionSkipVersionCheck() { // KT-60795 K2: missing INCOMPATIBLE_CLASS and corresponding CLI error
fun testWrongMetadataVersionSkipVersionCheck() = muteForK2 {
doTestKotlinLibraryWithWrongMetadataVersion("library", null, "-Xskip-metadata-version-check") doTestKotlinLibraryWithWrongMetadataVersion("library", null, "-Xskip-metadata-version-check")
} }
fun testWrongMetadataVersionSkipPrereleaseCheckHasNoEffect() { // KT-60795 K2: missing INCOMPATIBLE_CLASS and corresponding CLI error
fun testWrongMetadataVersionSkipPrereleaseCheckHasNoEffect() = muteForK2 {
doTestKotlinLibraryWithWrongMetadataVersion("library", null, "-Xskip-prerelease-check") doTestKotlinLibraryWithWrongMetadataVersion("library", null, "-Xskip-prerelease-check")
} }
fun testRequireKotlin() { // KT-59901 K2: Disappeared API_NOT_AVAILABLE
fun testRequireKotlin() = muteForK2 {
compileKotlin("source.kt", tmpdir, listOf(compileLibrary("library"))) compileKotlin("source.kt", tmpdir, listOf(compileLibrary("library")))
} }
fun testHasStableParameterNames() { // KT-59901 K2: Disappeared API_NOT_AVAILABLE
val library = compileLibrary("library", additionalOptions = listOf("-language-version", "2.0")) fun testRequireKotlinInNestedClasses() = muteForK2 {
compileKotlin("source.kt", tmpdir, listOf(library), additionalOptions = listOf("-language-version", "2.0"))
}
fun testRequireKotlinInNestedClasses() {
compileKotlin("source.kt", tmpdir, listOf(compileLibrary("library"))) compileKotlin("source.kt", tmpdir, listOf(compileLibrary("library")))
} }
fun testRequireKotlinInNestedClassesJs() { // KT-59901 K2: Disappeared API_NOT_AVAILABLE
fun testRequireKotlinInNestedClassesJs() = muteForK2 {
compileKotlin("source.kt", File(tmpdir, "usage.js"), listOf(compileJsLibrary("library")), K2JSCompiler()) compileKotlin("source.kt", File(tmpdir, "usage.js"), listOf(compileJsLibrary("library")), K2JSCompiler())
} }
fun testRequireKotlinInNestedClassesAgainst14Js() { // KT-59901 K2: Disappeared API_NOT_AVAILABLE
fun testRequireKotlinInNestedClassesAgainst14Js() = muteForK2 {
val library = compileJsLibrary("library", additionalOptions = listOf("-Xmetadata-version=1.4.0")) val library = compileJsLibrary("library", additionalOptions = listOf("-Xmetadata-version=1.4.0"))
compileKotlin( compileKotlin(
"source.kt", File(tmpdir, "usage.js"), listOf(library), K2JSCompiler(), "source.kt", File(tmpdir, "usage.js"), listOf(library), K2JSCompiler(),
@@ -323,7 +337,8 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
compileKotlin("source.kt", tmpdir, listOf(library)) compileKotlin("source.kt", tmpdir, listOf(library))
} }
fun testStrictMetadataVersionSemanticsOldVersion() { // KT-60795 K2: missing INCOMPATIBLE_CLASS and corresponding CLI error
fun testStrictMetadataVersionSemanticsOldVersion() = muteForK2 {
val nextMetadataVersion = JvmMetadataVersion.INSTANCE.next() val nextMetadataVersion = JvmMetadataVersion.INSTANCE.next()
val library = compileLibrary( val library = compileLibrary(
"library", additionalOptions = listOf("-Xgenerate-strict-metadata-version", "-Xmetadata-version=$nextMetadataVersion") "library", additionalOptions = listOf("-Xgenerate-strict-metadata-version", "-Xmetadata-version=$nextMetadataVersion")
@@ -435,7 +450,8 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
compileKotlin("source.kt", tmpdir, listOf(File(tmpdir, "library.jar"))) compileKotlin("source.kt", tmpdir, listOf(File(tmpdir, "library.jar")))
} }
fun testInnerClassPackageConflict2() { // KT-60792 K2 can resolve FQ type name to a nested classifier even in presence of a parent package
fun testInnerClassPackageConflict2() = muteForK2 {
val library1 = compileLibrary("library1", destination = File(tmpdir, "library1")) val library1 = compileLibrary("library1", destination = File(tmpdir, "library1"))
val library2 = compileLibrary("library2", destination = File(tmpdir, "library2")) val library2 = compileLibrary("library2", destination = File(tmpdir, "library2"))
@@ -454,7 +470,8 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
compileKotlin("source.kt", tmpdir, listOf(library1)) compileKotlin("source.kt", tmpdir, listOf(library1))
} }
fun testWrongInlineTarget() { // KT-60777 K2: missing INLINE_FROM_HIGHER_PLATFORM
fun testWrongInlineTarget() = muteForK2 {
val library = compileLibrary("library", additionalOptions = listOf("-jvm-target", "11")) val library = compileLibrary("library", additionalOptions = listOf("-jvm-target", "11"))
compileKotlin("source.kt", tmpdir, listOf(library), additionalOptions = listOf("-jvm-target", "1.8")) compileKotlin("source.kt", tmpdir, listOf(library), additionalOptions = listOf("-jvm-target", "1.8"))
@@ -497,14 +514,8 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
compileKotlin("source.kt", tmpdir, listOf(library), additionalOptions = listOf("-Xfriend-paths=${library.path}")) compileKotlin("source.kt", tmpdir, listOf(library), additionalOptions = listOf("-Xfriend-paths=${library.path}"))
} }
fun testInternalFromFriendModuleFir() { // KT-60791 K2: implement EXPLICIT_OVERRIDE_REQUIRED_IN_MIXED(COMPATIBILITY)_MODE
val library = compileLibrary("library") fun testJvmDefaultClashWithOld() = muteForK2 {
compileKotlin(
"source.kt", tmpdir, listOf(library), additionalOptions = listOf("-Xfriend-paths=${library.path}", "-language-version", "2.0")
)
}
fun testJvmDefaultClashWithOld() {
val library = compileLibrary("library", additionalOptions = listOf("-Xjvm-default=disable")) val library = compileLibrary("library", additionalOptions = listOf("-Xjvm-default=disable"))
compileKotlin("source.kt", tmpdir, listOf(library), additionalOptions = listOf("-jvm-target", "1.8", "-Xjvm-default=all")) compileKotlin("source.kt", tmpdir, listOf(library), additionalOptions = listOf("-jvm-target", "1.8", "-Xjvm-default=all"))
} }
@@ -514,7 +525,8 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
compileKotlin("contextualDeclarationUse.kt", tmpdir, listOf(library), additionalOptions = listOf("-Xskip-prerelease-check")) compileKotlin("contextualDeclarationUse.kt", tmpdir, listOf(library), additionalOptions = listOf("-Xskip-prerelease-check"))
} }
fun testJvmDefaultClashWithNoCompatibility() { // KT-60791 K2: implement EXPLICIT_OVERRIDE_REQUIRED_IN_MIXED(COMPATIBILITY)_MODE
fun testJvmDefaultClashWithNoCompatibility() = muteForK2 {
val library = compileLibrary("library", additionalOptions = listOf("-Xjvm-default=disable")) val library = compileLibrary("library", additionalOptions = listOf("-Xjvm-default=disable"))
compileKotlin( compileKotlin(
"source.kt", tmpdir, listOf(library), additionalOptions = listOf("-jvm-target", "1.8", "-Xjvm-default=all-compatibility") "source.kt", tmpdir, listOf(library), additionalOptions = listOf("-jvm-target", "1.8", "-Xjvm-default=all-compatibility")
@@ -541,7 +553,8 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
) )
} }
fun testInternalFromForeignModuleJs() { // KT-60531 K2/JS: Report diagnostics before running FIR2IR
fun testInternalFromForeignModuleJs() = muteForK2 {
compileKotlin( compileKotlin(
"source.kt", "source.kt",
File(tmpdir, "usage.js"), File(tmpdir, "usage.js"),
@@ -566,7 +579,7 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
val library = compileCommonLibrary("library") val library = compileCommonLibrary("library")
compileKotlin( compileKotlin(
"source.kt", tmpdir, listOf(library), K2MetadataCompiler(), listOf( "source.kt", tmpdir, listOf(library), K2MetadataCompiler(), listOf(
// TODO: "-Xfriend-paths=${library.path}" "-Xfriend-paths=${library.path}"
) )
) )
} }
@@ -581,52 +594,42 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
} }
} }
fun testFirAgainstFirUsingFlag() { fun testIncorrectJavaSignature() {
val library = compileLibrary("library", additionalOptions = listOf("-language-version", "2.0"))
compileKotlin("source.kt", tmpdir, listOf(library), additionalOptions = listOf("-Xuse-k2"))
}
fun testFirAgainstFir() {
val library = compileLibrary("library", additionalOptions = listOf("-language-version", "2.0"))
compileKotlin("source.kt", tmpdir, listOf(library), additionalOptions = listOf("-language-version", "2.0"))
}
fun testFirIncorrectJavaSignature() {
compileKotlin( compileKotlin(
"source.kt", tmpdir, "source.kt", tmpdir,
listOf(), listOf(),
additionalOptions = listOf("-language-version", "2.0"),
additionalSources = listOf("A.java", "B.java"), additionalSources = listOf("A.java", "B.java"),
) )
} }
fun testFirIncorrectRemoveSignature() { fun testIncorrectRemoveSignature() {
compileKotlin( compileKotlin(
"source.kt", tmpdir, "source.kt", tmpdir,
listOf(), listOf(),
additionalOptions = listOf("-language-version", "2.0"),
additionalSources = listOf("A.java", "B.java"), additionalSources = listOf("A.java", "B.java"),
) )
} }
fun testAgainstStable() { fun testAgainstStable() {
val library = compileLibrary("library") val library = compileLibrary("library", additionalOptions = listOf("-language-version", "1.9"))
compileKotlin("source.kt", tmpdir, listOf(library)) compileKotlin("source.kt", tmpdir, listOf(library))
val library2 = compileLibrary("library", additionalOptions = listOf("-Xabi-stability=stable")) val library2 = compileLibrary("library", additionalOptions = listOf("-language-version", "1.9", "-Xabi-stability=stable"))
compileKotlin("source.kt", tmpdir, listOf(library2)) compileKotlin("source.kt", tmpdir, listOf(library2))
} }
fun testAgainstFir() { fun testAgainstFir() {
val library = compileLibrary("library", additionalOptions = listOf("-language-version", "2.0")) val library = compileLibrary("library", additionalOptions = listOf("-language-version", "2.0"))
compileKotlin("source.kt", tmpdir, listOf(library)) compileKotlin("source.kt", tmpdir, listOf(library))
}
fun testAgainstFirWithUnstableAbi() {
val library2 = compileLibrary("library", additionalOptions = listOf("-language-version", "2.0", "-Xabi-stability=unstable")) val library2 = compileLibrary("library", additionalOptions = listOf("-language-version", "2.0", "-Xabi-stability=unstable"))
compileKotlin("source.kt", tmpdir, listOf(library2)) compileKotlin("source.kt", tmpdir, listOf(library2))
} }
fun testAgainstUnstable() { fun testAgainstUnstable() {
val library = compileLibrary("library", additionalOptions = listOf("-Xabi-stability=unstable")) val library = compileLibrary("library", additionalOptions = listOf("-language-version", "1.9", "-Xabi-stability=unstable"))
compileKotlin("source.kt", tmpdir, listOf(library)) compileKotlin("source.kt", tmpdir, listOf(library))
} }
@@ -660,7 +663,8 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
compileKotlin("main.kt", tmpdir, listOf(library), additionalOptions = features) compileKotlin("main.kt", tmpdir, listOf(library), additionalOptions = features)
} }
fun testUnreachableExtensionVarPropertyDeclaration() { // Fixed in the LV2.0 branch.
fun testUnreachableExtensionVarPropertyDeclaration() = muteForK2 {
val (output, exitCode) = compileKotlin("source.kt", tmpdir, expectedFileName = null) val (output, exitCode) = compileKotlin("source.kt", tmpdir, expectedFileName = null)
assertEquals("Output:\n$output", ExitCode.COMPILATION_ERROR, exitCode) assertEquals("Output:\n$output", ExitCode.COMPILATION_ERROR, exitCode)
} }
@@ -696,27 +700,9 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
) )
} }
fun testDeserializedAnnotationReferencesJava() {
// Only Java
val libraryAnnotation = compileLibrary("libraryAnnotation")
// Specifically, use K1
// Remove "-Xuse-k2=false" argument once it becomes forbidden
val libraryUsingAnnotation = compileLibrary(
"libraryUsingAnnotation",
additionalOptions = listOf("-language-version", "1.8", "-Xuse-k2=false"),
extraClassPath = listOf(libraryAnnotation)
)
compileKotlin(
"usage.kt",
output = tmpdir,
classpath = listOf(libraryAnnotation, libraryUsingAnnotation),
additionalOptions = listOf("-language-version", "2.0")
)
}
companion object { companion object {
private fun copyJarFileWithoutEntry(jarPath: File, vararg entriesToDelete: String): File = @JvmStatic
protected fun copyJarFileWithoutEntry(jarPath: File, vararg entriesToDelete: String): File =
transformJar(jarPath, { _, bytes -> bytes }, entriesToDelete.toSet()) transformJar(jarPath, { _, bytes -> bytes }, entriesToDelete.toSet())
private fun transformJar( private fun transformJar(
@@ -0,0 +1,48 @@
/*
* 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.jvm.compiler
import org.jetbrains.kotlin.config.LanguageVersion
class FirCompileKotlinAgainstCustomBinariesTest : AbstractCompileKotlinAgainstCustomBinariesTest() {
override val languageVersion: LanguageVersion
get() = maxOf(LanguageVersion.LATEST_STABLE, LanguageVersion.KOTLIN_2_0)
override fun muteForK2(test: () -> Unit) {
try {
test()
} catch (e: Throwable) {
return
}
fail("Looks like this test can be unmuted. Remove the call to `muteForK2`.")
}
fun testHasStableParameterNames() {
compileKotlin("source.kt", tmpdir, listOf(compileLibrary("library")))
}
fun testDeserializedAnnotationReferencesJava() {
// Only Java
val libraryAnnotation = compileLibrary("libraryAnnotation")
// Specifically, use K1
// Remove "-Xuse-k2=false" argument once it becomes forbidden
val libraryUsingAnnotation = compileLibrary(
"libraryUsingAnnotation",
additionalOptions = listOf("-language-version", "1.8", "-Xuse-k2=false"),
extraClassPath = listOf(libraryAnnotation)
)
compileKotlin(
"usage.kt",
output = tmpdir,
classpath = listOf(libraryAnnotation, libraryUsingAnnotation),
)
}
fun testFirAgainstFirUsingFlag() {
compileKotlin("source.kt", tmpdir, listOf(compileLibrary("library")), additionalOptions = listOf("-Xuse-k2"))
}
}
@@ -0,0 +1,48 @@
/*
* Copyright 2010-2023 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.jvm.compiler
import org.jetbrains.kotlin.config.LanguageVersion
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil
import org.jetbrains.kotlin.test.KotlinTestUtils
import java.io.File
class OldCompileKotlinAgainstCustomBinariesTest : AbstractCompileKotlinAgainstCustomBinariesTest() {
override val languageVersion: LanguageVersion
get() = LanguageVersion.KOTLIN_1_9
private fun analyzeFileToPackageView(vararg extraClassPath: File): PackageViewDescriptor {
val environment = createEnvironment(extraClassPath.toList())
val ktFile = KotlinTestUtils.loadKtFile(environment.project, getTestDataFileWithExtension("kt"))
val result = JvmResolveUtil.analyzeAndCheckForErrors(ktFile, environment)
return result.moduleDescriptor.getPackage(LoadDescriptorUtil.TEST_PACKAGE_FQNAME).also {
assertFalse("Failed to find package: " + LoadDescriptorUtil.TEST_PACKAGE_FQNAME, it.isEmpty())
}
}
private fun analyzeAndGetAllDescriptors(vararg extraClassPath: File): Collection<DeclarationDescriptor> =
DescriptorUtils.getAllDescriptors(analyzeFileToPackageView(*extraClassPath).memberScope)
fun testDuplicateObjectInBinaryAndSources() {
val allDescriptors = analyzeAndGetAllDescriptors(compileLibrary("library"))
assertEquals(allDescriptors.toString(), 2, allDescriptors.size)
for (descriptor in allDescriptors) {
assertTrue("Wrong name: $descriptor", descriptor.name.asString() == "Lol")
assertTrue("Should be an object: $descriptor", DescriptorUtils.isObject(descriptor))
}
}
fun testBrokenJarWithNoClassForObject() {
val brokenJar = copyJarFileWithoutEntry(compileLibrary("library"), "test/Lol.class")
val allDescriptors = analyzeAndGetAllDescriptors(brokenJar)
assertEmpty("No descriptors should be found: $allDescriptors", allDescriptors)
}
}