[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() { private fun groupModules() {
for ((index, module) in modules.withIndex()) { for ((index, module) in modules.withIndex()) {
originalPositions[module] = index originalPositions[module] = index
val group = findOrCreateKmpGroup(module, groupsByModules) val group = findOrCreateRootKmpGroup(module)
group.addModule(module) group.addModule(module)
groupsByModules.putIfAbsent(module, group) 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() return sortedModules.toList().filterNotNull()
} }
private fun findOrCreateKmpGroup( // The group of the root source set, e.g., commonMain
private fun findOrCreateRootKmpGroup(
module: KtModule, module: KtModule,
groups: MutableMap<KtModule, KmpGroup>,
): KmpGroup { ): KmpGroup {
groups[module]?.let { return it } groupsByModules[module]?.let { return it }
module.directDependsOnDependencies.firstNotNullOfOrNull { dependency -> groups[dependency] }?.let { return it }
return KmpGroup() 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 { private fun getOriginalPositionOrSetCorrupted(module: KtModule): Int {
@@ -76,6 +76,34 @@ class KmpModuleSorterTest : TestWithMockProject() {
assertEquals(listOf(p1Platform, p1Intermediate, p1Common, p2Intermediate, p2Common), this.buildDependenciesToTest(p2Platform)) 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] // See [org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirAbstractSessionFactory#collectDependencySymbolProviders]
private fun buildDependenciesToTest(module: KtModule): List<KtModule> { private fun buildDependenciesToTest(module: KtModule): List<KtModule> {
val dependenciesToSort = buildSet { val dependenciesToSort = buildSet {