[LL FIR] KT-58325 Fix test library discoverability for combined Kotlin symbol providers

- An LL FIR test failed after merging stub-based deserialized symbol
  providers into combined Kotlin symbol providers:
  `DiagnosticCompilerTestFE10TestdataTestGenerated.TestsWithStdLib.Multiplatform.testJvmOverloads`
- Cause: The combined Kotlin symbol provider was able to find a class
  for `JvmOverloads`. However, the `KtModule` of `JvmOverloads` was
  `LibraryByRoots` with just the stdlib, while the registered stub-based
  deserialized symbol provider was known to the combined symbol provider
  with a `LibraryByRoots` containing 6 different paths. Hence, the
  single-root module wasn't found in the provider map.
- The fix creates a `LibraryByRoot` for each root, which leads to a
  separate deserialized symbol provider for each of the six roots,
  solving the discoverability problem.
This commit is contained in:
Marco Pennekamp
2023-05-09 12:58:49 +02:00
committed by Space Team
parent accc9b0eb3
commit bb7625c5b0
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.test.getAnalyzerServices
import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
import org.jetbrains.kotlin.utils.addIfNotNull
import java.io.File import java.io.File
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.Paths import java.nio.file.Paths
@@ -44,8 +43,8 @@ abstract class KtModuleByCompilerConfiguration(
val directRegularDependencies: List<KtModule> by lazy(LazyThreadSafetyMode.PUBLICATION) { val directRegularDependencies: List<KtModule> by lazy(LazyThreadSafetyMode.PUBLICATION) {
buildList { buildList {
testModule.allDependencies.mapTo(this) { moduleProvider.getModule(it.moduleName) } testModule.allDependencies.mapTo(this) { moduleProvider.getModule(it.moduleName) }
addIfNotNull( addAll(
libraryByRoots( librariesByRoots(
(configuration.jvmModularRoots + configuration.jvmClasspathRoots).map(File::toPath) (configuration.jvmModularRoots + configuration.jvmClasspathRoots).map(File::toPath)
) )
) )
@@ -62,22 +61,15 @@ abstract class KtModuleByCompilerConfiguration(
val directFriendDependencies: List<KtModule> by lazy(LazyThreadSafetyMode.PUBLICATION) { val directFriendDependencies: List<KtModule> by lazy(LazyThreadSafetyMode.PUBLICATION) {
buildList { buildList {
testModule.friendDependencies.mapTo(this) { moduleProvider.getModule(it.moduleName) } testModule.friendDependencies.mapTo(this) { moduleProvider.getModule(it.moduleName) }
addIfNotNull( addAll(
libraryByRoots(configuration[JVMConfigurationKeys.FRIEND_PATHS].orEmpty().map(Paths::get)) librariesByRoots(configuration[JVMConfigurationKeys.FRIEND_PATHS].orEmpty().map(Paths::get))
) )
} }
} }
protected abstract val ktModule: KtModule protected abstract val ktModule: KtModule
private fun libraryByRoots(roots: List<Path>): LibraryByRoots? { private fun librariesByRoots(roots: List<Path>): List<LibraryByRoot> = roots.map { LibraryByRoot(it, ktModule, project) }
if (roots.isEmpty()) return null
return LibraryByRoots(
roots,
ktModule,
project,
)
}
val languageVersionSettings: LanguageVersionSettings val languageVersionSettings: LanguageVersionSettings
get() = testModule.languageVersionSettings get() = testModule.languageVersionSettings
@@ -131,33 +123,33 @@ class KtLibrarySourceModuleByCompilerConfiguration(
override val libraryName: String get() = testModule.name override val libraryName: String get() = testModule.name
} }
private class LibraryByRoots( private class LibraryByRoot(
private val roots: List<Path>, private val root: Path,
private val module: KtModule, private val parentModule: KtModule,
override val project: Project, override val project: Project,
) : KtLibraryModule { ) : KtLibraryModule {
override val libraryName: String get() = "Test Library" override val libraryName: String get() = "Test Library $root"
override val directRegularDependencies: List<KtModule> get() = emptyList() override val directRegularDependencies: List<KtModule> get() = emptyList()
override val directDependsOnDependencies: List<KtModule> get() = emptyList() override val directDependsOnDependencies: List<KtModule> get() = emptyList()
override val transitiveDependsOnDependencies: List<KtModule> get() = emptyList() override val transitiveDependsOnDependencies: List<KtModule> get() = emptyList()
override val directFriendDependencies: List<KtModule> get() = emptyList() override val directFriendDependencies: List<KtModule> get() = emptyList()
override val contentScope: GlobalSearchScope get() = ProjectScope.getLibrariesScope(project) override val contentScope: GlobalSearchScope get() = ProjectScope.getLibrariesScope(project)
override val platform: TargetPlatform get() = module.platform override val platform: TargetPlatform get() = parentModule.platform
override val analyzerServices: PlatformDependentAnalyzerServices get() = module.analyzerServices override val analyzerServices: PlatformDependentAnalyzerServices get() = parentModule.analyzerServices
override fun getBinaryRoots(): Collection<Path> = roots override fun getBinaryRoots(): Collection<Path> = listOf(root)
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (this === other) return true if (this === other) return true
if (javaClass != other?.javaClass) return false if (javaClass != other?.javaClass) return false
other as LibraryByRoots other as LibraryByRoot
return roots == other.roots return root == other.root
} }
override fun hashCode(): Int { override fun hashCode(): Int {
return roots.hashCode() return root.hashCode()
} }
override val librarySources: KtLibrarySourceModule? get() = null override val librarySources: KtLibrarySourceModule? get() = null
} }