Support diagnostic tests with Kotlin against compiled Java

This commit is contained in:
Victor Petukhov
2020-12-11 17:25:16 +03:00
parent 6f8f531d87
commit 71ca18e937
5 changed files with 68 additions and 14 deletions
@@ -0,0 +1,43 @@
/*
* 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.checkers
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.MockLibraryUtil.compileJavaFilesLibraryToJar
import java.io.File
import kotlin.io.path.ExperimentalPathApi
import kotlin.io.path.createTempDirectory
abstract class AbstractForeignAnnotationsCompiledJavaDiagnosticTest : AbstractDiagnosticsTest() {
@OptIn(ExperimentalPathApi::class)
override fun doMultiFileTest(
wholeFile: File,
files: List<TestFile>
) {
val ktFiles = files.filter { !it.name.endsWith(".java") }
val dir = createTempDirectory()
val javaFile = File("${wholeFile.parentFile.path}/${wholeFile.nameWithoutExtension}.java")
File("$dir/${wholeFile.nameWithoutExtension}.java").apply { createNewFile() }.writeText(javaFile.readText())
File(FOREIGN_JDK8_ANNOTATIONS_SOURCES_PATH).copyRecursively(File("$dir/annotations/"))
super.doMultiFileTest(
wholeFile,
ktFiles,
compileJavaFilesLibraryToJar(dir.toString(), "foreign-annotations"),
usePsiClassFilesReading = false,
excludeNonTypeUseJetbrainsAnnotations = true
)
}
override fun doTest(filePath: String) {
val file = File(filePath)
val expectedText = KotlinTestUtils.doLoadFile(file)
doMultiFileTest(file, createTestFilesFromFile(file, expectedText))
}
}
@@ -27,7 +27,9 @@ abstract class AbstractJspecifyAnnotationsTest : AbstractDiagnosticsTest() {
super.doMultiFileTest( super.doMultiFileTest(
wholeFile, wholeFile,
files, files,
MockLibraryUtil.compileJavaFilesLibraryToJar(FOREIGN_JDK8_ANNOTATIONS_SOURCES_PATH, "foreign-annotations") MockLibraryUtil.compileJavaFilesLibraryToJar(FOREIGN_JDK8_ANNOTATIONS_SOURCES_PATH, "foreign-annotations"),
usePsiClassFilesReading = false,
excludeNonTypeUseJetbrainsAnnotations = true
) )
} }
@@ -86,9 +86,12 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
fun doMultiFileTest( fun doMultiFileTest(
wholeFile: File, wholeFile: File,
files: List<TestFile>, files: List<TestFile>,
additionalClasspath: File? = null additionalClasspath: File? = null,
usePsiClassFilesReading: Boolean = true,
excludeNonTypeUseJetbrainsAnnotations: Boolean = false
) { ) {
environment = createEnvironment(wholeFile, files, additionalClasspath) environment =
createEnvironment(wholeFile, files, additionalClasspath, usePsiClassFilesReading, excludeNonTypeUseJetbrainsAnnotations)
//after environment initialization cause of `tearDown` logic, maybe it's obsolete //after environment initialization cause of `tearDown` logic, maybe it's obsolete
if (shouldSkipTest(wholeFile, files)) { if (shouldSkipTest(wholeFile, files)) {
println("${wholeFile.name} test is skipped") println("${wholeFile.name} test is skipped")
@@ -46,13 +46,16 @@ abstract class KotlinMultiFileTestWithJava<M : KotlinBaseTest.TestModule, F : Ko
protected fun createEnvironment( protected fun createEnvironment(
file: File, file: File,
files: List<F>, files: List<F>,
additionalClasspath: File? = null additionalClasspath: File? = null,
usePsiClassFilesReading: Boolean = true,
excludeNonTypeUseJetbrainsAnnotations: Boolean = false
): KotlinCoreEnvironment { ): KotlinCoreEnvironment {
val defaultClasspath = getClasspath(file, excludeNonTypeUseJetbrainsAnnotations)
val configuration = createConfiguration( val configuration = createConfiguration(
extractConfigurationKind(files), extractConfigurationKind(files),
getTestJdkKind(files), getTestJdkKind(files),
backend, backend,
if (additionalClasspath == null) getClasspath(file) else getClasspath(file) + additionalClasspath, if (additionalClasspath == null) defaultClasspath else defaultClasspath + additionalClasspath,
if (isJavaSourceRootNeeded()) listOf(javaFilesDir) else emptyList(), if (isJavaSourceRootNeeded()) listOf(javaFilesDir) else emptyList(),
files files
) )
@@ -63,9 +66,9 @@ abstract class KotlinMultiFileTestWithJava<M : KotlinBaseTest.TestModule, F : Ko
configuration.addKotlinSourceRoot(kotlinSourceRoot!!.path) configuration.addKotlinSourceRoot(kotlinSourceRoot!!.path)
} }
// Currently, we're testing IDE behavior when generating the .txt files for comparison, but this can be changed. // Currently, by default, we're testing IDE behavior when generating the .txt files for comparison, but this can be changed.
// The main difference is the fact that the new class file reading implementation doesn't load parameter names from JDK classes. // The main difference is the fact that the new class file reading implementation doesn't load parameter names from JDK classes.
configuration.put(JVMConfigurationKeys.USE_PSI_CLASS_FILES_READING, true) configuration.put(JVMConfigurationKeys.USE_PSI_CLASS_FILES_READING, usePsiClassFilesReading)
updateConfiguration(configuration) updateConfiguration(configuration)
return createForTests(testRootDisposable, configuration, getEnvironmentConfigFiles()) return createForTests(testRootDisposable, configuration, getEnvironmentConfigFiles())
@@ -81,9 +84,11 @@ abstract class KotlinMultiFileTestWithJava<M : KotlinBaseTest.TestModule, F : Ko
setupEnvironment(environment) setupEnvironment(environment)
} }
private fun getClasspath(file: File): List<File> { private fun getClasspath(file: File, excludeNonTypeUseJetbrainsAnnotations: Boolean): List<File> {
val result: MutableList<File> = ArrayList() val result: MutableList<File> = ArrayList()
result.add(KtTestUtil.getAnnotationsJar()) if (!excludeNonTypeUseJetbrainsAnnotations) {
result.add(KtTestUtil.getAnnotationsJar())
}
result.addAll(getExtraClasspath()) result.addAll(getExtraClasspath())
val fileText = file.readText(Charsets.UTF_8) val fileText = file.readText(Charsets.UTF_8)
if (InTextDirectivesUtils.isDirectiveDefined(fileText, "ANDROID_ANNOTATIONS")) { if (InTextDirectivesUtils.isDirectiveDefined(fileText, "ANDROID_ANNOTATIONS")) {
@@ -129,7 +134,7 @@ abstract class KotlinMultiFileTestWithJava<M : KotlinBaseTest.TestModule, F : Ko
fileName: String, fileName: String,
text: String, text: String,
directives: Directives directives: Directives
): F? { ): F {
if (fileName.endsWith(".java")) { if (fileName.endsWith(".java")) {
writeSourceFile(fileName, text, javaFilesDir) writeSourceFile(fileName, text, javaFilesDir)
} }
@@ -16,10 +16,7 @@
package org.jetbrains.kotlin.generators.tests package org.jetbrains.kotlin.generators.tests
import org.jetbrains.kotlin.checkers.AbstractForeignJava8AnnotationsNoAnnotationInClasspathTest import org.jetbrains.kotlin.checkers.*
import org.jetbrains.kotlin.checkers.AbstractForeignJava8AnnotationsNoAnnotationInClasspathWithPsiClassReadingTest
import org.jetbrains.kotlin.checkers.AbstractForeignJava8AnnotationsTest
import org.jetbrains.kotlin.checkers.AbstractJspecifyAnnotationsTest
import org.jetbrains.kotlin.checkers.javac.AbstractJavacForeignJava8AnnotationsTest import org.jetbrains.kotlin.checkers.javac.AbstractJavacForeignJava8AnnotationsTest
import org.jetbrains.kotlin.generators.impl.generateTestGroupSuite import org.jetbrains.kotlin.generators.impl.generateTestGroupSuite
import org.jetbrains.kotlin.jvm.compiler.AbstractLoadJava8Test import org.jetbrains.kotlin.jvm.compiler.AbstractLoadJava8Test
@@ -52,6 +49,10 @@ fun main(args: Array<String>) {
model("foreignAnnotationsJava8/tests/jspecify/kotlin") model("foreignAnnotationsJava8/tests/jspecify/kotlin")
} }
testClass<AbstractForeignAnnotationsCompiledJavaDiagnosticTest> {
model("foreignAnnotationsJava8/tests/typeEnhancementOnCompiledJava")
}
testClass<AbstractLoadJava8Test> { testClass<AbstractLoadJava8Test> {
model("loadJava8/compiledJava", extension = "java", testMethod = "doTestCompiledJava") model("loadJava8/compiledJava", extension = "java", testMethod = "doTestCompiledJava")
model("loadJava8/sourceJava", extension = "java", testMethod = "doTestSourceJava") model("loadJava8/sourceJava", extension = "java", testMethod = "doTestSourceJava")