diff --git a/dokka-subprojects/core/src/main/kotlin/org/jetbrains/dokka/transformers/documentation/DefaultDocumentableMerger.kt b/dokka-subprojects/core/src/main/kotlin/org/jetbrains/dokka/transformers/documentation/DefaultDocumentableMerger.kt index 9de2c2b1a4..c7565be2c3 100644 --- a/dokka-subprojects/core/src/main/kotlin/org/jetbrains/dokka/transformers/documentation/DefaultDocumentableMerger.kt +++ b/dokka-subprojects/core/src/main/kotlin/org/jetbrains/dokka/transformers/documentation/DefaultDocumentableMerger.kt @@ -116,9 +116,12 @@ public class DefaultDocumentableMerger(context: DokkaContext) : DocumentableMerg listOf(actuals to actuals.flatMap { it.sourceSets }.toSet()) } else expects.map { expect -> val actualsForGivenExpect = actuals.filter { actual -> - dependencyInfo[actual.sourceSets.single()] + // [actual.sourceSets] can already be partially merged and contain more than one source set + actual.sourceSets.all { + dependencyInfo[it] ?.contains(expect.expectPresentInSet!!) ?: throw IllegalStateException("Cannot resolve expect/actual relation for ${actual.name}") + } } (listOf(expect) + actualsForGivenExpect) to actualsForGivenExpect.flatMap { it.sourceSets }.toSet() } diff --git a/dokka-subprojects/plugin-base/src/test/kotlin/expectActuals/ExpectActualsTest.kt b/dokka-subprojects/plugin-base/src/test/kotlin/expectActuals/ExpectActualsTest.kt index e7f535aa49..248f6feb7f 100644 --- a/dokka-subprojects/plugin-base/src/test/kotlin/expectActuals/ExpectActualsTest.kt +++ b/dokka-subprojects/plugin-base/src/test/kotlin/expectActuals/ExpectActualsTest.kt @@ -4,6 +4,7 @@ package expectActuals +import org.jetbrains.dokka.DokkaSourceSetID import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest import org.jetbrains.dokka.model.withDescendants import org.jetbrains.dokka.pages.ClasslikePageNode @@ -380,4 +381,58 @@ class ExpectActualsTest : BaseAbstractTest() { ) } } + + + @Test + fun `should work with the reversed order of source sets #3798`() { + val configuration = dokkaConfiguration { + sourceSets { + val commonId = DokkaSourceSetID("root", "common") + sourceSet { + sourceRoots = listOf("src/jvm/") + analysisPlatform = "jvm" + name = "jvm" + displayName = "jvm" + dependentSourceSets = setOf(commonId) + } + sourceSet { + sourceRoots = listOf("src/native/") + analysisPlatform = "native" + name = "native" + displayName = "native" + dependentSourceSets = setOf(commonId) + } + sourceSet { + sourceRoots = listOf("src/common/") + analysisPlatform = "common" + name = "common" + displayName = "common" + } + } + } + + testInline( + """ + /src/common/test.kt + expect fun shared() + + /src/native/test.kt + actual fun shared(){} + + /src/jvm/test.kt + actual fun shared(){} + """.trimMargin(), configuration + ) { + documentablesTransformationStage = { module -> + val function = module.packages.single().functions.single { it.name == "shared" } + assertTrue(function.isExpectActual) + assertEquals( + "common", function.expectPresentInSet?.sourceSetID?.sourceSetName + ) + assertEquals( + setOf("common", "jvm", "native"), function.sourceSets.map { it.sourceSetID.sourceSetName }.toSet() + ) + } + } + } }