[LL] Fix incorrect KMP groups in case of reordered dependencies

KTIJ-27569
This commit is contained in:
Pavel Kirpichenkov
2024-01-16 20:22:38 +02:00
committed by Space Team
parent 98e3813af9
commit 6deb679e5c
2 changed files with 42 additions and 7 deletions
@@ -39,10 +39,9 @@ class KmpModuleSorter private constructor(private val modules: List<KtModule>) {
private fun groupModules() {
for ((index, module) in modules.withIndex()) {
originalPositions[module] = index
val group = findOrCreateKmpGroup(module, groupsByModules)
val group = findOrCreateRootKmpGroup(module)
group.addModule(module)
groupsByModules.putIfAbsent(module, group)
module.directDependsOnDependencies.forEach { dependency -> groupsByModules.putIfAbsent(dependency, group) }
}
}
@@ -60,13 +59,21 @@ class KmpModuleSorter private constructor(private val modules: List<KtModule>) {
return sortedModules.toList().filterNotNull()
}
private fun findOrCreateKmpGroup(
// The group of the root source set, e.g., commonMain
private fun findOrCreateRootKmpGroup(
module: KtModule,
groups: MutableMap<KtModule, KmpGroup>,
): KmpGroup {
groups[module]?.let { return it }
module.directDependsOnDependencies.firstNotNullOfOrNull { dependency -> groups[dependency] }?.let { return it }
return KmpGroup()
groupsByModules[module]?.let { return it }
val root = if (module.directDependsOnDependencies.isEmpty()) module
else module.transitiveDependsOnDependencies.singleOrNull { dependency -> dependency.directDependsOnDependencies.isEmpty() }
if (root == null) {
hasErrors = true
return KmpGroup()
}
return groupsByModules.getOrPut(root) { KmpGroup() }
}
private fun getOriginalPositionOrSetCorrupted(module: KtModule): Int {
@@ -76,6 +76,34 @@ class KmpModuleSorterTest : TestWithMockProject() {
assertEquals(listOf(p1Platform, p1Intermediate, p1Common, p2Intermediate, p2Common), this.buildDependenciesToTest(p2Platform))
}
@Test
fun testPartsOfTheGroupAreMergedCorrectly1() {
val m1 = createKtModule("m1")
val m2 = createKtModule("m2", directDependsOnDependencies = listOf(m1))
val m3 = createKtModule("m3", directDependsOnDependencies = listOf(m2))
val m4 = createKtModule("m4", directDependsOnDependencies = listOf(m3))
val c = createKtModule("c", directRegularDependencies = listOf(m1, m3, m4, m2))
val d = createKtModule("d", directRegularDependencies = listOf(m2, m4, m3, m1))
assertEquals(listOf(m4, m3, m2, m1), buildDependenciesToTest(c))
assertEquals(listOf(m4, m3, m2, m1), buildDependenciesToTest(d))
}
@Test
fun testPartsOfTheGroupAreMergedCorrectly2() {
val m1 = createKtModule("m1")
val m2 = createKtModule("m2", directDependsOnDependencies = listOf(m1))
val m3 = createKtModule("m3", directDependsOnDependencies = listOf(m2))
val m4 = createKtModule("m4", directDependsOnDependencies = listOf(m3))
val m5 = createKtModule("m5", directDependsOnDependencies = listOf(m4))
val m6 = createKtModule("m6", directDependsOnDependencies = listOf(m5))
val c = createKtModule("c", directRegularDependencies = listOf(m3, m4, m6, m5, m2, m1))
val d = createKtModule("d", directRegularDependencies = listOf(m1, m2, m5, m6, m4, m3))
assertEquals(listOf(m6, m5, m4, m3, m2, m1), buildDependenciesToTest(c))
assertEquals(listOf(m6, m5, m4, m3, m2, m1), buildDependenciesToTest(d))
}
// See [org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirAbstractSessionFactory#collectDependencySymbolProviders]
private fun buildDependenciesToTest(module: KtModule): List<KtModule> {
val dependenciesToSort = buildSet {