Tests: do not add transitive dependencies in multi-module tests

Prefer to have all module dependencies, including dependencies on
stdlib/reflect, declared explicitly. This allows to have tests on
situations like the one in KT-45308: three modules A<-B<-C, where C
doesn't depend on A, which was compiling correctly with the old JVM
backend before 1.5, but started to fail with JVM IR in 1.5.

Also simplify the code a bit, remove duplicated logic.
This commit is contained in:
Alexander Udalov
2021-05-19 21:50:57 +02:00
parent eac3f507b6
commit 8dee36d420
6 changed files with 25 additions and 59 deletions
@@ -29,6 +29,7 @@ fun builder(c: suspend Controller.() -> Unit) {
}
// MODULE: main(lib)
// WITH_RUNTIME
// FILE: B.kt
import a.builder
@@ -83,6 +83,7 @@ interface IrElementVisitor<out R, in D>
interface IrElementTransformer<in D> : IrElementVisitor<IrElement, D>
// MODULE: main(lib)
// WITH_RUNTIME
// FILE: B.kt
fun foo(cases: Collection<IrConst<*>>, exprTransformer: IrElementTransformer<Any>, context: Any) {
@@ -94,6 +95,3 @@ fun foo(cases: Collection<IrConst<*>>, exprTransformer: IrElementTransformer<Any
fun box(): String {
return "OK"
}
@@ -11,6 +11,7 @@ class FqName(val s: String)
val VOLATILE_ANNOTATION_FQ_NAME = FqName("volatile")
// MODULE: main(lib)
// WITH_RUNTIME
// FILE: B.kt
import first.second.VOLATILE_ANNOTATION_FQ_NAME
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS
// MODULE: lib1
// FILE: lib1.kt
@@ -13,14 +12,12 @@ inline class IC<TT>(val c: C<TT>) {
fun foo(): Int = c.hashCode()
}
// MODULE: main(lib2)
// MODULE: main(lib1, lib2)
// FILE: main.kt
fun box(): String {
val ic = IC<Int>(C(42))
if (ic.foo() != 42) return "FAIL"
return "OK"
}
}
+4
View File
@@ -1,3 +1,7 @@
// KT-45308 Psi2ir: "AssertionError: TypeAliasDescriptor expected" caused by using typealias from one module as a type in another module without a transitive dependency
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND_FIR: JVM_IR
// MODULE: a
// FILE: a.kt
package a
@@ -13,7 +13,10 @@ 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.config.CompilerConfiguration
import org.jetbrains.kotlin.config.CompilerConfigurationKey
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.test.ConfigurationKind
import org.jetbrains.kotlin.test.MockLibraryUtil
@@ -50,7 +53,6 @@ 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
@@ -244,8 +246,6 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig
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>) {
@@ -347,55 +347,20 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig
}
}
private fun CompilerConfiguration.registerModuleDependencies(module: TestModule) {
val dependencyProvider = testServices.dependencyProvider
val modulesFromDependencies = module.allDependencies
.filter { it.kind == DependencyKind.Binary }
.map { dependencyProvider.getTestModule(it.moduleName) }
.takeIf { it.isNotEmpty() }
?: return
val jarManager = testServices.compiledClassesManager
val dependenciesClassPath = modulesFromDependencies.map { jarManager.getCompiledKotlinDirForModule(it) }
addJvmClasspathRoots(dependenciesClassPath)
addJvmClasspathRoots(module.allDependencies.filter { it.kind == DependencyKind.Binary }.toFileList())
val binaryFriends = module.friendDependencies.filter { it.kind == DependencyKind.Binary }
if (binaryFriends.isNotEmpty()) {
put(JVMConfigurationKeys.FRIEND_PATHS, binaryFriends.toFileList().map { it.absolutePath })
}
}
@OptIn(ExperimentalStdlibApi::class)
private fun initBinaryDependencies(
module: TestModule,
configuration: CompilerConfiguration,
) {
val binaryDependencies = module.allDependencies.filter { it.kind == DependencyKind.Binary }
val binaryFriends = module.friendDependencies.filter { it.kind == DependencyKind.Binary }
val dependencyProvider = testServices.dependencyProvider
val compiledClassesManager = testServices.compiledClassesManager
val compilerConfigurationProvider = testServices.compilerConfigurationProvider
fun addDependenciesToClasspath(dependencies: List<DependencyDescription>): List<File> {
val jvmClasspathRoots = buildList<File> {
dependencies.forEach {
val dependencyModule = dependencyProvider.getTestModule(it.moduleName)
add(compiledClassesManager.getCompiledKotlinDirForModule(dependencyModule))
addIfNotNull(compiledClassesManager.getCompiledJavaDirForModule(dependencyModule))
addAll(compilerConfigurationProvider.getCompilerConfiguration(dependencyModule).jvmClasspathRoots)
}
}
configuration.addJvmClasspathRoots(jvmClasspathRoots)
return jvmClasspathRoots
}
addDependenciesToClasspath(binaryDependencies)
addDependenciesToClasspath(binaryFriends)
if (binaryFriends.isNotEmpty()) {
configuration.put(JVMConfigurationKeys.FRIEND_PATHS, binaryFriends.flatMap {
val friendModule = dependencyProvider.getTestModule(it.moduleName)
listOfNotNull(
compiledClassesManager.getCompiledKotlinDirForModule(friendModule),
compiledClassesManager.getCompiledJavaDirForModule(friendModule)
)
}.map { it.absolutePath })
}
private fun List<DependencyDescription>.toFileList(): List<File> = this.flatMap { dependency ->
val friendModule = testServices.dependencyProvider.getTestModule(dependency.moduleName)
listOfNotNull(
testServices.compiledClassesManager.getCompiledKotlinDirForModule(friendModule),
testServices.compiledClassesManager.getCompiledJavaDirForModule(friendModule)
)
}
}