Support java 9 modules in the diagnostic tests both in sources and binaries

This commit is contained in:
Victor Petukhov
2021-04-06 16:25:16 +03:00
parent 1f0616439c
commit 71755b7a5e
9 changed files with 259 additions and 101 deletions
@@ -49,6 +49,9 @@ fun CompilerConfiguration.addJvmSdkRoots(files: List<File>) {
val CompilerConfiguration.jvmClasspathRoots: List<File>
get() = getList(CLIConfigurationKeys.CONTENT_ROOTS).filterIsInstance<JvmClasspathRoot>().map(JvmContentRoot::file)
val CompilerConfiguration.jvmModularRoots: List<File>
get() = getList(CLIConfigurationKeys.CONTENT_ROOTS).filterIsInstance<JvmModulePathRoot>().map(JvmContentRoot::file)
@JvmOverloads
fun CompilerConfiguration.addJavaSourceRoot(file: File, packagePrefix: String? = null) {
add(CLIConfigurationKeys.CONTENT_ROOTS, JavaSourceRoot(file, packagePrefix))
@@ -0,0 +1,10 @@
/*
* Copyright 2010-2021 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.test
enum class TestJavacVersion {
JAVAC_1_8, JAVAC_9
}
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.test.directives
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.test.TestJavacVersion
import org.jetbrains.kotlin.test.TestJdkKind
import org.jetbrains.kotlin.test.directives.model.DirectiveApplicability
import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer
@@ -33,6 +34,8 @@ object JvmEnvironmentConfigurationDirectives : SimpleDirectivesContainer() {
val WITH_FOREIGN_ANNOTATIONS by directive("Add foreign nullability annotations to classpath")
val ALLOW_KOTLIN_PACKAGE by directive("Don't require stdlib as a java 9 module")
val WITH_JSR305_TEST_ANNOTATIONS by directive(
description = """
Add test nullability annotations based on JSR-305 annotations
@@ -47,6 +50,14 @@ object JvmEnvironmentConfigurationDirectives : SimpleDirectivesContainer() {
"Compile this java file into jar and add it to classpath instead of compiling Kotlin with Java sources",
applicability = DirectiveApplicability.File
)
val ALL_JAVA_AS_BINARY by directive(
"Compile all java files into jar and add it to classpath instead of compiling Kotlin with Java sources",
applicability = DirectiveApplicability.Global
)
val COMPILE_JAVA_USING by enumDirective<TestJavacVersion>(
"Compile all including java files using javac of specific version",
applicability = DirectiveApplicability.Global
)
val JSPECIFY_MUTE by directive(
"Skip jspecify checks for compliance Kotlin diagnostics to jspecify marks",
@@ -5,22 +5,20 @@
package org.jetbrains.kotlin.test.runners
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.TestJavacVersion
import org.jetbrains.kotlin.test.TestJdkKind
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives.REPORT_JVM_DIAGNOSTICS_ON_FRONTEND
import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives.SKIP_TXT
import org.jetbrains.kotlin.test.directives.ForeignAnnotationsDirectives.ANNOTATIONS_PATH
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.COMPILE_JAVA_USING
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.JDK_KIND
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.JVM_TARGET
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.SKIP_JAVA_SOURCES
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.STDLIB_JDK8
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.USE_PSI_CLASS_FILES_READING
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.WITH_FOREIGN_ANNOTATIONS
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.WITH_JSR305_TEST_ANNOTATIONS
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.WITH_STDLIB
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade
import org.jetbrains.kotlin.test.frontend.classic.handlers.ClassicDiagnosticsHandler
import org.jetbrains.kotlin.test.frontend.classic.handlers.DeclarationsDumpHandler
@@ -34,7 +32,7 @@ import org.jetbrains.kotlin.test.services.sourceProviders.AdditionalDiagnosticsS
import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider
abstract class AbstractForeignAnnotationsTestBase : AbstractKotlinCompilerTest() {
protected abstract val foreignAnnotationsConfigurator: Constructor<JvmForeignAnnotationsConfigurator>
protected open val foreignAnnotationsConfigurator: Constructor<JvmForeignAnnotationsConfigurator>? = null
override fun TestConfigurationBuilder.configuration() {
globalDefaults {
@@ -46,17 +44,17 @@ abstract class AbstractForeignAnnotationsTestBase : AbstractKotlinCompilerTest()
defaultDirectives {
+REPORT_JVM_DIAGNOSTICS_ON_FRONTEND
+WITH_FOREIGN_ANNOTATIONS
+WITH_JSR305_TEST_ANNOTATIONS
}
enableMetaInfoHandler()
useConfigurators(
::CommonEnvironmentConfigurator,
::JvmEnvironmentConfigurator,
foreignAnnotationsConfigurator
::JvmEnvironmentConfigurator
)
foreignAnnotationsConfigurator.takeIf { it != null }?.also { useConfigurators(it) }
useMetaInfoProcessors(::OldNewInferenceMetaInfoProcessor)
useAdditionalSourceProviders(
::AdditionalDiagnosticsSourceFilesProvider,
@@ -72,6 +70,7 @@ abstract class AbstractForeignAnnotationsTestBase : AbstractKotlinCompilerTest()
forTestsMatching("compiler/testData/diagnostics/foreignAnnotationsTests/tests/*") {
defaultDirectives {
ANNOTATIONS_PATH with JavaForeignAnnotationType.Annotations
+WITH_JSR305_TEST_ANNOTATIONS
}
}
@@ -81,6 +80,14 @@ abstract class AbstractForeignAnnotationsTestBase : AbstractKotlinCompilerTest()
}
}
forTestsMatching("compiler/testData/diagnostics/foreignAnnotationsTests/java9Tests/*") {
defaultDirectives {
ANNOTATIONS_PATH with JavaForeignAnnotationType.Java9Annotations
JDK_KIND with TestJdkKind.FULL_JDK_9
COMPILE_JAVA_USING with TestJavacVersion.JAVAC_9
}
}
forTestsMatching("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/*") {
useSourcePreprocessor(::JspecifyTestsPreprocessor, needToPrepend = true)
}
@@ -93,9 +100,6 @@ abstract class AbstractForeignAnnotationsTest : AbstractForeignAnnotationsTestBa
}
abstract class AbstractForeignAnnotationsNoAnnotationInClasspathTest : AbstractForeignAnnotationsTestBase() {
override val foreignAnnotationsConfigurator: Constructor<JvmForeignAnnotationsConfigurator>
get() = ::JvmForeignAnnotationsAgainstCompiledJavaConfigurator
override fun configure(builder: TestConfigurationBuilder) {
super.configure(builder)
with(builder) {
@@ -6,19 +6,24 @@
package org.jetbrains.kotlin.test.services.configuration
import com.intellij.openapi.util.SystemInfo
import org.jetbrains.kotlin.cli.jvm.config.addJavaSourceRoot
import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoot
import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoots
import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
import com.intellij.psi.PsiJavaModule.MODULE_INFO_FILE
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.cli.jvm.addModularRootIfNotNull
import org.jetbrains.kotlin.cli.jvm.config.*
import org.jetbrains.kotlin.cli.jvm.configureStandardLibs
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.test.ConfigurationKind
import org.jetbrains.kotlin.test.MockLibraryUtil
import org.jetbrains.kotlin.test.MockLibraryUtil.compileJavaFilesLibraryToJar
import org.jetbrains.kotlin.test.TestJavacVersion
import org.jetbrains.kotlin.test.TestJdkKind
import org.jetbrains.kotlin.test.directives.ForeignAnnotationsDirectives
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.ASSERTIONS_MODE
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.COMPILE_JAVA_USING
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.CONSTRUCTOR_CALL_NORMALIZATION_MODE
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.INCLUDE_JAVA_AS_BINARY
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.JVM_TARGET
@@ -37,15 +42,16 @@ import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives
import org.jetbrains.kotlin.test.model.DependencyDescription
import org.jetbrains.kotlin.test.model.DependencyKind
import org.jetbrains.kotlin.test.model.TestFile
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.*
import org.jetbrains.kotlin.test.services.configuration.JdkForeignAnnotationType.Companion.FOREIGN_ANNOTATIONS_SOURCES_PATH
import org.jetbrains.kotlin.test.services.configuration.JdkForeignAnnotationType.Companion.FOREIGN_JDK8_ANNOTATIONS_SOURCES_PATH
import org.jetbrains.kotlin.test.services.configuration.JdkForeignAnnotationType.Companion.JSR_305_TEST_ANNOTATIONS_PATH
import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertTrue
import org.jetbrains.kotlin.test.services.configuration.JvmForeignAnnotationsConfigurator.Companion.JSR_305_TEST_ANNOTATIONS_PATH
import org.jetbrains.kotlin.test.services.jvm.CompiledClassesManager
import org.jetbrains.kotlin.test.services.jvm.compiledClassesManager
import org.jetbrains.kotlin.test.util.KtTestUtil
import org.jetbrains.kotlin.test.util.joinToArrayString
import org.jetbrains.kotlin.utils.PathUtil
import org.jetbrains.kotlin.utils.addIfNotNull
import java.io.File
import kotlin.io.path.ExperimentalPathApi
@@ -56,6 +62,8 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig
val TEST_CONFIGURATION_KIND_KEY = CompilerConfigurationKey.create<ConfigurationKind>("ConfigurationKind")
private val DEFAULT_JVM_TARGET_FROM_PROPERTY: String? = System.getProperty("kotlin.test.default.jvm.target")
private const val JAVA_BINARIES_JAR_NAME = "java-binaries"
}
override val directivesContainers: List<DirectivesContainer>
@@ -81,6 +89,7 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig
register(JVM_TARGET, JVMConfigurationKeys.JVM_TARGET)
}
@OptIn(ExperimentalPathApi::class, ExperimentalStdlibApi::class)
override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule) {
if (module.targetPlatform !in JvmPlatforms.allJvmPlatforms) return
configureDefaultJvmTarget(configuration)
@@ -120,9 +129,20 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig
configuration.put(TEST_CONFIGURATION_KIND_KEY, it)
}
val javaVersionToCompile = registeredDirectives[COMPILE_JAVA_USING].singleOrNull()
val javaBinaryFiles = module.javaFiles.filter { INCLUDE_JAVA_AS_BINARY in it.directives }
val withForeignAnnotations = JvmEnvironmentConfigurationDirectives.WITH_FOREIGN_ANNOTATIONS in registeredDirectives
assertTrue(javaVersionToCompile == null || javaBinaryFiles.isNotEmpty() || withForeignAnnotations) {
"'COMPILE_JAVA_USING' can't be use if there aren't any java files to compile " +
"(mark java files by 'INCLUDE_JAVA_AS_BINARY' or include foreign annotations using 'WITH_FOREIGN_ANNOTATIONS' " +
"which will be compiled by specified version of javac)"
}
val useJava9ToCompileIncludedJavaFiles = javaVersionToCompile == TestJavacVersion.JAVAC_9
if (configurationKind.withRuntime) {
configuration.addJvmClasspathRoot(ForTestCompileRuntime.runtimeJarForTests())
configuration.addJvmClasspathRoot(ForTestCompileRuntime.scriptRuntimeJarForTests())
configuration.configureStandardLibs(PathUtil.kotlinPathsForDistDirectory, K2JVMCompilerArguments().also { it.noReflect = true })
configuration.addJvmClasspathRoot(ForTestCompileRuntime.kotlinTestJarForTests())
} else if (configurationKind.withMockRuntime) {
configuration.addJvmClasspathRoot(ForTestCompileRuntime.minimalRuntimeJarForTests())
@@ -131,63 +151,87 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig
if (configurationKind.withReflection) {
configuration.addJvmClasspathRoot(ForTestCompileRuntime.reflectJarForTests())
}
configuration.addJvmClasspathRoot(KtTestUtil.getAnnotationsJar())
if (JvmEnvironmentConfigurationDirectives.STDLIB_JDK8 in module.directives) {
configuration.addJvmClasspathRoot(ForTestCompileRuntime.runtimeJarForTestsWithJdk8())
}
if (JvmEnvironmentConfigurationDirectives.WITH_FOREIGN_ANNOTATIONS in registeredDirectives) {
if (withForeignAnnotations) {
val annotationPath = registeredDirectives[ForeignAnnotationsDirectives.ANNOTATIONS_PATH].singleOrNull()
?: JdkForeignAnnotationType.Jdk8Annotations
?: JavaForeignAnnotationType.Java8Annotations
val javaFilesDir = createTempDirectory().toFile().also {
File(annotationPath.path).copyRecursively(it)
}
val jar = compileJavaFilesLibraryToJar(
val foreignAnnotationsJar = compileJavaFilesLibraryToJar(
javaFilesDir.path,
"foreign-annotations",
assertions = JUnit5Assertions,
extraClasspath = configuration.jvmClasspathRoots.map { it.absolutePath }
extraClasspath = configuration.jvmClasspathRoots.map { it.absolutePath },
useJava9 = useJava9ToCompileIncludedJavaFiles
)
configuration.addJvmClasspathRoot(jar)
configuration.addModularRootIfNotNull(useJava9ToCompileIncludedJavaFiles, "java9_annotations", foreignAnnotationsJar)
configuration.addJvmClasspathRoot(ForTestCompileRuntime.jvmAnnotationsForTests())
} else {
// Add jetbrains annotations of an old version, without supporting type use target
configuration.addJvmClasspathRoot(KtTestUtil.getAnnotationsJar())
}
if (JvmEnvironmentConfigurationDirectives.WITH_JSR305_TEST_ANNOTATIONS in registeredDirectives) {
val javaFilesDir = createTempDirectory().toFile().also {
File(JSR_305_TEST_ANNOTATIONS_PATH).copyRecursively(it)
}
val jar = compileJavaFilesLibraryToJar(
javaFilesDir.path,
"jsr-305-test-annotations",
assertions = JUnit5Assertions,
extraClasspath = configuration.jvmClasspathRoots.map { it.absolutePath }
configuration.addJvmClasspathRoot(
compileJavaFilesLibraryToJar(
javaFilesDir.path,
"jsr-305-test-annotations",
assertions = JUnit5Assertions,
extraClasspath = configuration.jvmClasspathRoots.map { it.absolutePath }
)
)
configuration.addJvmClasspathRoot(jar)
configuration.addJvmClasspathRoot(KtTestUtil.getAnnotationsJar())
}
val isIr = module.targetBackend?.isIR == true
configuration.put(JVMConfigurationKeys.IR, isIr)
if (JvmEnvironmentConfigurationDirectives.SKIP_JAVA_SOURCES !in module.directives) {
val javaSourceFiles = module.javaFiles.filter { INCLUDE_JAVA_AS_BINARY !in it.directives }
javaSourceFiles.takeIf { it.isNotEmpty() }?.let { javaFiles ->
javaFiles.forEach { testServices.sourceFileProvider.getRealFileForSourceFile(it) }
val javaSourceFiles = module.javaFiles.filter { INCLUDE_JAVA_AS_BINARY !in it.directives }
if (javaSourceFiles.isNotEmpty() && JvmEnvironmentConfigurationDirectives.SKIP_JAVA_SOURCES !in module.directives && ALL_JAVA_AS_BINARY !in registeredDirectives) {
javaSourceFiles.forEach { testServices.sourceFileProvider.getRealFileForSourceFile(it) }
// TODO: temporary hack to provide java 9 modules in the source mode properly (see comment on ClasspathRootsResolved::addModularRoots)
addJavaCompiledModulesFromDependentKotlinModules(configuration, configurationKind, module, bySources = true)
val moduleInfoFiles = javaSourceFiles.filter { it.name == MODULE_INFO_FILE }
if (moduleInfoFiles.isNotEmpty()) {
addJavaSourceRootsByJavaModules(configuration, moduleInfoFiles)
} else {
configuration.addJavaSourceRoot(testServices.sourceFileProvider.javaSourceDirectory)
}
}
val javaBinaryFiles = module.javaFiles.filter { INCLUDE_JAVA_AS_BINARY in it.directives }
if (javaBinaryFiles.isNotEmpty()) {
javaBinaryFiles.forEach { testServices.sourceFileProvider.getRealFileForBinaryFile(it) }
javaBinaryFiles.takeIf { it.isNotEmpty() }?.let { javaFiles ->
javaFiles.forEach { testServices.sourceFileProvider.getRealFileForBinaryFile(it) }
val jar = compileJavaFilesLibraryToJar(
testServices.sourceFileProvider.javaBinaryDirectory.path,
"java-binaries",
extraClasspath = configuration.jvmClasspathRoots.map { it.absolutePath },
assertions = JUnit5Assertions
)
configuration.addJvmClasspathRoot(jar)
addJavaCompiledModulesFromDependentKotlinModules(configuration, configurationKind, module, bySources = false)
val moduleInfoFiles = javaBinaryFiles.filter { it.name == MODULE_INFO_FILE }
// TODO: Use module graph to build proper modulepath for each module according cross-module dependencies
if (moduleInfoFiles.isNotEmpty()) {
addJavaBinaryRootsByJavaModules(configuration, configurationKind, moduleInfoFiles)
} else {
configuration.addJvmClasspathRoot(
compileJavaFilesLibraryToJar(
testServices.sourceFileProvider.javaBinaryDirectory.path,
JAVA_BINARIES_JAR_NAME,
extraClasspath = configuration.jvmClasspathRoots.map { it.absolutePath },
assertions = JUnit5Assertions,
useJava9 = useJava9ToCompileIncludedJavaFiles
)
)
}
}
configuration.registerModuleDependencies(module)
@@ -196,9 +240,94 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig
configuration.put(JVMConfigurationKeys.USE_PSI_CLASS_FILES_READING, true)
}
if (JvmEnvironmentConfigurationDirectives.ALLOW_KOTLIN_PACKAGE in module.directives) {
configuration.put(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE, true)
}
initBinaryDependencies(module, configuration)
}
private fun addJavaSourceRootsByJavaModules(configuration: CompilerConfiguration, moduleInfoFiles: List<TestFile>) {
val javaSourceDirectory = testServices.sourceFileProvider.javaSourceDirectory
for (moduleInfoFile in moduleInfoFiles) {
val moduleName = moduleInfoFile.relativePath.substringBefore('/')
val moduleDir = File("${javaSourceDirectory.path}/$moduleName").also { it.mkdir() }
configuration.addJavaSourceRoot(moduleDir)
}
}
private fun addJavaBinaryRootsByJavaModules(
configuration: CompilerConfiguration,
configurationKind: ConfigurationKind,
moduleInfoFiles: List<TestFile>
) {
val javaBinaryDirectory = testServices.sourceFileProvider.javaBinaryDirectory
for (moduleInfoFile in moduleInfoFiles) {
val moduleName = moduleInfoFile.relativePath.substringBefore('/')
addJavaCompiledModule(configuration, configurationKind, moduleName, bySources = true, targetDir = javaBinaryDirectory)
}
}
private fun addJavaCompiledModulesFromDependentKotlinModules(
configuration: CompilerConfiguration,
configurationKind: ConfigurationKind,
module: TestModule,
bySources: Boolean
) {
val moduleDependencies = module.dependencies.map { testServices.dependencyProvider.getTestModule(it.moduleName) }
val filterJavaModuleInfoFiles = { testFile: TestFile ->
val binaryFilesFilter = INCLUDE_JAVA_AS_BINARY in testFile.directives || ALL_JAVA_AS_BINARY in module.directives
val includeOrExcludeBinaryFilesFilter = (bySources && !binaryFilesFilter) || (!bySources && binaryFilesFilter)
includeOrExcludeBinaryFilesFilter && testFile.name == MODULE_INFO_FILE
}
val moduleInfoFilesFromDependencies = moduleDependencies.mapNotNull { it.javaFiles.singleOrNull(filterJavaModuleInfoFiles) }
for (dependentModuleInfoFile in moduleInfoFilesFromDependencies) {
val moduleName = dependentModuleInfoFile.relativePath.substringBefore('/')
addJavaCompiledModule(configuration, configurationKind, moduleName, bySources)
}
}
private fun addJavaCompiledModule(
configuration: CompilerConfiguration,
configurationKind: ConfigurationKind,
moduleName: String,
bySources: Boolean,
targetDir: File = testServices.sourceFileProvider.run { if (bySources) javaSourceDirectory else javaBinaryDirectory }
) {
val moduleDir = File("${targetDir.path}/$moduleName")
val javaBinaries = if (bySources) {
compileJavaFilesToModularJar(configuration, configurationKind, moduleDir)
} else {
File("${moduleDir.path}/$JAVA_BINARIES_JAR_NAME.jar")
}
configuration.addModularRootIfNotNull(isModularJava = true, moduleName, javaBinaries)
}
@OptIn(ExperimentalStdlibApi::class)
private fun compileJavaFilesToModularJar(
configuration: CompilerConfiguration,
configurationKind: ConfigurationKind,
sourcesDir: File
): File {
val modulePath = buildList {
addAll(configuration.jvmModularRoots.map { it.absolutePath })
if (configurationKind.withRuntime) {
add(ForTestCompileRuntime.runtimeJarForTests().path)
}
}
return MockLibraryUtil.compileLibraryToJar(
sourcesDir.path,
sourcesDir,
JAVA_BINARIES_JAR_NAME,
extraClasspath = configuration.jvmClasspathRoots.map { it.absolutePath },
extraModulepath = modulePath,
assertions = JUnit5Assertions,
useJava9 = true
)
}
private fun configureDefaultJvmTarget(configuration: CompilerConfiguration) {
if (DEFAULT_JVM_TARGET_FROM_PROPERTY == null) return
val customDefaultTarget = JvmTarget.fromString(DEFAULT_JVM_TARGET_FROM_PROPERTY)
@@ -15,22 +15,19 @@ import org.jetbrains.kotlin.test.directives.ForeignAnnotationsDirectives.JSR305_
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives
import org.jetbrains.kotlin.test.directives.model.singleOrZeroValue
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.*
import org.jetbrains.kotlin.utils.JavaTypeEnhancementState
import org.jetbrains.kotlin.utils.ReportLevel
import java.io.File
enum class JavaForeignAnnotationType(val path: String) {
Annotations("third-party/annotations"),
Java8Annotations("third-party/java8-annotations");
Java8Annotations("third-party/java8-annotations"),
Java9Annotations("third-party/java9-annotations");
}
open class JvmForeignAnnotationsConfigurator(testServices: TestServices) : EnvironmentConfigurator(testServices) {
companion object {
val FOREIGN_ANNOTATIONS_SOURCES_PATH = Annotations.path
val FOREIGN_JDK8_ANNOTATIONS_SOURCES_PATH = Jdk8Annotations.path
val JSR_305_TEST_ANNOTATIONS_PATH = "compiler/testData/diagnostics/helpers/jsr305_test_annotations"
const val JSR_305_TEST_ANNOTATIONS_PATH = "compiler/testData/diagnostics/helpers/jsr305_test_annotations"
}
override val directivesContainers: List<DirectivesContainer>
@@ -55,33 +52,3 @@ open class JvmForeignAnnotationsConfigurator(testServices: TestServices) : Envir
)
}
}
class JvmForeignAnnotationsAgainstCompiledJavaConfigurator(testServices: TestServices) : JvmForeignAnnotationsConfigurator(testServices) {
@OptIn(ExperimentalStdlibApi::class)
override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule) {
val compiledJavaPath = testServices.createTempDirectory("java-compiled-files")
val foreignAnnotations = createJarWithForeignAnnotations(module)
val testAnnotations = compileTestAnnotations(foreignAnnotations)
val additionalClasspath = buildList {
addAll(foreignAnnotations)
addAll(testAnnotations)
}.map { it.path }
module.javaFiles.forEach { testServices.sourceFileProvider.getRealFileForSourceFile(it) }
CodegenTestUtil.compileJava(
CodegenTestUtil.findJavaSourcesInDirectory(testServices.sourceFileProvider.javaSourceDirectory),
additionalClasspath,
emptyList(),
compiledJavaPath,
JUnit5Assertions
)
val extraClassPath = buildList {
add(compiledJavaPath)
addAll(testAnnotations)
}
configuration.addJvmClasspathRoots(extraClassPath)
}
}
@@ -18,7 +18,15 @@ object MockLibraryUtilExt {
extraOptions: List<String> = emptyList(),
extraClasspath: List<String> = emptyList(),
): File {
return MockLibraryUtil.compileJavaFilesLibraryToJar(sourcesPath, jarName, addSources, extraOptions, extraClasspath, JUnit4Assertions)
return MockLibraryUtil.compileJavaFilesLibraryToJar(
sourcesPath,
jarName,
addSources,
extraOptions,
extraClasspath,
extraModulepath = listOf(),
JUnit4Assertions
)
}
@JvmStatic
@@ -39,6 +47,7 @@ object MockLibraryUtilExt {
allowKotlinSources,
extraOptions,
extraClasspath,
extraModulepath = listOf(),
useJava9,
JUnit4Assertions
)
@@ -64,6 +73,7 @@ object MockLibraryUtilExt {
allowKotlinSources,
extraOptions,
extraClasspath,
extraModulepath = listOf(),
useJava9,
JUnit4Assertions
)
@@ -9,15 +9,15 @@ package org.jetbrains.kotlin.test
import org.jetbrains.kotlin.test.util.KtTestUtil
import org.jetbrains.kotlin.utils.rethrow
import java.io.File
import java.io.IOException
import java.io.StringWriter
import java.io.*
import java.nio.charset.Charset
import java.util.*
import javax.tools.Diagnostic
import javax.tools.DiagnosticCollector
import javax.tools.JavaFileObject
import javax.tools.ToolProvider
import java.util.stream.Collectors
@JvmOverloads
@Throws(IOException::class)
@@ -66,13 +66,19 @@ fun compileJavaFilesExternally(files: Collection<File>, options: List<String?>,
for (file in files) {
command.add(file.path)
}
return try {
val process = ProcessBuilder().command(command).inheritIO().start()
process.waitFor()
process.exitValue() == 0
} catch (e: Exception) {
throw rethrow(e)
val process = ProcessBuilder().command(command).start()
val errorsReader = BufferedReader(InputStreamReader(process.errorStream))
val errors = errorsReader.lines().collect(Collectors.joining(System.lineSeparator()))
process.waitFor()
val isSuccess = process.exitValue() == 0
if (!isSuccess) {
System.err.println(errors)
}
return isSuccess
}
private fun errorsToString(diagnosticCollector: DiagnosticCollector<JavaFileObject>, humanReadable: Boolean): String {
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
import org.jetbrains.kotlin.preloading.ClassPreloadingUtils
import org.jetbrains.kotlin.preloading.Preloader
import org.jetbrains.kotlin.test.KtAssert.assertTrue
import org.jetbrains.kotlin.test.util.KtTestUtil
import org.jetbrains.kotlin.utils.PathUtil
import java.io.ByteArrayOutputStream
@@ -36,6 +37,7 @@ object MockLibraryUtil {
allowKotlinSources: Boolean = true,
extraOptions: List<String> = emptyList(),
extraClasspath: List<String> = emptyList(),
extraModulepath: List<String> = emptyList(),
useJava9: Boolean = false,
assertions: Assertions
): File {
@@ -47,6 +49,7 @@ object MockLibraryUtil {
allowKotlinSources,
extraOptions,
extraClasspath,
extraModulepath,
useJava9,
assertions
)
@@ -59,16 +62,22 @@ object MockLibraryUtil {
addSources: Boolean = false,
extraOptions: List<String> = emptyList(),
extraClasspath: List<String> = emptyList(),
assertions: Assertions
extraModulepath: List<String> = emptyList(),
assertions: Assertions,
useJava9: Boolean = false
): File {
return compileJvmLibraryToJar(
sourcesPath, jarName, addSources,
allowKotlinSources = false,
extraClasspath = extraClasspath, extraOptions = extraOptions,
assertions = assertions
extraOptions,
extraClasspath,
extraModulepath,
useJava9,
assertions
)
}
@OptIn(ExperimentalStdlibApi::class)
@JvmStatic
fun compileLibraryToJar(
sourcesPath: String,
@@ -78,15 +87,18 @@ object MockLibraryUtil {
allowKotlinSources: Boolean = true,
extraOptions: List<String> = emptyList(),
extraClasspath: List<String> = emptyList(),
extraModulepath: List<String> = emptyList(),
useJava9: Boolean = false,
assertions: Assertions
): File {
assertTrue("Module path can be used only for compilation using javac 9 and higher", useJava9 || extraModulepath.isEmpty())
val classesDir = File(contentDir, "classes")
val srcFile = File(sourcesPath)
val kotlinFiles = FileUtil.findFilesByMask(Pattern.compile(".*\\.kt"), srcFile)
if (srcFile.isFile || kotlinFiles.isNotEmpty()) {
KtAssert.assertTrue("Only java files are expected", allowKotlinSources)
assertTrue("Only java files are expected", allowKotlinSources)
compileKotlin(sourcesPath, classesDir, extraOptions, *extraClasspath.toTypedArray())
}
@@ -94,7 +106,6 @@ object MockLibraryUtil {
if (javaFiles.isNotEmpty()) {
val classpath = mutableListOf<String>()
classpath += ForTestCompileRuntime.runtimeJarForTests().path
classpath += KtTestUtil.getAnnotationsJar().path
classpath += extraClasspath
// Probably no kotlin files were present, so dir might not have been created after kotlin compiler
@@ -104,10 +115,17 @@ object MockLibraryUtil {
FileUtil.createDirectory(classesDir)
}
val options = listOf(
"-classpath", classpath.joinToString(File.pathSeparator),
"-d", classesDir.path
)
val options = buildList {
add("-classpath")
add(classpath.joinToString(File.pathSeparator))
add("-d")
add(classesDir.path)
if (useJava9) {
add("--module-path")
add(extraModulepath.joinToString(File.pathSeparator))
}
}
val compile =
if (useJava9) ::compileJavaFilesExternallyWithJava9