aboutsummaryrefslogtreecommitdiff
path: root/plugins/base/src/main/kotlin
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/base/src/main/kotlin')
-rw-r--r--plugins/base/src/main/kotlin/DokkaBase.kt2
-rw-r--r--plugins/base/src/main/kotlin/resolvers/local/DefaultLocationProvider.kt1
-rw-r--r--plugins/base/src/main/kotlin/resolvers/local/DokkaLocationProvider.kt40
-rw-r--r--plugins/base/src/main/kotlin/transformers/documentables/DefaultDocumentableMerger.kt410
-rw-r--r--plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt45
-rw-r--r--plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt2
6 files changed, 299 insertions, 201 deletions
diff --git a/plugins/base/src/main/kotlin/DokkaBase.kt b/plugins/base/src/main/kotlin/DokkaBase.kt
index 44a532f8..fcea6be9 100644
--- a/plugins/base/src/main/kotlin/DokkaBase.kt
+++ b/plugins/base/src/main/kotlin/DokkaBase.kt
@@ -54,7 +54,7 @@ class DokkaBase : DokkaPlugin() {
}
val documentableMerger by extending {
- CoreExtensions.documentableMerger with DefaultDocumentableMerger
+ CoreExtensions.documentableMerger providing ::DefaultDocumentableMerger
}
val deprecatedDocumentableFilter by extending {
diff --git a/plugins/base/src/main/kotlin/resolvers/local/DefaultLocationProvider.kt b/plugins/base/src/main/kotlin/resolvers/local/DefaultLocationProvider.kt
index c25aa543..e085af1a 100644
--- a/plugins/base/src/main/kotlin/resolvers/local/DefaultLocationProvider.kt
+++ b/plugins/base/src/main/kotlin/resolvers/local/DefaultLocationProvider.kt
@@ -4,6 +4,7 @@ import org.jetbrains.dokka.base.DokkaBase
import org.jetbrains.dokka.base.resolvers.external.ExternalLocationProvider
import org.jetbrains.dokka.base.resolvers.shared.ExternalDocumentation
import org.jetbrains.dokka.base.resolvers.shared.PackageList
+import org.jetbrains.dokka.base.resolvers.anchors.SymbolAnchorHint
import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.model.DisplaySourceSet
import org.jetbrains.dokka.pages.RootPageNode
diff --git a/plugins/base/src/main/kotlin/resolvers/local/DokkaLocationProvider.kt b/plugins/base/src/main/kotlin/resolvers/local/DokkaLocationProvider.kt
index 096104cc..0269d7a6 100644
--- a/plugins/base/src/main/kotlin/resolvers/local/DokkaLocationProvider.kt
+++ b/plugins/base/src/main/kotlin/resolvers/local/DokkaLocationProvider.kt
@@ -1,5 +1,6 @@
package org.jetbrains.dokka.base.resolvers.local
+import org.jetbrains.dokka.base.renderers.sourceSets
import org.jetbrains.dokka.base.resolvers.anchors.SymbolAnchorHint
import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.links.PointingToDeclaration
@@ -26,35 +27,46 @@ open class DokkaLocationProvider(
pageGraphRoot.children.forEach { registerPath(it, emptyList()) }
}
- protected open val pagesIndex: Map<DRI, ContentPage> =
+ protected val pagesIndex: Map<Pair<DRI, DisplaySourceSet>, ContentPage> =
pageGraphRoot.withDescendants().filterIsInstance<ContentPage>()
- .flatMap { it.dri.map { dri -> dri to it } }
+ .flatMap { page ->
+ page.dri.flatMap { dri ->
+ page.sourceSets().map { sourceSet -> (dri to sourceSet) to page }
+ }
+ }
.groupingBy { it.first }
- .aggregate { dri, _, (_, page), first ->
- if (first) page else throw AssertionError("Multiple pages associated with dri: $dri")
+ .aggregate { key, _, (_, page), first ->
+ if (first) page else throw AssertionError("Multiple pages associated with key: ${key.first}/${key.second}")
}
- protected open val anchorsIndex: Map<DRI, ContentPage> =
+ protected val anchorsIndex: Map<Pair<DRI, DisplaySourceSet>, ContentPage> =
pageGraphRoot.withDescendants().filterIsInstance<ContentPage>()
.flatMap { page ->
page.content.withDescendants()
.filter { it.extra[SymbolAnchorHint] != null }
.mapNotNull { it.dci.dri.singleOrNull() }
.distinct()
- .map { it to page }
+ .flatMap { dri ->
+ page.sourceSets().map { sourceSet ->
+ (dri to sourceSet) to page
+ }
+ }
}.toMap()
override fun resolve(node: PageNode, context: PageNode?, skipExtension: Boolean) =
pathTo(node, context) + if (!skipExtension) extension else ""
- override fun resolve(dri: DRI, sourceSets: Set<DisplaySourceSet>, context: PageNode?) =
- getLocalLocation(dri, context)
- ?: getLocalLocation(dri.copy(target = PointingToDeclaration), context)
- // Not found in PageGraph, that means it's an external link
- ?: getExternalLocation(dri, sourceSets)
- ?: getExternalLocation(dri.copy(target = PointingToDeclaration), sourceSets)
-
- private fun getLocalLocation(dri: DRI, context: PageNode?): String? =
+ override fun resolve(dri: DRI, sourceSets: Set<DisplaySourceSet>, context: PageNode?): String? =
+ sourceSets.mapNotNull { sourceSet ->
+ val driWithSourceSet = Pair(dri, sourceSet)
+ getLocalLocation(driWithSourceSet, context)
+ ?: getLocalLocation(driWithSourceSet.copy(first = dri.copy(target = PointingToDeclaration)), context)
+ // Not found in PageGraph, that means it's an external link
+ ?: getExternalLocation(dri, sourceSets)
+ ?: getExternalLocation(dri.copy(target = PointingToDeclaration), sourceSets)
+ }.distinct().singleOrNull()
+
+ private fun getLocalLocation(dri: Pair<DRI, DisplaySourceSet>, context: PageNode?): String? =
pagesIndex[dri]?.let { resolve(it, context) }
?: anchorsIndex[dri]?.let { resolve(it, context) + "#$dri" }
diff --git a/plugins/base/src/main/kotlin/transformers/documentables/DefaultDocumentableMerger.kt b/plugins/base/src/main/kotlin/transformers/documentables/DefaultDocumentableMerger.kt
index 17ead667..d556c9cb 100644
--- a/plugins/base/src/main/kotlin/transformers/documentables/DefaultDocumentableMerger.kt
+++ b/plugins/base/src/main/kotlin/transformers/documentables/DefaultDocumentableMerger.kt
@@ -1,195 +1,269 @@
package org.jetbrains.dokka.base.transformers.documentables
+import org.jetbrains.dokka.DokkaConfiguration
+import org.jetbrains.dokka.DokkaSourceSetID
import org.jetbrains.dokka.model.*
+import org.jetbrains.dokka.model.properties.WithExtraProperties
import org.jetbrains.dokka.model.properties.mergeExtras
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.transformers.documentation.DocumentableMerger
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
+import org.jetbrains.kotlin.utils.addToStdlib.safeAs
-internal object DefaultDocumentableMerger : DocumentableMerger {
+internal class DefaultDocumentableMerger(context: DokkaContext) : DocumentableMerger {
+ private val dependencyInfo = context.getDependencyInfo()
- override fun invoke(modules: Collection<DModule>, context: DokkaContext): DModule {
- return modules.reduce { left, right ->
+ override fun invoke(modules: Collection<DModule>): DModule {
+
+ return topologicalSort(modules).reduce { left, right ->
val list = listOf(left, right)
DModule(
name = modules.map { it.name }.distinct().joinToString("|"),
packages = merge(
- list.flatMap { it.packages },
- DPackage::mergeWith
- ),
+ list.flatMap { it.packages }
+ ) { pck1, pck2 -> pck1.mergeWith(pck2) },
documentation = list.map { it.documentation }.flatMap { it.entries }.associate { (k, v) -> k to v },
expectPresentInSet = list.firstNotNullResult { it.expectPresentInSet },
sourceSets = list.flatMap { it.sourceSets }.toSet()
).mergeExtras(left, right)
}
}
-}
-private fun <T : Documentable> merge(elements: List<T>, reducer: (T, T) -> T): List<T> =
- elements.groupingBy { it.dri }
- .reduce { _, left, right -> reducer(left, right) }
- .values.toList()
+ private fun topologicalSort(allModules: Collection<DModule>): List<DModule> {
-private fun <T> mergeExpectActual(
- elements: List<T>,
- reducer: (T, T) -> T
-): List<T> where T : Documentable, T : WithExpectActual {
+ val modulesMap: Map<DokkaSourceSetID, ModuleOfDifferentTranslators> =
+ allModules.groupBy { it.sourceSets.single().sourceSetID }
- fun analyzeExpectActual(sameDriElements: List<T>) = sameDriElements.reduce(reducer)
+ //this returns representation of graph where directed edges are leading from module to modules that depend on it
+ val graph: Map<ModuleOfDifferentTranslators?, List<ModuleOfDifferentTranslators>> = modulesMap.flatMap { (_, module) ->
+ module.first().sourceSets.single().dependentSourceSets.map { sourceSet ->
+ modulesMap[sourceSet] to module
+ }
+ }.groupBy { it.first }.entries
+ .map { it.key to it.value.map { it.second } }
+ .toMap()
- return elements.groupBy { it.dri }.values.map(::analyzeExpectActual)
-}
-fun DPackage.mergeWith(other: DPackage): DPackage = copy(
- functions = mergeExpectActual(functions + other.functions, DFunction::mergeWith),
- properties = mergeExpectActual(properties + other.properties, DProperty::mergeWith),
- classlikes = mergeExpectActual(classlikes + other.classlikes, DClasslike::mergeWith),
- documentation = documentation + other.documentation,
- expectPresentInSet = expectPresentInSet ?: other.expectPresentInSet,
- typealiases = merge(typealiases + other.typealiases, DTypeAlias::mergeWith),
- sourceSets = sourceSets + other.sourceSets
-).mergeExtras(this, other)
-
-fun DFunction.mergeWith(other: DFunction): DFunction = copy(
- parameters = merge(this.parameters + other.parameters, DParameter::mergeWith),
- receiver = receiver?.let { r -> other.receiver?.let { r.mergeWith(it) } ?: r } ?: other.receiver,
- documentation = documentation + other.documentation,
- expectPresentInSet = expectPresentInSet ?: other.expectPresentInSet,
- sources = sources + other.sources,
- visibility = visibility + other.visibility,
- modifier = modifier + other.modifier,
- sourceSets = sourceSets + other.sourceSets,
- generics = merge(generics + other.generics, DTypeParameter::mergeWith)
-).mergeExtras(this, other)
-
-fun DProperty.mergeWith(other: DProperty): DProperty = copy(
- receiver = receiver?.let { r -> other.receiver?.let { r.mergeWith(it) } ?: r } ?: other.receiver,
- documentation = documentation + other.documentation,
- expectPresentInSet = expectPresentInSet ?: other.expectPresentInSet,
- sources = sources + other.sources,
- visibility = visibility + other.visibility,
- modifier = modifier + other.modifier,
- sourceSets = sourceSets + other.sourceSets,
- getter = getter?.let { g -> other.getter?.let { g.mergeWith(it) } ?: g } ?: other.getter,
- setter = setter?.let { s -> other.setter?.let { s.mergeWith(it) } ?: s } ?: other.setter,
- generics = merge(generics + other.generics, DTypeParameter::mergeWith)
-).mergeExtras(this, other)
-
-fun DClasslike.mergeWith(other: DClasslike): DClasslike = when {
- this is DClass && other is DClass -> mergeWith(other)
- this is DEnum && other is DEnum -> mergeWith(other)
- this is DInterface && other is DInterface -> mergeWith(other)
- this is DObject && other is DObject -> mergeWith(other)
- this is DAnnotation && other is DAnnotation -> mergeWith(other)
- else -> throw IllegalStateException("${this::class.qualifiedName} ${this.name} cannot be mergesd with ${other::class.qualifiedName} ${other.name}")
+ val visited = modulesMap.map { it.value to false }.toMap().toMutableMap()
+ val topologicalSortedList: MutableList<ModuleOfDifferentTranslators> = mutableListOf()
+
+ fun dfs(module: ModuleOfDifferentTranslators) {
+ visited[module] = true
+ graph[module]?.forEach { if (!visited[it]!!) dfs(it) }
+ topologicalSortedList.add(0, module)
+ }
+ modulesMap.values.forEach { if (!visited[it]!!) dfs(it) }
+
+ return topologicalSortedList.flatten()
+ }
+
+ private fun DokkaContext.getDependencyInfo()
+ : Map<DokkaConfiguration.DokkaSourceSet, List<DokkaConfiguration.DokkaSourceSet>> {
+
+ fun getDependencies(sourceSet: DokkaConfiguration.DokkaSourceSet): List<DokkaConfiguration.DokkaSourceSet> =
+ listOf(sourceSet) + configuration.sourceSets.filter {
+ it.sourceSetID in sourceSet.dependentSourceSets
+ }.flatMap { getDependencies(it) }
+
+ return configuration.sourceSets.map { it to getDependencies(it) }.toMap()
+ }
+
+ private fun <T : Documentable> merge(elements: List<T>, reducer: (T, T) -> T): List<T> =
+ elements.groupingBy { it.dri }
+ .reduce { _, left, right -> reducer(left, right) }
+ .values.toList()
+
+ private fun <T> mergeExpectActual(
+ elements: List<T>,
+ reducer: (T, T) -> T
+ ): List<T> where T : Documentable, T : WithExpectActual {
+
+ fun analyzeExpectActual(sameDriElements: List<T>) = sameDriElements
+ .partition { it.expectPresentInSet != null }
+ .let { (expects, actuals) ->
+ expects.map { expect ->
+ listOf(expect) + actuals.filter { actual ->
+ dependencyInfo[actual.sourceSets.single()]
+ ?.contains(expect.expectPresentInSet!!)
+ ?: throw IllegalStateException("Cannot resolve expect/actual relation for ${actual.name}")
+ }
+ }.map { it.reduce(reducer) }
+ }
+
+ fun T.isExpectActual(): Boolean =
+ this.safeAs<WithExtraProperties<T>>().let { it != null && it.extra[IsExpectActual] != null }
+
+ fun mergeClashingElements(elements: List<T>) = if(elements.size <= 1) elements else elements.map {
+ when(it) {
+ is DClass -> it.copy(name = "${it.name}(${it.sourceSets.single().analysisPlatform.key})")
+ is DObject -> it.copy(name = "${it.name}(${it.sourceSets.single().analysisPlatform.key})")
+ is DAnnotation -> it.copy(name = "${it.name}(${it.sourceSets.single().analysisPlatform.key})")
+ is DInterface -> it.copy(name = "${it.name}(${it.sourceSets.single().analysisPlatform.key})")
+ is DEnum -> it.copy(name = "${it.name}(${it.sourceSets.single().analysisPlatform.key})")
+ is DFunction -> it.copy(name = "${it.name}(${it.sourceSets.single().analysisPlatform.key})")
+ is DProperty -> it.copy(name = "${it.name}(${it.sourceSets.single().analysisPlatform.key})")
+ else -> elements
+ }
+ } as List<T>
+
+ return elements.partition {
+ it.isExpectActual()
+ }.let { (expectActuals, notExpectActuals) ->
+ notExpectActuals.groupBy { it.dri }.values.flatMap(::mergeClashingElements) +
+ expectActuals.groupBy { it.dri }.values.flatMap(::analyzeExpectActual)
+ }
+ }
+
+ fun DPackage.mergeWith(other: DPackage): DPackage = copy(
+ functions = mergeExpectActual(functions + other.functions) { f1, f2 -> f1.mergeWith(f2) },
+ properties = mergeExpectActual(properties + other.properties) { p1, p2 -> p1.mergeWith(p2) },
+ classlikes = mergeExpectActual(classlikes + other.classlikes) { c1, c2 -> c1.mergeWith(c2) },
+ documentation = documentation + other.documentation,
+ expectPresentInSet = expectPresentInSet ?: other.expectPresentInSet,
+ typealiases = merge(typealiases + other.typealiases) { ta1, ta2 -> ta1.mergeWith(ta2) },
+ sourceSets = sourceSets + other.sourceSets
+ ).mergeExtras(this, other)
+
+ fun DFunction.mergeWith(other: DFunction): DFunction = copy(
+ parameters = merge(this.parameters + other.parameters) { p1, p2 -> p1.mergeWith(p2) },
+ receiver = receiver?.let { r -> other.receiver?.let { r.mergeWith(it) } ?: r } ?: other.receiver,
+ documentation = documentation + other.documentation,
+ expectPresentInSet = expectPresentInSet ?: other.expectPresentInSet,
+ sources = sources + other.sources,
+ visibility = visibility + other.visibility,
+ modifier = modifier + other.modifier,
+ sourceSets = sourceSets + other.sourceSets,
+ generics = merge(generics + other.generics) { tp1, tp2 -> tp1.mergeWith(tp2) },
+ ).mergeExtras(this, other)
+
+ fun DProperty.mergeWith(other: DProperty): DProperty = copy(
+ receiver = receiver?.let { r -> other.receiver?.let { r.mergeWith(it) } ?: r } ?: other.receiver,
+ documentation = documentation + other.documentation,
+ expectPresentInSet = expectPresentInSet ?: other.expectPresentInSet,
+ sources = sources + other.sources,
+ visibility = visibility + other.visibility,
+ modifier = modifier + other.modifier,
+ sourceSets = sourceSets + other.sourceSets,
+ getter = getter?.let { g -> other.getter?.let { g.mergeWith(it) } ?: g } ?: other.getter,
+ setter = setter?.let { s -> other.setter?.let { s.mergeWith(it) } ?: s } ?: other.setter,
+ generics = merge(generics + other.generics) { tp1, tp2 -> tp1.mergeWith(tp2) },
+ ).mergeExtras(this, other)
+
+ fun DClasslike.mergeWith(other: DClasslike): DClasslike = when {
+ this is DClass && other is DClass -> mergeWith(other)
+ this is DEnum && other is DEnum -> mergeWith(other)
+ this is DInterface && other is DInterface -> mergeWith(other)
+ this is DObject && other is DObject -> mergeWith(other)
+ this is DAnnotation && other is DAnnotation -> mergeWith(other)
+ else -> throw IllegalStateException("${this::class.qualifiedName} ${this.name} cannot be merged with ${other::class.qualifiedName} ${other.name}")
+ }
+
+ fun DClass.mergeWith(other: DClass): DClass = copy(
+ constructors = mergeExpectActual(
+ constructors + other.constructors
+ ) { f1, f2 -> f1.mergeWith(f2) },
+ functions = mergeExpectActual(functions + other.functions) { f1, f2 -> f1.mergeWith(f2) },
+ properties = mergeExpectActual(properties + other.properties) { p1, p2 -> p1.mergeWith(p2) },
+ classlikes = mergeExpectActual(classlikes + other.classlikes) { c1, c2 -> c1.mergeWith(c2) },
+ companion = companion?.let { c -> other.companion?.let { c.mergeWith(it) } ?: c } ?: other.companion,
+ generics = merge(generics + other.generics) { tp1, tp2 -> tp1.mergeWith(tp2) },
+ modifier = modifier + other.modifier,
+ supertypes = supertypes + other.supertypes,
+ documentation = documentation + other.documentation,
+ expectPresentInSet = expectPresentInSet ?: other.expectPresentInSet,
+ sources = sources + other.sources,
+ visibility = visibility + other.visibility,
+ sourceSets = sourceSets + other.sourceSets
+ ).mergeExtras(this, other)
+
+ fun DEnum.mergeWith(other: DEnum): DEnum = copy(
+ entries = merge(entries + other.entries) { ee1, ee2 -> ee1.mergeWith(ee2) },
+ constructors = mergeExpectActual(
+ constructors + other.constructors
+ ) { f1, f2 -> f1.mergeWith(f2) },
+ functions = mergeExpectActual(functions + other.functions) { f1, f2 -> f1.mergeWith(f2) },
+ properties = mergeExpectActual(properties + other.properties) { p1, p2 -> p1.mergeWith(p2) },
+ classlikes = mergeExpectActual(classlikes + other.classlikes) { c1, c2 -> c1.mergeWith(c2) },
+ companion = companion?.let { c -> other.companion?.let { c.mergeWith(it) } ?: c } ?: other.companion,
+ supertypes = supertypes + other.supertypes,
+ documentation = documentation + other.documentation,
+ expectPresentInSet = expectPresentInSet ?: other.expectPresentInSet,
+ sources = sources + other.sources,
+ visibility = visibility + other.visibility,
+ sourceSets = sourceSets + other.sourceSets
+ ).mergeExtras(this, other)
+
+ fun DEnumEntry.mergeWith(other: DEnumEntry): DEnumEntry = copy(
+ functions = mergeExpectActual(functions + other.functions) { f1, f2 -> f1.mergeWith(f2) },
+ properties = mergeExpectActual(properties + other.properties) { p1, p2 -> p1.mergeWith(p2) },
+ classlikes = mergeExpectActual(classlikes + other.classlikes) { c1, c2 -> c1.mergeWith(c2) },
+ documentation = documentation + other.documentation,
+ expectPresentInSet = expectPresentInSet ?: other.expectPresentInSet,
+ sourceSets = sourceSets + other.sourceSets
+ ).mergeExtras(this, other)
+
+ fun DObject.mergeWith(other: DObject): DObject = copy(
+ functions = mergeExpectActual(functions + other.functions) { f1, f2 -> f1.mergeWith(f2) },
+ properties = mergeExpectActual(properties + other.properties) { p1, p2 -> p1.mergeWith(p2) },
+ classlikes = mergeExpectActual(classlikes + other.classlikes) { c1, c2 -> c1.mergeWith(c2) },
+ supertypes = supertypes + other.supertypes,
+ documentation = documentation + other.documentation,
+ expectPresentInSet = expectPresentInSet ?: other.expectPresentInSet,
+ sources = sources + other.sources,
+ visibility = visibility + other.visibility,
+ sourceSets = sourceSets + other.sourceSets
+ ).mergeExtras(this, other)
+
+ fun DInterface.mergeWith(other: DInterface): DInterface = copy(
+ functions = mergeExpectActual(functions + other.functions) { f1, f2 -> f1.mergeWith(f2) },
+ properties = mergeExpectActual(properties + other.properties) { p1, p2 -> p1.mergeWith(p2) },
+ classlikes = mergeExpectActual(classlikes + other.classlikes) { c1, c2 -> c1.mergeWith(c2) },
+ companion = companion?.let { c -> other.companion?.let { c.mergeWith(it) } ?: c } ?: other.companion,
+ generics = merge(generics + other.generics) { tp1, tp2 -> tp1.mergeWith(tp2) },
+ supertypes = supertypes + other.supertypes,
+ documentation = documentation + other.documentation,
+ expectPresentInSet = expectPresentInSet ?: other.expectPresentInSet,
+ sources = sources + other.sources,
+ visibility = visibility + other.visibility,
+ sourceSets = sourceSets + other.sourceSets
+ ).mergeExtras(this, other)
+
+ fun DAnnotation.mergeWith(other: DAnnotation): DAnnotation = copy(
+ constructors = mergeExpectActual(
+ constructors + other.constructors
+ ) { f1, f2 -> f1.mergeWith(f2) },
+ functions = mergeExpectActual(functions + other.functions) { f1, f2 -> f1.mergeWith(f2) },
+ properties = mergeExpectActual(properties + other.properties) { p1, p2 -> p1.mergeWith(p2) },
+ classlikes = mergeExpectActual(classlikes + other.classlikes) { c1, c2 -> c1.mergeWith(c2) },
+ companion = companion?.let { c -> other.companion?.let { c.mergeWith(it) } ?: c } ?: other.companion,
+ documentation = documentation + other.documentation,
+ expectPresentInSet = expectPresentInSet ?: other.expectPresentInSet,
+ sources = sources + other.sources,
+ visibility = visibility + other.visibility,
+ sourceSets = sourceSets + other.sourceSets,
+ generics = merge(generics + other.generics) { tp1, tp2 -> tp1.mergeWith(tp2) }
+ ).mergeExtras(this, other)
+
+ fun DParameter.mergeWith(other: DParameter): DParameter = copy(
+ documentation = documentation + other.documentation,
+ expectPresentInSet = expectPresentInSet ?: other.expectPresentInSet,
+ sourceSets = sourceSets + other.sourceSets
+ ).mergeExtras(this, other)
+
+ fun DTypeParameter.mergeWith(other: DTypeParameter): DTypeParameter = copy(
+ documentation = documentation + other.documentation,
+ expectPresentInSet = expectPresentInSet ?: other.expectPresentInSet,
+ sourceSets = sourceSets + other.sourceSets
+ ).mergeExtras(this, other)
+
+ fun DTypeAlias.mergeWith(other: DTypeAlias): DTypeAlias = copy(
+ documentation = documentation + other.documentation,
+ expectPresentInSet = expectPresentInSet ?: other.expectPresentInSet,
+ underlyingType = underlyingType + other.underlyingType,
+ visibility = visibility + other.visibility,
+ sourceSets = sourceSets + other.sourceSets
+ ).mergeExtras(this, other)
}
-fun DClass.mergeWith(other: DClass): DClass = copy(
- constructors = mergeExpectActual(
- constructors + other.constructors,
- DFunction::mergeWith
- ),
- functions = mergeExpectActual(functions + other.functions, DFunction::mergeWith),
- properties = mergeExpectActual(properties + other.properties, DProperty::mergeWith),
- classlikes = mergeExpectActual(classlikes + other.classlikes, DClasslike::mergeWith),
- companion = companion?.let { c -> other.companion?.let { c.mergeWith(it) } ?: c } ?: other.companion,
- generics = merge(generics + other.generics, DTypeParameter::mergeWith),
- modifier = modifier + other.modifier,
- supertypes = supertypes + other.supertypes,
- documentation = documentation + other.documentation,
- expectPresentInSet = expectPresentInSet ?: other.expectPresentInSet,
- sources = sources + other.sources,
- visibility = visibility + other.visibility,
- sourceSets = sourceSets + other.sourceSets
-).mergeExtras(this, other)
-
-fun DEnum.mergeWith(other: DEnum): DEnum = copy(
- entries = merge(entries + other.entries, DEnumEntry::mergeWith),
- constructors = mergeExpectActual(
- constructors + other.constructors,
- DFunction::mergeWith
- ),
- functions = mergeExpectActual(functions + other.functions, DFunction::mergeWith),
- properties = mergeExpectActual(properties + other.properties, DProperty::mergeWith),
- classlikes = mergeExpectActual(classlikes + other.classlikes, DClasslike::mergeWith),
- companion = companion?.let { c -> other.companion?.let { c.mergeWith(it) } ?: c } ?: other.companion,
- supertypes = supertypes + other.supertypes,
- documentation = documentation + other.documentation,
- expectPresentInSet = expectPresentInSet ?: other.expectPresentInSet,
- sources = sources + other.sources,
- visibility = visibility + other.visibility,
- sourceSets = sourceSets + other.sourceSets
-).mergeExtras(this, other)
-
-fun DEnumEntry.mergeWith(other: DEnumEntry): DEnumEntry = copy(
- functions = mergeExpectActual(functions + other.functions, DFunction::mergeWith),
- properties = mergeExpectActual(properties + other.properties, DProperty::mergeWith),
- classlikes = mergeExpectActual(classlikes + other.classlikes, DClasslike::mergeWith),
- documentation = documentation + other.documentation,
- expectPresentInSet = expectPresentInSet ?: other.expectPresentInSet,
- sourceSets = sourceSets + other.sourceSets
-).mergeExtras(this, other)
-
-fun DObject.mergeWith(other: DObject): DObject = copy(
- functions = mergeExpectActual(functions + other.functions, DFunction::mergeWith),
- properties = mergeExpectActual(properties + other.properties, DProperty::mergeWith),
- classlikes = mergeExpectActual(classlikes + other.classlikes, DClasslike::mergeWith),
- supertypes = supertypes + other.supertypes,
- documentation = documentation + other.documentation,
- expectPresentInSet = expectPresentInSet ?: other.expectPresentInSet,
- sources = sources + other.sources,
- visibility = visibility + other.visibility,
- sourceSets = sourceSets + other.sourceSets
-).mergeExtras(this, other)
-
-fun DInterface.mergeWith(other: DInterface): DInterface = copy(
- functions = mergeExpectActual(functions + other.functions, DFunction::mergeWith),
- properties = mergeExpectActual(properties + other.properties, DProperty::mergeWith),
- classlikes = mergeExpectActual(classlikes + other.classlikes, DClasslike::mergeWith),
- companion = companion?.let { c -> other.companion?.let { c.mergeWith(it) } ?: c } ?: other.companion,
- generics = merge(generics + other.generics, DTypeParameter::mergeWith),
- supertypes = supertypes + other.supertypes,
- documentation = documentation + other.documentation,
- expectPresentInSet = expectPresentInSet ?: other.expectPresentInSet,
- sources = sources + other.sources,
- visibility = visibility + other.visibility,
- sourceSets = sourceSets + other.sourceSets
-).mergeExtras(this, other)
-
-fun DAnnotation.mergeWith(other: DAnnotation): DAnnotation = copy(
- constructors = mergeExpectActual(
- constructors + other.constructors,
- DFunction::mergeWith
- ),
- functions = mergeExpectActual(functions + other.functions, DFunction::mergeWith),
- properties = mergeExpectActual(properties + other.properties, DProperty::mergeWith),
- classlikes = mergeExpectActual(classlikes + other.classlikes, DClasslike::mergeWith),
- companion = companion?.let { c -> other.companion?.let { c.mergeWith(it) } ?: c } ?: other.companion,
- documentation = documentation + other.documentation,
- expectPresentInSet = expectPresentInSet ?: other.expectPresentInSet,
- sources = sources + other.sources,
- visibility = visibility + other.visibility,
- sourceSets = sourceSets + other.sourceSets,
- generics = merge(generics + other.generics, DTypeParameter::mergeWith)
-).mergeExtras(this, other)
-
-fun DParameter.mergeWith(other: DParameter): DParameter = copy(
- documentation = documentation + other.documentation,
- expectPresentInSet = expectPresentInSet ?: other.expectPresentInSet,
- sourceSets = sourceSets + other.sourceSets
-).mergeExtras(this, other)
-
-fun DTypeParameter.mergeWith(other: DTypeParameter): DTypeParameter = copy(
- documentation = documentation + other.documentation,
- expectPresentInSet = expectPresentInSet ?: other.expectPresentInSet,
- sourceSets = sourceSets + other.sourceSets
-).mergeExtras(this, other)
-
-fun DTypeAlias.mergeWith(other: DTypeAlias): DTypeAlias = copy(
- documentation = documentation + other.documentation,
- expectPresentInSet = expectPresentInSet ?: other.expectPresentInSet,
- underlyingType = underlyingType + other.underlyingType,
- visibility = visibility + other.visibility,
- sourceSets = sourceSets + other.sourceSets
-).mergeExtras(this, other)
+private typealias ModuleOfDifferentTranslators = List<DModule>
diff --git a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt
index 8e5a1927..57d4f151 100644
--- a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt
+++ b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt
@@ -12,6 +12,7 @@ import org.jetbrains.dokka.model.*
import org.jetbrains.dokka.model.Nullable
import org.jetbrains.dokka.model.TypeConstructor
import org.jetbrains.dokka.model.doc.*
+import org.jetbrains.dokka.model.properties.ExtraProperty
import org.jetbrains.dokka.model.properties.PropertyContainer
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.transformers.sources.SourceToDocumentableTranslator
@@ -140,6 +141,7 @@ private class DokkaDescriptorVisitor(
val driWithPlatform = parent.dri.withClass(descriptor.name.asString()).withEmptyInfo()
val scope = descriptor.unsubstitutedMemberScope
val isExpect = descriptor.isExpect
+ val isActual = descriptor.isActual
val info = descriptor.resolveClassDescriptionData()
return DInterface(
@@ -156,11 +158,11 @@ private class DokkaDescriptorVisitor(
generics = descriptor.declaredTypeParameters.map { it.toVariantTypeParameter() },
companion = descriptor.companion(driWithPlatform),
sourceSets = setOf(sourceSet),
- extra = PropertyContainer.withAll(
+ extra = PropertyContainer.withAll<DInterface>(
descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(),
descriptor.getAnnotations().toSourceSetDependent().toAnnotations(),
ImplementedInterfaces(info.allImplementedInterfaces.toSourceSetDependent())
- )
+ ).let { if (isExpect || isActual) it + IsExpectActual else it }
)
}
@@ -168,6 +170,7 @@ private class DokkaDescriptorVisitor(
val driWithPlatform = parent.dri.withClass(descriptor.name.asString()).withEmptyInfo()
val scope = descriptor.unsubstitutedMemberScope
val isExpect = descriptor.isExpect
+ val isActual = descriptor.isActual
val info = descriptor.resolveClassDescriptionData()
@@ -183,11 +186,11 @@ private class DokkaDescriptorVisitor(
supertypes = info.supertypes.toSourceSetDependent(),
documentation = info.docs,
sourceSets = setOf(sourceSet),
- extra = PropertyContainer.withAll(
+ extra = PropertyContainer.withAll<DObject>(
descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(),
descriptor.getAnnotations().toSourceSetDependent().toAnnotations(),
ImplementedInterfaces(info.allImplementedInterfaces.toSourceSetDependent())
- )
+ ).let { if (isExpect || isActual) it + IsExpectActual else it }
)
}
@@ -195,6 +198,7 @@ private class DokkaDescriptorVisitor(
val driWithPlatform = parent.dri.withClass(descriptor.name.asString()).withEmptyInfo()
val scope = descriptor.unsubstitutedMemberScope
val isExpect = descriptor.isExpect
+ val isActual = descriptor.isActual
val info = descriptor.resolveClassDescriptionData()
return DEnum(
@@ -212,11 +216,11 @@ private class DokkaDescriptorVisitor(
documentation = info.docs,
companion = descriptor.companion(driWithPlatform),
sourceSets = setOf(sourceSet),
- extra = PropertyContainer.withAll(
+ extra = PropertyContainer.withAll<DEnum>(
descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(),
descriptor.getAnnotations().toSourceSetDependent().toAnnotations(),
ImplementedInterfaces(info.allImplementedInterfaces.toSourceSetDependent())
- )
+ ).let { if (isExpect || isActual) it + IsExpectActual else it }
)
}
@@ -245,6 +249,8 @@ private class DokkaDescriptorVisitor(
fun annotationDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): DAnnotation {
val driWithPlatform = parent.dri.withClass(descriptor.name.asString()).withEmptyInfo()
val scope = descriptor.unsubstitutedMemberScope
+ val isExpect = descriptor.isExpect
+ val isActual = descriptor.isActual
return DAnnotation(
dri = driWithPlatform.dri,
@@ -253,12 +259,12 @@ private class DokkaDescriptorVisitor(
classlikes = scope.classlikes(driWithPlatform),
functions = scope.functions(driWithPlatform),
properties = scope.properties(driWithPlatform),
- expectPresentInSet = null,
+ expectPresentInSet = sourceSet.takeIf { isExpect },
sourceSets = setOf(sourceSet),
- extra = PropertyContainer.withAll(
+ extra = PropertyContainer.withAll<DAnnotation>(
descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(),
descriptor.getAnnotations().toSourceSetDependent().toAnnotations()
- ),
+ ).let { if (isExpect || isActual) it + IsExpectActual else it },
companion = descriptor.companionObjectDescriptor?.let { objectDescriptor(it, driWithPlatform) },
visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(),
generics = descriptor.declaredTypeParameters.map { it.toVariantTypeParameter() },
@@ -271,6 +277,7 @@ private class DokkaDescriptorVisitor(
val driWithPlatform = parent.dri.withClass(descriptor.name.asString()).withEmptyInfo()
val scope = descriptor.unsubstitutedMemberScope
val isExpect = descriptor.isExpect
+ val isActual = descriptor.isActual
val info = descriptor.resolveClassDescriptionData()
val actual = descriptor.createSources()
@@ -296,17 +303,18 @@ private class DokkaDescriptorVisitor(
modifier = descriptor.modifier().toSourceSetDependent(),
companion = descriptor.companion(driWithPlatform),
sourceSets = setOf(sourceSet),
- extra = PropertyContainer.withAll(
+ extra = PropertyContainer.withAll<DClass>(
descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(),
descriptor.getAnnotations().toSourceSetDependent().toAnnotations(),
ImplementedInterfaces(info.allImplementedInterfaces.toSourceSetDependent())
- )
+ ).let { if (isExpect || isActual) it + IsExpectActual else it }
)
}
override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, parent: DRIWithPlatformInfo): DProperty {
val dri = parent.dri.copy(callable = Callable.from(descriptor))
val isExpect = descriptor.isExpect
+ val isActual = descriptor.isActual
val actual = descriptor.createSources()
return DProperty(
@@ -333,7 +341,7 @@ private class DokkaDescriptorVisitor(
(descriptor.additionalExtras() + descriptor.getAnnotationsWithBackingField()
.toAdditionalExtras()).toSet().toSourceSetDependent().toAdditionalModifiers(),
descriptor.getAnnotationsWithBackingField().toSourceSetDependent().toAnnotations()
- )
+ ).let { if (isExpect || isActual) it + IsExpectActual else it }
)
}
@@ -346,6 +354,7 @@ private class DokkaDescriptorVisitor(
override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, parent: DRIWithPlatformInfo): DFunction {
val (dri, inheritedFrom) = descriptor.createDRI()
val isExpect = descriptor.isExpect
+ val isActual = descriptor.isActual
val actual = descriptor.createSources()
return DFunction(
@@ -367,11 +376,11 @@ private class DokkaDescriptorVisitor(
modifier = descriptor.modifier().toSourceSetDependent(),
type = descriptor.returnType!!.toBound(),
sourceSets = setOf(sourceSet),
- extra = PropertyContainer.withAll(
+ extra = PropertyContainer.withAll<DFunction>(
InheritedFunction(inheritedFrom.toSourceSetDependent()),
descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(),
descriptor.getAnnotations().toSourceSetDependent().toAnnotations()
- )
+ ).let { if (isExpect || isActual) it + IsExpectActual else it }
)
}
@@ -380,6 +389,7 @@ private class DokkaDescriptorVisitor(
val dri = parent.dri.copy(callable = Callable.from(descriptor, name))
val actual = descriptor.createSources()
val isExpect = descriptor.isExpect
+ val isActual = descriptor.isActual
return DFunction(
dri = dri,
@@ -418,7 +428,7 @@ private class DokkaDescriptorVisitor(
if (descriptor.isPrimary) {
it + PrimaryConstructorExtra
} else it
- }
+ }.let { if (isExpect || isActual) it + IsExpectActual else it }
)
}
@@ -443,6 +453,7 @@ private class DokkaDescriptorVisitor(
val dri = parent.copy(callable = Callable.from(descriptor))
val isGetter = descriptor is PropertyGetterDescriptor
val isExpect = descriptor.isExpect
+ val isActual = descriptor.isActual
fun PropertyDescriptor.asParameter(parent: DRI) =
DParameter(
@@ -490,10 +501,10 @@ private class DokkaDescriptorVisitor(
},
sources = descriptor.createSources(),
sourceSets = setOf(sourceSet),
- extra = PropertyContainer.withAll(
+ extra = PropertyContainer.withAll<DFunction>(
descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(),
descriptor.getAnnotations().toSourceSetDependent().toAnnotations()
- )
+ ).let { if (isExpect || isActual) it + IsExpectActual else it }
)
}
diff --git a/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt b/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt
index 3cc77f96..615412f4 100644
--- a/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt
+++ b/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt
@@ -490,7 +490,7 @@ open class DefaultPageCreator(
header(2, name, kind = kind)
table(kind, extra = extra, styles = emptySet()) {
collection
- .groupBy { it.name }
+ .groupBy { it.name } // This groupBy should probably use LocationProvider
// This hacks displaying actual typealias signatures along classlike ones
.mapValues { if (it.value.any { it is DClasslike }) it.value.filter { it !is DTypeAlias } else it.value }
.toSortedMap(compareBy(nullsLast(String.CASE_INSENSITIVE_ORDER)) { it })