diff --git a/analysis/analysis-api-impl-barebone/tests/org/jetbrains/kotlin/analysis/api/impl/barebone/test/AbstractFrontendApiTest.kt b/analysis/analysis-api-impl-barebone/tests/org/jetbrains/kotlin/analysis/api/impl/barebone/test/AbstractFrontendApiTest.kt index b861b89d376..6686948f038 100644 --- a/analysis/analysis-api-impl-barebone/tests/org/jetbrains/kotlin/analysis/api/impl/barebone/test/AbstractFrontendApiTest.kt +++ b/analysis/analysis-api-impl-barebone/tests/org/jetbrains/kotlin/analysis/api/impl/barebone/test/AbstractFrontendApiTest.kt @@ -153,6 +153,7 @@ abstract class AbstractFrontendApiTest : TestWithDisposable() { useAdditionalService { ExpressionMarkerProvider() } useAdditionalService(::TestKtModuleProvider) useAdditionalService { ExecutionListenerBasedDisposableProvider() } + useAdditionalService { StandardLibrariesPathProviderForKotlinProject } configureTest(this) startingArtifactFactory = { ResultingArtifact.Source() } diff --git a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/CodegenTestsOnAndroidGenerator.kt b/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/CodegenTestsOnAndroidGenerator.kt index 31fac8f1ff3..d0cb6f59201 100644 --- a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/CodegenTestsOnAndroidGenerator.kt +++ b/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/CodegenTestsOnAndroidGenerator.kt @@ -416,6 +416,7 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager assertions = JUnit5Assertions useAdditionalService(::TemporaryDirectoryManagerImpl) useAdditionalService { ExecutionListenerBasedDisposableProvider() } + useAdditionalService { StandardLibrariesPathProviderForKotlinProject } useSourcePreprocessor(*AbstractKotlinCompilerTest.defaultPreprocessors.toTypedArray()) useDirectives(*AbstractKotlinCompilerTest.defaultDirectiveContainers.toTypedArray()) class AndroidTransformingPreprocessor(testServices: TestServices) : SourceFilePreprocessor(testServices) { diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/JvmBoxRunner.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/JvmBoxRunner.kt index 1682f819f13..bb64135737c 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/JvmBoxRunner.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/JvmBoxRunner.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.test.backend.handlers import junit.framework.TestCase import org.jetbrains.kotlin.backend.common.CodegenUtil.getMemberDeclarationsToGenerate import org.jetbrains.kotlin.codegen.* -import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil.getFileClassInfoNoResolve import org.jetbrains.kotlin.psi.KtFile @@ -24,13 +23,10 @@ import org.jetbrains.kotlin.test.model.BinaryArtifacts import org.jetbrains.kotlin.test.model.DependencyKind import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.model.nameWithoutExtension -import org.jetbrains.kotlin.test.services.TestServices -import org.jetbrains.kotlin.test.services.compilerConfigurationProvider +import org.jetbrains.kotlin.test.services.* import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurator.Companion.TEST_CONFIGURATION_KIND_KEY -import org.jetbrains.kotlin.test.services.dependencyProvider import org.jetbrains.kotlin.test.services.jvm.compiledClassesManager import org.jetbrains.kotlin.test.services.jvm.jvmBoxMainClassProvider -import org.jetbrains.kotlin.test.services.runtimeClasspathProviders import org.jetbrains.kotlin.test.services.sourceProviders.MainFunctionForBlackBoxTestsSourceProvider import org.jetbrains.kotlin.test.services.sourceProviders.MainFunctionForBlackBoxTestsSourceProvider.Companion.fileContainsBoxMethod import org.jetbrains.kotlin.test.util.KtTestUtil @@ -297,9 +293,9 @@ open class JvmBoxRunner(testServices: TestServices) : JvmBinaryArtifactHandler(t private fun createClassLoader(module: TestModule, classFileFactory: ClassFileFactory): GeneratedClassLoader { val configuration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module) val parentClassLoader = if (configuration[TEST_CONFIGURATION_KIND_KEY]?.withReflection == true) { - ForTestCompileRuntime.runtimeAndReflectJarClassLoader() + testServices.standardLibrariesPathProvider.getRuntimeAndReflectJarClassLoader() } else { - ForTestCompileRuntime.runtimeJarClassLoader() + testServices.standardLibrariesPathProvider.getRuntimeJarClassLoader() } val classpath = computeRuntimeClasspath(module) return GeneratedClassLoader(classFileFactory, parentClassLoader, *classpath.map { it.toURI().toURL() }.toTypedArray()) diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/runners/AbstractKotlinCompilerTest.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/runners/AbstractKotlinCompilerTest.kt index 61811830d32..8905b5d9e65 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/runners/AbstractKotlinCompilerTest.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/runners/AbstractKotlinCompilerTest.kt @@ -43,6 +43,7 @@ abstract class AbstractKotlinCompilerTest { assertions = JUnit5Assertions useAdditionalService(::TemporaryDirectoryManagerImpl) useAdditionalService { ExecutionListenerBasedDisposableProvider() } + useAdditionalService { StandardLibrariesPathProviderForKotlinProject } useSourcePreprocessor(*defaultPreprocessors.toTypedArray()) useDirectives(*defaultDirectiveContainers.toTypedArray()) configureDebugFlags() diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/KotlinStandardLibrariesPathProvider.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/KotlinStandardLibrariesPathProvider.kt new file mode 100644 index 00000000000..55e2999b688 --- /dev/null +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/KotlinStandardLibrariesPathProvider.kt @@ -0,0 +1,127 @@ +/* + * Copyright 2010-2022 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.services + +import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime +import java.io.File +import java.lang.ref.SoftReference +import java.net.URL +import java.net.URLClassLoader + +abstract class KotlinStandardLibrariesPathProvider : TestService { + companion object { + @Volatile + private var runtimeJarClassLoader: SoftReference = SoftReference(null) + + @Volatile + private var reflectJarClassLoader: SoftReference = SoftReference(null) + + private fun createClassLoader(vararg files: File): ClassLoader { + val urls: MutableList = ArrayList(2) + for (file in files) { + urls.add(file.toURI().toURL()) + } + return URLClassLoader(urls.toTypedArray(), null) + } + } + + /** + * kotlin-stdlib.jar + */ + abstract fun runtimeJarForTests(): File + + /** + * kotlin-stdlib-jdk8.jar + */ + abstract fun runtimeJarForTestsWithJdk8(): File + + /** + * Jar with minimal version of kotlin stdlib (may be same as runtimeJarForTests) + */ + abstract fun minimalRuntimeJarForTests(): File + + /** + * kotlin-reflect.jar + */ + abstract fun reflectJarForTests(): File + + /** + * kotlin-test.jar + */ + abstract fun kotlinTestJarForTests(): File + + /** + * kotlin-script-runtime.jar + */ + abstract fun scriptRuntimeJarForTests(): File + + /** + * kotlin-annotations-jvm.jar + */ + abstract fun jvmAnnotationsForTests(): File + + fun getRuntimeJarClassLoader(): ClassLoader = synchronized(this) { + var loader = runtimeJarClassLoader.get() + if (loader == null) { + loader = createClassLoader( + runtimeJarForTests(), + scriptRuntimeJarForTests(), + kotlinTestJarForTests() + ) + runtimeJarClassLoader = SoftReference(loader) + } + loader + } + + fun getRuntimeAndReflectJarClassLoader(): ClassLoader = synchronized(this) { + var loader = reflectJarClassLoader.get() + if (loader == null) { + loader = createClassLoader( + runtimeJarForTests(), + reflectJarForTests(), + scriptRuntimeJarForTests(), + kotlinTestJarForTests()) + reflectJarClassLoader = SoftReference(loader) + } + loader + } +} + +object StandardLibrariesPathProviderForKotlinProject : KotlinStandardLibrariesPathProvider() { + override fun runtimeJarForTests(): File = ForTestCompileRuntime.runtimeJarForTests() + override fun runtimeJarForTestsWithJdk8(): File = ForTestCompileRuntime.runtimeJarForTestsWithJdk8() + override fun minimalRuntimeJarForTests(): File = ForTestCompileRuntime.minimalRuntimeJarForTests() + override fun reflectJarForTests(): File = ForTestCompileRuntime.reflectJarForTests() + override fun kotlinTestJarForTests(): File = ForTestCompileRuntime.kotlinTestJarForTests() + override fun scriptRuntimeJarForTests(): File = ForTestCompileRuntime.scriptRuntimeJarForTests() + override fun jvmAnnotationsForTests(): File = ForTestCompileRuntime.jvmAnnotationsForTests() +} + +object EnvironmentBasedStandardLibrariesPathProvider : KotlinStandardLibrariesPathProvider() { + const val KOTLIN_STDLIB_PROP = "org.jetbrains.kotlin.test.kotlin-stdlib" + const val KOTLIN_STDLIB_JDK8_PROP = "org.jetbrains.kotlin.test.kotlin-stdlib-jdk8" + const val KOTLIN_REFLECT_PROP = "org.jetbrains.kotlin.test.kotlin-reflect" + const val KOTLIN_TEST_PROP = "org.jetbrains.kotlin.test.kotlin-test" + const val KOTLIN_SCRIPT_RUNTIME_PROP = "org.jetbrains.kotlin.test.kotlin-script-runtime" + const val KOTLIN_ANNOTATIONS_JVM_PROP = "org.jetbrains.kotlin.test.kotlin-annotations-jvm" + + private fun getFile(propertyName: String): File { + return System.getProperty(propertyName) + ?.let(::File) + ?.takeIf { it.exists() } + ?: error("Property $propertyName is not set or file under it not found") + } + + override fun runtimeJarForTests(): File = getFile(KOTLIN_STDLIB_PROP) + override fun runtimeJarForTestsWithJdk8(): File = getFile(KOTLIN_STDLIB_JDK8_PROP) + override fun minimalRuntimeJarForTests(): File = getFile(KOTLIN_STDLIB_PROP) + override fun reflectJarForTests(): File = getFile(KOTLIN_REFLECT_PROP) + override fun kotlinTestJarForTests(): File = getFile(KOTLIN_TEST_PROP) + override fun scriptRuntimeJarForTests(): File = getFile(KOTLIN_SCRIPT_RUNTIME_PROP) + override fun jvmAnnotationsForTests(): File = getFile(KOTLIN_ANNOTATIONS_JVM_PROP) +} + +val TestServices.standardLibrariesPathProvider: KotlinStandardLibrariesPathProvider by TestServices.testServiceAccessor() diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt index b7394231a9d..e251ae29bcd 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt @@ -14,7 +14,6 @@ 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.CompilerConfiguration import org.jetbrains.kotlin.config.CompilerConfigurationKey import org.jetbrains.kotlin.config.JVMConfigurationKeys @@ -104,26 +103,6 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig else -> error("Too many jdk kinds passed: ${jdkKinds.joinToArrayString()}") } } - - fun getLibraryFilesExceptRealRuntime(configurationKind: ConfigurationKind, directives: RegisteredDirectives): List { - val files = mutableListOf() - if (configurationKind.withRuntime) { - files.add(ForTestCompileRuntime.kotlinTestJarForTests()) - } else if (configurationKind.withMockRuntime) { - files.add(ForTestCompileRuntime.minimalRuntimeJarForTests()) - files.add(ForTestCompileRuntime.scriptRuntimeJarForTests()) - } - if (configurationKind.withReflection) { - files.add(ForTestCompileRuntime.reflectJarForTests()) - } - files.add(KtTestUtil.getAnnotationsJar()) - - if (JvmEnvironmentConfigurationDirectives.STDLIB_JDK8 in directives) { - files.add(ForTestCompileRuntime.runtimeJarForTestsWithJdk8()) - } - files.add(KtTestUtil.getAnnotationsJar()) - return files - } } override val directiveContainers: List @@ -332,7 +311,7 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig val modulePath = buildList { addAll(configuration.jvmModularRoots.map { it.absolutePath }) if (configurationKind.withRuntime) { - add(ForTestCompileRuntime.runtimeJarForTests().path) + add(testServices.standardLibrariesPathProvider.runtimeJarForTests().path) } } return MockLibraryUtil.compileLibraryToJar( @@ -393,4 +372,26 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig testServices.compiledClassesManager.getCompiledJavaDirForModule(friendModule) ) } + + private fun getLibraryFilesExceptRealRuntime(configurationKind: ConfigurationKind, directives: RegisteredDirectives): List { + val provider = testServices.standardLibrariesPathProvider + val files = mutableListOf() + if (configurationKind.withRuntime) { + files.add(provider.kotlinTestJarForTests()) + } else if (configurationKind.withMockRuntime) { + files.add(provider.minimalRuntimeJarForTests()) + files.add(provider.scriptRuntimeJarForTests()) + } + if (configurationKind.withReflection) { + files.add(provider.reflectJarForTests()) + } + files.add(KtTestUtil.getAnnotationsJar()) + + if (JvmEnvironmentConfigurationDirectives.STDLIB_JDK8 in directives) { + files.add(provider.runtimeJarForTestsWithJdk8()) + } + files.add(KtTestUtil.getAnnotationsJar()) + return files + } + } diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmForeignAnnotationsConfigurator.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmForeignAnnotationsConfigurator.kt index 8c6eee6ce16..5f012354de0 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmForeignAnnotationsConfigurator.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmForeignAnnotationsConfigurator.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.test.services.configuration import org.jetbrains.kotlin.cli.jvm.addModularRootIfNotNull import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoot import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots -import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.load.java.* import org.jetbrains.kotlin.name.FqName @@ -27,6 +26,7 @@ import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.EnvironmentConfigurator import org.jetbrains.kotlin.test.services.JUnit5Assertions import org.jetbrains.kotlin.test.services.TestServices +import org.jetbrains.kotlin.test.services.standardLibrariesPathProvider import org.jetbrains.kotlin.test.util.KtTestUtil import java.io.File import kotlin.io.path.createTempDirectory @@ -92,7 +92,7 @@ open class JvmForeignAnnotationsConfigurator(testServices: TestServices) : Envir useJava11 = useJava11ToCompileIncludedJavaFiles ) configuration.addModularRootIfNotNull(useJava11ToCompileIncludedJavaFiles, "java9_annotations", foreignAnnotationsJar) - configuration.addJvmClasspathRoot(ForTestCompileRuntime.jvmAnnotationsForTests()) + configuration.addJvmClasspathRoot(testServices.standardLibrariesPathProvider.jvmAnnotationsForTests()) if (JvmEnvironmentConfigurationDirectives.WITH_JSR305_TEST_ANNOTATIONS in registeredDirectives) { val jsr305AnnotationsDir = createTempDirectory().toFile().also {