diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/firAgainstFir/output.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/againstFir/output.fir.txt similarity index 100% rename from compiler/testData/compileKotlinAgainstCustomBinaries/firAgainstFir/output.txt rename to compiler/testData/compileKotlinAgainstCustomBinaries/againstFir/output.fir.txt diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/firIncorrectJavaSignature/output.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/againstFirWithStableAbi/output.fir.txt similarity index 100% rename from compiler/testData/compileKotlinAgainstCustomBinaries/firIncorrectJavaSignature/output.txt rename to compiler/testData/compileKotlinAgainstCustomBinaries/againstFirWithStableAbi/output.fir.txt diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/firAgainstFir/library/a.kt b/compiler/testData/compileKotlinAgainstCustomBinaries/againstFirWithUnstableAbi/library/a.kt similarity index 100% rename from compiler/testData/compileKotlinAgainstCustomBinaries/firAgainstFir/library/a.kt rename to compiler/testData/compileKotlinAgainstCustomBinaries/againstFirWithUnstableAbi/library/a.kt diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/firIncorrectRemoveSignature/output.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/againstFirWithUnstableAbi/output.fir.txt similarity index 100% rename from compiler/testData/compileKotlinAgainstCustomBinaries/firIncorrectRemoveSignature/output.txt rename to compiler/testData/compileKotlinAgainstCustomBinaries/againstFirWithUnstableAbi/output.fir.txt diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/againstFirWithUnstableAbi/output.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/againstFirWithUnstableAbi/output.txt new file mode 100644 index 00000000000..6495b48fe88 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/againstFirWithUnstableAbi/output.txt @@ -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 diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/firAgainstFir/source.kt b/compiler/testData/compileKotlinAgainstCustomBinaries/againstFirWithUnstableAbi/source.kt similarity index 100% rename from compiler/testData/compileKotlinAgainstCustomBinaries/firAgainstFir/source.kt rename to compiler/testData/compileKotlinAgainstCustomBinaries/againstFirWithUnstableAbi/source.kt diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/againstUnstable/output.fir.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/againstUnstable/output.fir.txt new file mode 100644 index 00000000000..d86bac9de59 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/againstUnstable/output.fir.txt @@ -0,0 +1 @@ +OK diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/anonymousObjectTypeMetadata/output.fir.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/anonymousObjectTypeMetadata/output.fir.txt new file mode 100644 index 00000000000..cb303cd887c --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/anonymousObjectTypeMetadata/output.fir.txt @@ -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 diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/anonymousObjectTypeMetadataKlib/output.fir.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/anonymousObjectTypeMetadataKlib/output.fir.txt new file mode 100644 index 00000000000..afe2d448c35 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/anonymousObjectTypeMetadataKlib/output.fir.txt @@ -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 diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/classfileWithoutConstructors/output.fir.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/classfileWithoutConstructors/output.fir.txt new file mode 100644 index 00000000000..9ac8a2c9157 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/classfileWithoutConstructors/output.fir.txt @@ -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 diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/firAgainstFirUsingFlag/output.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/firAgainstFirUsingFlag/output.txt index 01587e29e8e..426e84db76e 100644 --- a/compiler/testData/compileKotlinAgainstCustomBinaries/firAgainstFirUsingFlag/output.txt +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/firAgainstFirUsingFlag/output.txt @@ -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 diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/firIncorrectJavaSignature/A.java b/compiler/testData/compileKotlinAgainstCustomBinaries/incorrectJavaSignature/A.java similarity index 100% rename from compiler/testData/compileKotlinAgainstCustomBinaries/firIncorrectJavaSignature/A.java rename to compiler/testData/compileKotlinAgainstCustomBinaries/incorrectJavaSignature/A.java diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/firIncorrectJavaSignature/B.java b/compiler/testData/compileKotlinAgainstCustomBinaries/incorrectJavaSignature/B.java similarity index 100% rename from compiler/testData/compileKotlinAgainstCustomBinaries/firIncorrectJavaSignature/B.java rename to compiler/testData/compileKotlinAgainstCustomBinaries/incorrectJavaSignature/B.java diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/incorrectJavaSignature/output.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/incorrectJavaSignature/output.txt new file mode 100644 index 00000000000..d86bac9de59 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/incorrectJavaSignature/output.txt @@ -0,0 +1 @@ +OK diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/firIncorrectJavaSignature/source.kt b/compiler/testData/compileKotlinAgainstCustomBinaries/incorrectJavaSignature/source.kt similarity index 100% rename from compiler/testData/compileKotlinAgainstCustomBinaries/firIncorrectJavaSignature/source.kt rename to compiler/testData/compileKotlinAgainstCustomBinaries/incorrectJavaSignature/source.kt diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/firIncorrectRemoveSignature/A.java b/compiler/testData/compileKotlinAgainstCustomBinaries/incorrectRemoveSignature/A.java similarity index 100% rename from compiler/testData/compileKotlinAgainstCustomBinaries/firIncorrectRemoveSignature/A.java rename to compiler/testData/compileKotlinAgainstCustomBinaries/incorrectRemoveSignature/A.java diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/firIncorrectRemoveSignature/B.java b/compiler/testData/compileKotlinAgainstCustomBinaries/incorrectRemoveSignature/B.java similarity index 100% rename from compiler/testData/compileKotlinAgainstCustomBinaries/firIncorrectRemoveSignature/B.java rename to compiler/testData/compileKotlinAgainstCustomBinaries/incorrectRemoveSignature/B.java diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/incorrectRemoveSignature/output.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/incorrectRemoveSignature/output.txt new file mode 100644 index 00000000000..d86bac9de59 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/incorrectRemoveSignature/output.txt @@ -0,0 +1 @@ +OK diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/firIncorrectRemoveSignature/source.kt b/compiler/testData/compileKotlinAgainstCustomBinaries/incorrectRemoveSignature/source.kt similarity index 100% rename from compiler/testData/compileKotlinAgainstCustomBinaries/firIncorrectRemoveSignature/source.kt rename to compiler/testData/compileKotlinAgainstCustomBinaries/incorrectRemoveSignature/source.kt diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/internalFromForeignModule/output.fir.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/internalFromForeignModule/output.fir.txt new file mode 100644 index 00000000000..b0743833602 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/internalFromForeignModule/output.fir.txt @@ -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 diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/prohibitNestedClassesByDollarName/output.fir.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/prohibitNestedClassesByDollarName/output.fir.txt new file mode 100644 index 00000000000..c39b09946e5 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/prohibitNestedClassesByDollarName/output.fir.txt @@ -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 diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/sealedClassesAndInterfaces/output.fir.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/sealedClassesAndInterfaces/output.fir.txt new file mode 100644 index 00000000000..2ff1724177e --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/sealedClassesAndInterfaces/output.fir.txt @@ -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 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 c31dd6d4586..56ffa6786f2 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 @@ -148,7 +148,7 @@ abstract class AbstractKotlinCompilerIntegrationTest : TestCaseWithTmpdir() { ) } - protected fun compileKotlin( + protected open fun compileKotlin( fileName: String, output: File, classpath: List = emptyList(), diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/AbstractCompileKotlinAgainstCustomBinariesTest.kt similarity index 81% rename from compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt rename to compiler/tests/org/jetbrains/kotlin/jvm/compiler/AbstractCompileKotlinAgainstCustomBinariesTest.kt index f19a3665adc..9d46fe661c2 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/AbstractCompileKotlinAgainstCustomBinariesTest.kt @@ -17,15 +17,10 @@ import org.jetbrains.kotlin.cli.transformMetadataInClassFile import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime import org.jetbrains.kotlin.config.JvmTarget 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.load.java.JvmAnnotationNames import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion 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.KotlinTestUtils import org.jetbrains.kotlin.test.MockLibraryUtil @@ -42,29 +37,44 @@ import java.util.jar.JarFile import java.util.zip.ZipOutputStream import kotlin.experimental.xor -class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegrationTest() { +abstract class AbstractCompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegrationTest() { + abstract val languageVersion: LanguageVersion + override val testDataPath: String get() = "compiler/testData/compileKotlinAgainstCustomBinaries/" - 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()) - } + // Compiles Kotlin sources with the language version used in this test, unless language version is explicitly overridden. + // 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`. + override fun compileKotlin( + fileName: String, + output: File, + classpath: List, + compiler: CLICompiler<*>, + additionalOptions: List, + expectedFileName: String?, + additionalSources: List, + ): Pair { + 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): KotlinCoreEnvironment { + protected open fun muteForK2(test: () -> Unit) { + test() + } + + protected fun createEnvironment(extraClassPath: List): KotlinCoreEnvironment { val configuration = KotlinTestUtils.newConfiguration(ConfigurationKind.ALL, TestJdkKind.MOCK_JDK, *extraClassPath.toTypedArray()) return KotlinCoreEnvironment.createForTests(testRootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES) } - private fun analyzeAndGetAllDescriptors(vararg extraClassPath: File): Collection = - DescriptorUtils.getAllDescriptors(analyzeFileToPackageView(*extraClassPath).memberScope) - private fun doTestBrokenLibrary(libraryName: String, vararg pathsToDelete: String, additionalOptions: List = emptyList()) { // 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 @@ -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"))) } - 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() { 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") } - fun testIncompleteHierarchyInJava() { + // KT-60778 K2: implement MISSING_DEPENDENCY_CLASS(_SUPERCLASS) errors + fun testIncompleteHierarchyInJava() = muteForK2 { doTestBrokenLibrary("library", "test/Super.class") } - fun testIncompleteHierarchyInKotlin() { + // KT-60778 K2: implement MISSING_DEPENDENCY_CLASS(_SUPERCLASS) errors + fun testIncompleteHierarchyInKotlin() = muteForK2 { doTestBrokenLibrary("library", "test/Super.class") } - fun testIncompleteHierarchyMissingInterface() { + // KT-60778 K2: implement MISSING_DEPENDENCY_CLASS(_SUPERCLASS) errors + fun testIncompleteHierarchyMissingInterface() = muteForK2 { doTestBrokenLibrary("library", "test/A.class") } @@ -165,7 +165,8 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration 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") } @@ -173,7 +174,8 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration doTestBrokenLibrary("library", "test/Super.class") } - fun testIncompleteHierarchyWithExtendedCompilerChecks() { + // KT-60778 K2: implement MISSING_DEPENDENCY_CLASS(_SUPERCLASS) errors + fun testIncompleteHierarchyWithExtendedCompilerChecks() = muteForK2 { doTestBrokenLibrary( "library", "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") } - fun testIncompleteHierarchyOfEnclosingClass() { + // KT-60778 K2: implement MISSING_DEPENDENCY_CLASS(_SUPERCLASS) errors + fun testIncompleteHierarchyOfEnclosingClass() = muteForK2 { doTestBrokenLibrary("library", "test/Super.class") } - fun testMissingDependencySimple() { + // KT-60778 K2: implement MISSING_DEPENDENCY_CLASS(_SUPERCLASS) errors + fun testMissingDependencySimple() = muteForK2 { doTestBrokenLibrary("library", "a/A.class") } @@ -197,11 +202,13 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration 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") } - fun testMissingDependencyDifferentCases() { + // KT-60778 K2: implement MISSING_DEPENDENCY_CLASS(_SUPERCLASS) errors + fun testMissingDependencyDifferentCases() = muteForK2 { doTestBrokenLibrary("library", "a/A.class") } @@ -209,7 +216,8 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration doTestBrokenLibrary("library", "a/A\$Anno.class") } - fun testMissingDependencyConflictingLibraries() { + // KT-60778 K2: implement MISSING_DEPENDENCY_CLASS(_SUPERCLASS) errors + fun testMissingDependencyConflictingLibraries() = muteForK2 { val library1 = copyJarFileWithoutEntry( compileLibrary("library1"), "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)) } - fun testMissingDependencyJava() { + // KT-60778 K2: implement MISSING_DEPENDENCY_CLASS(_SUPERCLASS) errors + fun testMissingDependencyJava() = muteForK2 { 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 library2 = copyJarFileWithoutEntry(compileLibrary("library2"), "test/A.class", "test/A\$Inner.class") compileKotlin("source.kt", tmpdir, listOf(library1, library2)) @@ -263,11 +273,13 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration 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) } - fun testWrongMetadataVersionBadMetadata() { + // KT-60795 K2: missing INCOMPATIBLE_CLASS and corresponding CLI error + fun testWrongMetadataVersionBadMetadata() = muteForK2 { doTestKotlinLibraryWithWrongMetadataVersion("library", { name, value -> if (JvmAnnotationNames.METADATA_DATA_FIELD_NAME == name) { @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, _ -> if (JvmAnnotationNames.METADATA_STRINGS_FIELD_NAME == name) arrayOf() else null }) } - fun testWrongMetadataVersionSkipVersionCheck() { + // KT-60795 K2: missing INCOMPATIBLE_CLASS and corresponding CLI error + fun testWrongMetadataVersionSkipVersionCheck() = muteForK2 { 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") } - fun testRequireKotlin() { + // KT-59901 K2: Disappeared API_NOT_AVAILABLE + fun testRequireKotlin() = muteForK2 { compileKotlin("source.kt", tmpdir, listOf(compileLibrary("library"))) } - fun testHasStableParameterNames() { - val library = compileLibrary("library", additionalOptions = listOf("-language-version", "2.0")) - compileKotlin("source.kt", tmpdir, listOf(library), additionalOptions = listOf("-language-version", "2.0")) - } - - fun testRequireKotlinInNestedClasses() { + // KT-59901 K2: Disappeared API_NOT_AVAILABLE + fun testRequireKotlinInNestedClasses() = muteForK2 { 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()) } - fun testRequireKotlinInNestedClassesAgainst14Js() { + // KT-59901 K2: Disappeared API_NOT_AVAILABLE + fun testRequireKotlinInNestedClassesAgainst14Js() = muteForK2 { val library = compileJsLibrary("library", additionalOptions = listOf("-Xmetadata-version=1.4.0")) compileKotlin( "source.kt", File(tmpdir, "usage.js"), listOf(library), K2JSCompiler(), @@ -323,7 +337,8 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration 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 library = compileLibrary( "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"))) } - 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 library2 = compileLibrary("library2", destination = File(tmpdir, "library2")) @@ -454,7 +470,8 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration 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")) 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}")) } - fun testInternalFromFriendModuleFir() { - val library = compileLibrary("library") - compileKotlin( - "source.kt", tmpdir, listOf(library), additionalOptions = listOf("-Xfriend-paths=${library.path}", "-language-version", "2.0") - ) - } - - fun testJvmDefaultClashWithOld() { + // KT-60791 K2: implement EXPLICIT_OVERRIDE_REQUIRED_IN_MIXED(COMPATIBILITY)_MODE + fun testJvmDefaultClashWithOld() = muteForK2 { val library = compileLibrary("library", additionalOptions = listOf("-Xjvm-default=disable")) 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")) } - 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")) compileKotlin( "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( "source.kt", File(tmpdir, "usage.js"), @@ -566,7 +579,7 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration val library = compileCommonLibrary("library") compileKotlin( "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() { - 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() { + fun testIncorrectJavaSignature() { compileKotlin( "source.kt", tmpdir, listOf(), - additionalOptions = listOf("-language-version", "2.0"), additionalSources = listOf("A.java", "B.java"), ) } - fun testFirIncorrectRemoveSignature() { + fun testIncorrectRemoveSignature() { compileKotlin( "source.kt", tmpdir, listOf(), - additionalOptions = listOf("-language-version", "2.0"), additionalSources = listOf("A.java", "B.java"), ) } fun testAgainstStable() { - val library = compileLibrary("library") + val library = compileLibrary("library", additionalOptions = listOf("-language-version", "1.9")) 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)) } fun testAgainstFir() { val library = compileLibrary("library", additionalOptions = listOf("-language-version", "2.0")) compileKotlin("source.kt", tmpdir, listOf(library)) + } + fun testAgainstFirWithUnstableAbi() { val library2 = compileLibrary("library", additionalOptions = listOf("-language-version", "2.0", "-Xabi-stability=unstable")) compileKotlin("source.kt", tmpdir, listOf(library2)) } 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)) } @@ -660,7 +663,8 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration 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) 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 { - 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()) private fun transformJar( diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/FirCompileKotlinAgainstCustomBinariesTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/FirCompileKotlinAgainstCustomBinariesTest.kt new file mode 100644 index 00000000000..be7dcd873a3 --- /dev/null +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/FirCompileKotlinAgainstCustomBinariesTest.kt @@ -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")) + } +} diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/OldCompileKotlinAgainstCustomBinariesTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/OldCompileKotlinAgainstCustomBinariesTest.kt new file mode 100644 index 00000000000..d4cae86f53c --- /dev/null +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/OldCompileKotlinAgainstCustomBinariesTest.kt @@ -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 = + 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) + } +}