[Analysis API] support Java compilation in tests

Previously we just skipped Java sources.
The order of classes in light classes test data is changed due to
differences in implementations of `compileLibraryToJar` and `runJvmCompiler`

^KT-62892
This commit is contained in:
Dmitrii Gridin
2024-01-03 14:23:48 +01:00
committed by Space Team
parent a9f85d75f4
commit 6c7d1babf0
14 changed files with 448 additions and 322 deletions
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.cliArgument
import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.platform.isJs
import org.jetbrains.kotlin.platform.jvm.isJvm
@@ -16,6 +17,7 @@ import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirective
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
import org.jetbrains.kotlin.test.services.sourceFileProvider
import org.jetbrains.kotlin.test.services.standardLibrariesPathProvider
import org.jetbrains.kotlin.test.util.KtTestUtil
@@ -39,6 +41,7 @@ abstract class CliTestModuleCompiler : TestModuleCompiler() {
buildCompilerOptions(module, testServices),
compilationErrorExpected = Directives.COMPILATION_ERRORS in module.directives,
libraryName = module.name,
extraClasspath = buildExtraClasspath(module, testServices),
)
override fun compileTestModuleToLibrarySources(module: TestModule, testServices: TestServices): Path {
@@ -55,6 +58,12 @@ abstract class CliTestModuleCompiler : TestModuleCompiler() {
return librarySourcesPath
}
private fun buildExtraClasspath(module: TestModule, testServices: TestServices): List<String> = buildList {
addAll(buildPlatformExtraClasspath(module, testServices))
}
protected open fun buildPlatformExtraClasspath(module: TestModule, testServices: TestServices): List<String> = emptyList()
private fun buildCompilerOptions(module: TestModule, testServices: TestServices): List<String> = buildList {
addAll(buildCommonCompilerOptions(module))
addAll(buildPlatformCompilerOptions(module, testServices))
@@ -101,6 +110,13 @@ class JvmJarTestModuleCompiler : CliTestModuleCompiler() {
addAll(listOf(K2JVMCompilerArguments::jdkHome.cliArgument, jdkHome.toString()))
}
}
override fun buildPlatformExtraClasspath(module: TestModule, testServices: TestServices): List<String> = buildList {
val compilerConfiguration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module)
for (file in compilerConfiguration.jvmClasspathRoots) {
add(file.absolutePath)
}
}
}
class JsKlibTestModuleCompiler : CliTestModuleCompiler() {
@@ -7,10 +7,10 @@ package org.jetbrains.kotlin.analysis.test.framework.services.libraries
import org.jetbrains.kotlin.analysis.test.framework.utils.SkipTestException
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.cliArgument
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.test.MockLibraryUtil
import org.jetbrains.kotlin.test.services.JUnit5Assertions
import java.nio.file.Path
import kotlin.io.path.*
@@ -21,9 +21,10 @@ internal object CompilerExecutor {
options: List<String>,
compilationErrorExpected: Boolean,
libraryName: String,
extraClasspath: List<String>,
): Path {
val library = try {
compile(compilerKind, sourcesPath, options, libraryName)
compile(compilerKind, sourcesPath, options, libraryName, extraClasspath)
} catch (e: Throwable) {
if (!compilationErrorExpected) {
throw IllegalStateException("Unexpected compilation error while compiling library", e)
@@ -40,7 +41,13 @@ internal object CompilerExecutor {
return library
}
private fun compile(compilerKind: CompilerKind, sourcesPath: Path, options: List<String>, libraryName: String): Path {
private fun compile(
compilerKind: CompilerKind,
sourcesPath: Path,
options: List<String>,
libraryName: String,
extraClasspath: List<String>,
): Path {
val sourceFiles = sourcesPath.toFile().walkBottomUp()
val library = when (compilerKind) {
CompilerKind.JVM -> sourcesPath / "$libraryName.jar"
@@ -49,13 +56,20 @@ internal object CompilerExecutor {
when (compilerKind) {
CompilerKind.JVM -> {
val commands = buildList {
sourceFiles.mapTo(this) { it.absolutePath }
val extraOptions = buildList {
addAll(options)
add(K2JVMCompilerArguments::destination.cliArgument); add(library.absolutePathString())
add("-XXLanguage:-${LanguageFeature.SkipStandaloneScriptsInSourceRoots.name}")
}
MockLibraryUtil.runJvmCompiler(commands)
MockLibraryUtil.compileLibraryToJar(
sourcesPath = sourcesPath.absolutePathString(),
contentDir = sourcesPath.toFile(),
jarName = libraryName,
extraOptions = extraOptions,
assertions = JUnit5Assertions,
useJava11 = true,
extraClasspath = extraClasspath,
)
}
CompilerKind.JS -> {
val commands = buildList {
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2024 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.
*/
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.sourceFileProvider
import org.jetbrains.kotlin.test.util.KtTestUtil
import java.nio.file.Path
import kotlin.io.path.createDirectories
import kotlin.io.path.createFile
import kotlin.io.path.div
import kotlin.io.path.writeText
@@ -21,7 +22,10 @@ abstract class TestModuleCompiler : TestService {
val tmpDir = KtTestUtil.tmpDir("testSourcesToCompile").toPath()
for (testFile in module.files) {
val text = testServices.sourceFileProvider.getContentOfSourceFile(testFile)
val tmpSourceFile = (tmpDir / testFile.name).createFile()
val filePath = tmpDir / testFile.relativePath
filePath.parent.createDirectories()
val tmpSourceFile = filePath.createFile()
tmpSourceFile.writeText(text)
}
return compile(tmpDir, module, testServices)