aboutsummaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorVadim Mishenev <vad-mishenev@yandex.ru>2022-02-21 23:06:59 +0300
committerGitHub <noreply@github.com>2022-02-21 23:06:59 +0300
commitc44bf5487bd32f90a4576859548f1db0e9355a07 (patch)
tree2954c68d9247007ecc255d397fb207b1cb2d1be1 /plugins
parentf54597c754c9be6afb4ea374dc959dcc9fd551ce (diff)
downloaddokka-c44bf5487bd32f90a4576859548f1db0e9355a07.tar.gz
dokka-c44bf5487bd32f90a4576859548f1db0e9355a07.tar.bz2
dokka-c44bf5487bd32f90a4576859548f1db0e9355a07.zip
Add option to merge implicit expect-actual declarations (#2316)
* Add option to merge implicit expect-actual declarations * Merge entries, constructors * Fix StdLib integration test * Add doc
Diffstat (limited to 'plugins')
-rw-r--r--plugins/base/api/base.api29
-rw-r--r--plugins/base/base-test-utils/api/base-test-utils.api4
-rw-r--r--plugins/base/base-test-utils/src/main/kotlin/renderers/TestPage.kt8
-rw-r--r--plugins/base/src/main/kotlin/DokkaBaseConfiguration.kt4
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt19
-rw-r--r--plugins/base/src/main/kotlin/transformers/pages/merger/SameMethodNamePageMergerStrategy.kt8
-rw-r--r--plugins/base/src/main/kotlin/transformers/pages/samples/SamplesTransformer.kt14
-rw-r--r--plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt48
-rw-r--r--plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt519
-rw-r--r--plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt39
-rw-r--r--plugins/base/src/test/kotlin/content/functions/ContentForBriefTest.kt10
-rw-r--r--plugins/base/src/test/kotlin/content/functions/ContentForConstructors.kt2
-rw-r--r--plugins/base/src/test/kotlin/locationProvider/DokkaLocationProviderTest.kt5
-rw-r--r--plugins/base/src/test/kotlin/transformers/MergeImplicitExpectActualDeclarationsTest.kt352
-rw-r--r--plugins/javadoc/api/javadoc.api24
-rw-r--r--plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/JavadocPageCreator.kt4
-rw-r--r--plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/pages/JavadocPageNodes.kt83
-rw-r--r--plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/pages/htmlPreprocessors.kt8
-rw-r--r--plugins/mathjax/src/main/kotlin/MathjaxPlugin.kt9
19 files changed, 882 insertions, 307 deletions
diff --git a/plugins/base/api/base.api b/plugins/base/api/base.api
index b17b4052..40ee6813 100644
--- a/plugins/base/api/base.api
+++ b/plugins/base/api/base.api
@@ -68,25 +68,29 @@ public final class org/jetbrains/dokka/base/DokkaBase : org/jetbrains/dokka/plug
public final class org/jetbrains/dokka/base/DokkaBaseConfiguration : org/jetbrains/dokka/plugability/ConfigurableBlock {
public static final field Companion Lorg/jetbrains/dokka/base/DokkaBaseConfiguration$Companion;
+ public static final field mergeImplicitExpectActualDeclarationsDefault Z
public static final field separateInheritedMembersDefault Z
public fun <init> ()V
- public fun <init> (Ljava/util/List;Ljava/util/List;ZLjava/lang/String;)V
- public synthetic fun <init> (Ljava/util/List;Ljava/util/List;ZLjava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+ public fun <init> (Ljava/util/List;Ljava/util/List;ZLjava/lang/String;Z)V
+ public synthetic fun <init> (Ljava/util/List;Ljava/util/List;ZLjava/lang/String;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Ljava/util/List;
public final fun component2 ()Ljava/util/List;
public final fun component3 ()Z
public final fun component4 ()Ljava/lang/String;
- public final fun copy (Ljava/util/List;Ljava/util/List;ZLjava/lang/String;)Lorg/jetbrains/dokka/base/DokkaBaseConfiguration;
- public static synthetic fun copy$default (Lorg/jetbrains/dokka/base/DokkaBaseConfiguration;Ljava/util/List;Ljava/util/List;ZLjava/lang/String;ILjava/lang/Object;)Lorg/jetbrains/dokka/base/DokkaBaseConfiguration;
+ public final fun component5 ()Z
+ public final fun copy (Ljava/util/List;Ljava/util/List;ZLjava/lang/String;Z)Lorg/jetbrains/dokka/base/DokkaBaseConfiguration;
+ public static synthetic fun copy$default (Lorg/jetbrains/dokka/base/DokkaBaseConfiguration;Ljava/util/List;Ljava/util/List;ZLjava/lang/String;ZILjava/lang/Object;)Lorg/jetbrains/dokka/base/DokkaBaseConfiguration;
public fun equals (Ljava/lang/Object;)Z
public final fun getCustomAssets ()Ljava/util/List;
public final fun getCustomStyleSheets ()Ljava/util/List;
public final fun getFooterMessage ()Ljava/lang/String;
+ public final fun getMergeImplicitExpectActualDeclarations ()Z
public final fun getSeparateInheritedMembers ()Z
public fun hashCode ()I
public final fun setCustomAssets (Ljava/util/List;)V
public final fun setCustomStyleSheets (Ljava/util/List;)V
public final fun setFooterMessage (Ljava/lang/String;)V
+ public final fun setMergeImplicitExpectActualDeclarations (Z)V
public final fun setSeparateInheritedMembers (Z)V
public fun toString ()Ljava/lang/String;
}
@@ -1342,28 +1346,39 @@ public class org/jetbrains/dokka/base/translators/documentables/DefaultPageCreat
public fun <init> (Lorg/jetbrains/dokka/base/DokkaBaseConfiguration;Lorg/jetbrains/dokka/base/transformers/pages/comments/CommentsToContentConverter;Lorg/jetbrains/dokka/base/signatures/SignatureProvider;Lorg/jetbrains/dokka/utilities/DokkaLogger;Ljava/util/List;)V
public synthetic fun <init> (Lorg/jetbrains/dokka/base/DokkaBaseConfiguration;Lorg/jetbrains/dokka/base/transformers/pages/comments/CommentsToContentConverter;Lorg/jetbrains/dokka/base/signatures/SignatureProvider;Lorg/jetbrains/dokka/utilities/DokkaLogger;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
protected fun contentForBrief (Lorg/jetbrains/dokka/base/translators/documentables/PageContentBuilder$DocumentableContentBuilder;Lorg/jetbrains/dokka/model/Documentable;)V
- protected fun contentForClasslike (Lorg/jetbrains/dokka/model/DClasslike;)Lorg/jetbrains/dokka/pages/ContentGroup;
+ protected fun contentForClasslikesAndEntries (Ljava/util/List;)Lorg/jetbrains/dokka/pages/ContentGroup;
+ protected fun contentForComments (Ljava/util/List;Z)Ljava/util/List;
+ protected fun contentForComments (Lorg/jetbrains/dokka/links/DRI;Ljava/util/Set;Ljava/util/Map;Z)Ljava/util/List;
protected fun contentForComments (Lorg/jetbrains/dokka/model/Documentable;Z)Ljava/util/List;
+ public static synthetic fun contentForComments$default (Lorg/jetbrains/dokka/base/translators/documentables/DefaultPageCreator;Ljava/util/List;ZILjava/lang/Object;)Ljava/util/List;
+ public static synthetic fun contentForComments$default (Lorg/jetbrains/dokka/base/translators/documentables/DefaultPageCreator;Lorg/jetbrains/dokka/links/DRI;Ljava/util/Set;Ljava/util/Map;ZILjava/lang/Object;)Ljava/util/List;
public static synthetic fun contentForComments$default (Lorg/jetbrains/dokka/base/translators/documentables/DefaultPageCreator;Lorg/jetbrains/dokka/model/Documentable;ZILjava/lang/Object;)Ljava/util/List;
protected fun contentForDescription (Lorg/jetbrains/dokka/model/Documentable;)Ljava/util/List;
- protected fun contentForEnumEntry (Lorg/jetbrains/dokka/model/DEnumEntry;)Lorg/jetbrains/dokka/pages/ContentGroup;
protected fun contentForFunction (Lorg/jetbrains/dokka/model/DFunction;)Lorg/jetbrains/dokka/pages/ContentGroup;
protected fun contentForMember (Lorg/jetbrains/dokka/model/Documentable;)Lorg/jetbrains/dokka/pages/ContentGroup;
+ protected fun contentForMembers (Ljava/util/List;)Lorg/jetbrains/dokka/pages/ContentGroup;
protected fun contentForModule (Lorg/jetbrains/dokka/model/DModule;)Lorg/jetbrains/dokka/pages/ContentGroup;
protected fun contentForPackage (Lorg/jetbrains/dokka/model/DPackage;)Lorg/jetbrains/dokka/pages/ContentGroup;
protected fun contentForProperty (Lorg/jetbrains/dokka/model/DProperty;)Lorg/jetbrains/dokka/pages/ContentGroup;
+ protected fun contentForScope (Ljava/util/Set;Ljava/util/Set;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/Map;)Lorg/jetbrains/dokka/pages/ContentGroup;
protected fun contentForScope (Lorg/jetbrains/dokka/model/WithScope;Lorg/jetbrains/dokka/links/DRI;Ljava/util/Set;)Lorg/jetbrains/dokka/pages/ContentGroup;
+ protected fun contentForScopes (Ljava/util/List;Ljava/util/Set;)Lorg/jetbrains/dokka/pages/ContentGroup;
protected fun divergentBlock (Lorg/jetbrains/dokka/base/translators/documentables/PageContentBuilder$DocumentableContentBuilder;Ljava/lang/String;Ljava/util/Collection;Lorg/jetbrains/dokka/pages/ContentKind;Lorg/jetbrains/dokka/model/properties/PropertyContainer;)V
public static synthetic fun divergentBlock$default (Lorg/jetbrains/dokka/base/translators/documentables/DefaultPageCreator;Lorg/jetbrains/dokka/base/translators/documentables/PageContentBuilder$DocumentableContentBuilder;Ljava/lang/String;Ljava/util/Collection;Lorg/jetbrains/dokka/pages/ContentKind;Lorg/jetbrains/dokka/model/properties/PropertyContainer;ILjava/lang/Object;)V
protected fun getContentBuilder ()Lorg/jetbrains/dokka/base/translators/documentables/PageContentBuilder;
public final fun getCustomTagContentProviders ()Ljava/util/List;
public final fun getLogger ()Lorg/jetbrains/dokka/utilities/DokkaLogger;
+ protected final fun getMergeImplicitExpectActualDeclarations ()Z
protected final fun getSeparateInheritedMembers ()Z
public fun pageForClasslike (Lorg/jetbrains/dokka/model/DClasslike;)Lorg/jetbrains/dokka/pages/ClasslikePageNode;
+ public fun pageForClasslikes (Ljava/util/List;)Lorg/jetbrains/dokka/pages/ClasslikePageNode;
+ public fun pageForEnumEntries (Ljava/util/List;)Lorg/jetbrains/dokka/pages/ClasslikePageNode;
public fun pageForEnumEntry (Lorg/jetbrains/dokka/model/DEnumEntry;)Lorg/jetbrains/dokka/pages/ClasslikePageNode;
public fun pageForFunction (Lorg/jetbrains/dokka/model/DFunction;)Lorg/jetbrains/dokka/pages/MemberPageNode;
+ public fun pageForFunctions (Ljava/util/List;)Lorg/jetbrains/dokka/pages/MemberPageNode;
public fun pageForModule (Lorg/jetbrains/dokka/model/DModule;)Lorg/jetbrains/dokka/pages/ModulePageNode;
public fun pageForPackage (Lorg/jetbrains/dokka/model/DPackage;)Lorg/jetbrains/dokka/pages/PackagePageNode;
+ public fun pageForProperties (Ljava/util/List;)Lorg/jetbrains/dokka/pages/MemberPageNode;
public fun pageForProperty (Lorg/jetbrains/dokka/model/DProperty;)Lorg/jetbrains/dokka/pages/MemberPageNode;
protected fun toHeaderString (Lorg/jetbrains/dokka/model/doc/TagWrapper;)Ljava/lang/String;
}
@@ -1462,6 +1477,8 @@ public class org/jetbrains/dokka/base/translators/documentables/PageContentBuild
public static synthetic fun linkNode$default (Lorg/jetbrains/dokka/base/translators/documentables/PageContentBuilder$DocumentableContentBuilder;Ljava/lang/String;Lorg/jetbrains/dokka/links/DRI;Lorg/jetbrains/dokka/pages/DCI;Ljava/util/Set;Ljava/util/Set;Lorg/jetbrains/dokka/model/properties/PropertyContainer;ILjava/lang/Object;)Lorg/jetbrains/dokka/pages/ContentDRILink;
public final fun list (Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;Lkotlin/jvm/functions/Function2;)V
public static synthetic fun list$default (Lorg/jetbrains/dokka/base/translators/documentables/PageContentBuilder$DocumentableContentBuilder;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V
+ public final fun multiBlock (Ljava/lang/String;ILorg/jetbrains/dokka/pages/Kind;Ljava/lang/Iterable;Ljava/util/Set;Ljava/util/Set;Lorg/jetbrains/dokka/model/properties/PropertyContainer;ZZLjava/util/List;ZLkotlin/jvm/functions/Function3;)V
+ public static synthetic fun multiBlock$default (Lorg/jetbrains/dokka/base/translators/documentables/PageContentBuilder$DocumentableContentBuilder;Ljava/lang/String;ILorg/jetbrains/dokka/pages/Kind;Ljava/lang/Iterable;Ljava/util/Set;Ljava/util/Set;Lorg/jetbrains/dokka/model/properties/PropertyContainer;ZZLjava/util/List;ZLkotlin/jvm/functions/Function3;ILjava/lang/Object;)V
public final fun operator (Ljava/lang/String;)V
public final fun orderedList (Lorg/jetbrains/dokka/pages/Kind;Ljava/util/Set;Ljava/util/Set;Lorg/jetbrains/dokka/model/properties/PropertyContainer;Lkotlin/jvm/functions/Function1;)V
public static synthetic fun orderedList$default (Lorg/jetbrains/dokka/base/translators/documentables/PageContentBuilder$DocumentableContentBuilder;Lorg/jetbrains/dokka/pages/Kind;Ljava/util/Set;Ljava/util/Set;Lorg/jetbrains/dokka/model/properties/PropertyContainer;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
diff --git a/plugins/base/base-test-utils/api/base-test-utils.api b/plugins/base/base-test-utils/api/base-test-utils.api
index b6ec84a1..a0b535f2 100644
--- a/plugins/base/base-test-utils/api/base-test-utils.api
+++ b/plugins/base/base-test-utils/api/base-test-utils.api
@@ -62,8 +62,8 @@ public final class org/jetbrains/dokka/base/testApi/testRunner/BaseTestMethods :
}
public final class renderers/RawTestPage : org/jetbrains/dokka/pages/RootPageNode, org/jetbrains/dokka/pages/ContentPage {
- public fun <init> (Lorg/jetbrains/dokka/pages/ContentNode;Ljava/lang/String;Ljava/util/Set;Lorg/jetbrains/dokka/model/Documentable;Ljava/util/List;Ljava/util/List;)V
- public synthetic fun <init> (Lorg/jetbrains/dokka/pages/ContentNode;Ljava/lang/String;Ljava/util/Set;Lorg/jetbrains/dokka/model/Documentable;Ljava/util/List;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+ public fun <init> (Lorg/jetbrains/dokka/pages/ContentNode;Ljava/lang/String;Ljava/util/Set;Ljava/util/List;Ljava/util/List;)V
+ public synthetic fun <init> (Lorg/jetbrains/dokka/pages/ContentNode;Ljava/lang/String;Ljava/util/Set;Ljava/util/List;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun getChildren ()Ljava/util/List;
public fun getContent ()Lorg/jetbrains/dokka/pages/ContentNode;
public fun getDocumentable ()Lorg/jetbrains/dokka/model/Documentable;
diff --git a/plugins/base/base-test-utils/src/main/kotlin/renderers/TestPage.kt b/plugins/base/base-test-utils/src/main/kotlin/renderers/TestPage.kt
index 67ba2dd3..4066c7c6 100644
--- a/plugins/base/base-test-utils/src/main/kotlin/renderers/TestPage.kt
+++ b/plugins/base/base-test-utils/src/main/kotlin/renderers/TestPage.kt
@@ -1,15 +1,14 @@
package renderers
import org.jetbrains.dokka.DokkaConfiguration
+import org.jetbrains.dokka.base.signatures.KotlinSignatureProvider
+import org.jetbrains.dokka.base.transformers.pages.comments.CommentsToContentConverter
+import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder
import org.jetbrains.dokka.links.DRI
-import org.jetbrains.dokka.model.Documentable
import org.jetbrains.dokka.model.doc.DocTag
import org.jetbrains.dokka.model.properties.PropertyContainer
import org.jetbrains.dokka.pages.*
import org.jetbrains.dokka.utilities.DokkaConsoleLogger
-import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder
-import org.jetbrains.dokka.base.signatures.KotlinSignatureProvider
-import org.jetbrains.dokka.base.transformers.pages.comments.CommentsToContentConverter
fun testPage(callback: PageContentBuilder.DocumentableContentBuilder.() -> Unit): RawTestPage {
val content = PageContentBuilder(
@@ -29,7 +28,6 @@ class RawTestPage(
override val content: ContentNode,
override val name: String = "testPage",
override val dri: Set<DRI> = setOf(DRI.topLevel),
- override val documentable: Documentable? = null,
override val embeddedResources: List<String> = emptyList(),
override val children: List<PageNode> = emptyList(),
): RootPageNode(), ContentPage {
diff --git a/plugins/base/src/main/kotlin/DokkaBaseConfiguration.kt b/plugins/base/src/main/kotlin/DokkaBaseConfiguration.kt
index 21757d70..8ea8818d 100644
--- a/plugins/base/src/main/kotlin/DokkaBaseConfiguration.kt
+++ b/plugins/base/src/main/kotlin/DokkaBaseConfiguration.kt
@@ -8,12 +8,14 @@ data class DokkaBaseConfiguration(
var customStyleSheets: List<File> = defaultCustomStyleSheets,
var customAssets: List<File> = defaultCustomAssets,
var separateInheritedMembers: Boolean = separateInheritedMembersDefault,
- var footerMessage: String = defaultFooterMessage
+ var footerMessage: String = defaultFooterMessage,
+ var mergeImplicitExpectActualDeclarations: Boolean = mergeImplicitExpectActualDeclarationsDefault
) : ConfigurableBlock {
companion object {
val defaultFooterMessage = "© ${Year.now().value} Copyright"
val defaultCustomStyleSheets: List<File> = emptyList()
val defaultCustomAssets: List<File> = emptyList()
const val separateInheritedMembersDefault: Boolean = false
+ const val mergeImplicitExpectActualDeclarationsDefault: Boolean = false
}
} \ No newline at end of file
diff --git a/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt b/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt
index 43526dc3..3297d09f 100644
--- a/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt
+++ b/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt
@@ -1,14 +1,14 @@
package org.jetbrains.dokka.base.renderers.html
-import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import org.jetbrains.dokka.base.DokkaBase
import org.jetbrains.dokka.base.DokkaBaseConfiguration
import org.jetbrains.dokka.base.renderers.sourceSets
-import org.jetbrains.dokka.base.templating.AddToSearch
import org.jetbrains.dokka.base.templating.AddToSourcesetDependencies
import org.jetbrains.dokka.base.templating.toJsonString
-import org.jetbrains.dokka.links.DRI
-import org.jetbrains.dokka.model.*
+import org.jetbrains.dokka.model.DEnum
+import org.jetbrains.dokka.model.DEnumEntry
+import org.jetbrains.dokka.model.DFunction
+import org.jetbrains.dokka.model.withDescendants
import org.jetbrains.dokka.pages.*
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.plugability.configuration
@@ -30,19 +30,18 @@ abstract class NavigationDataProvider {
when {
this !is ClasslikePageNode ->
children.filterIsInstance<ContentPage>().map { visit(it) }
- documentable is DEnum ->
- children.filter { it is ContentPage && it.documentable is DEnumEntry }.map { visit(it as ContentPage) }
+ documentables.any { it is DEnum } ->
+ children.filter { it is WithDocumentables && it.documentables.any { it is DEnumEntry } }
+ .map { visit(it as ContentPage) }
else -> emptyList()
}.sortedBy { it.name.toLowerCase() }
/**
- * Parenthesis is applied in 2 cases:
+ * Parenthesis is applied in 1 case:
* - page only contains functions (therefore documentable from this page is [DFunction])
- * - page merges only functions (documentable is null because [SameMethodNamePageMergerStrategy][org.jetbrains.dokka.base.transformers.pages.merger.SameMethodNamePageMergerStrategy]
- * removes it from page)
*/
private val ContentPage.displayableName: String
- get() = if (documentable is DFunction || (documentable == null && dri.all { it.callable != null })) {
+ get() = if (this is WithDocumentables && documentables.all { it is DFunction }) {
"$name()"
} else {
name
diff --git a/plugins/base/src/main/kotlin/transformers/pages/merger/SameMethodNamePageMergerStrategy.kt b/plugins/base/src/main/kotlin/transformers/pages/merger/SameMethodNamePageMergerStrategy.kt
index 2fb70fc8..6c12c719 100644
--- a/plugins/base/src/main/kotlin/transformers/pages/merger/SameMethodNamePageMergerStrategy.kt
+++ b/plugins/base/src/main/kotlin/transformers/pages/merger/SameMethodNamePageMergerStrategy.kt
@@ -23,7 +23,7 @@ class SameMethodNamePageMergerStrategy(val logger: DokkaLogger) : PageMergerStra
children = members.flatMap { it.children }.distinct(),
content = squashDivergentInstances(members).withSourceSets(members.allSourceSets()),
embeddedResources = members.flatMap { it.embeddedResources }.distinct(),
- documentable = null
+ documentables = members.flatMap { it.documentables }
)
return (pages - members) + listOf(merged)
@@ -37,9 +37,9 @@ class SameMethodNamePageMergerStrategy(val logger: DokkaLogger) : PageMergerStra
.reduce { acc, node ->
acc.mapTransform<ContentDivergentGroup, ContentNode> { g ->
g.copy(children = (g.children +
- (node.dfs { it is ContentDivergentGroup && it.groupID == g.groupID } as? ContentDivergentGroup)
- ?.children?.single()
- ).filterNotNull()
+ ((node.dfs { it is ContentDivergentGroup && it.groupID == g.groupID } as? ContentDivergentGroup)
+ ?.children ?: emptyList())
+ )
)
}
}
diff --git a/plugins/base/src/main/kotlin/transformers/pages/samples/SamplesTransformer.kt b/plugins/base/src/main/kotlin/transformers/pages/samples/SamplesTransformer.kt
index 3ff7a77d..db133bb8 100644
--- a/plugins/base/src/main/kotlin/transformers/pages/samples/SamplesTransformer.kt
+++ b/plugins/base/src/main/kotlin/transformers/pages/samples/SamplesTransformer.kt
@@ -35,14 +35,18 @@ abstract class SamplesTransformer(val context: DokkaContext) : PageTransformer {
"<script src=\"https://unpkg.com/kotlin-playground@1\"></script>"
return input.transformContentPagesTree { page ->
- page.documentable?.documentation?.entries?.fold(page) { acc, entry ->
- entry.value.children.filterIsInstance<Sample>().fold(acc) { acc, sample ->
+ val samples = (page as? WithDocumentables)?.documentables?.flatMap {
+ it.documentation.entries.flatMap { entry ->
+ entry.value.children.filterIsInstance<Sample>().map { entry.key to it }
+ }
+ }
+
+ samples?.fold(page as ContentPage) { acc, (sampleSourceSet, sample) ->
acc.modified(
- content = acc.content.addSample(page, entry.key, sample.name, analysis),
+ content = acc.content.addSample(page, sampleSourceSet, sample.name, analysis),
embeddedResources = acc.embeddedResources + kotlinPlaygroundScript
)
- }
- } ?: page
+ } ?: page
}
}
diff --git a/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt b/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt
index f66ff222..93305055 100644
--- a/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt
+++ b/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt
@@ -1,15 +1,15 @@
package org.jetbrains.dokka.base.transformers.pages.sourcelinks
-import com.intellij.psi.PsiElement
import com.intellij.psi.PsiDocumentManager
+import com.intellij.psi.PsiElement
import org.jetbrains.dokka.DokkaConfiguration
-import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder
-import org.jetbrains.dokka.model.DocumentableSource
import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet
import org.jetbrains.dokka.analysis.DescriptorDocumentableSource
import org.jetbrains.dokka.analysis.PsiDocumentableSource
import org.jetbrains.dokka.base.DokkaBase
import org.jetbrains.dokka.base.resolvers.anchors.SymbolAnchorHint
+import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder
+import org.jetbrains.dokka.model.DocumentableSource
import org.jetbrains.dokka.model.WithSources
import org.jetbrains.dokka.model.toDisplaySourceSets
import org.jetbrains.dokka.pages.*
@@ -32,8 +32,9 @@ class SourceLinksTransformer(val context: DokkaContext) : PageTransformer {
override fun invoke(input: RootPageNode) =
input.transformContentPagesTree { node ->
- when (val documentable = node.documentable) {
- is WithSources -> resolveSources(documentable)
+ when (node) {
+ is WithDocumentables ->
+ node.documentables.filterIsInstance<WithSources>().flatMap { resolveSources(it) }
.takeIf { it.isNotEmpty() }
?.let { node.addSourcesContent(it) }
?: node
@@ -65,23 +66,26 @@ class SourceLinksTransformer(val context: DokkaContext) : PageTransformer {
private fun PageContentBuilder.buildSourcesContent(
node: ContentPage,
sources: List<Pair<DokkaSourceSet, String>>
- ) = contentFor(
- node.dri.first(),
- node.documentable!!.sourceSets.toSet()
- ) {
- header(2, "Sources", kind = ContentKind.Source)
- +ContentTable(
- header = emptyList(),
- children = sources.map {
- buildGroup(node.dri, setOf(it.first), kind = ContentKind.Source, extra = mainExtra + SymbolAnchorHint(it.second, ContentKind.Source)) {
- link("${it.first.displayName} source", it.second)
- }
- },
- dci = DCI(node.dri, ContentKind.Source),
- sourceSets = node.documentable!!.sourceSets.toDisplaySourceSets(),
- style = emptySet(),
- extra = mainExtra + SimpleAttr.header("Sources")
- )
+ ): ContentGroup {
+ val documentables = (node as? WithDocumentables)?.documentables.orEmpty()
+ return contentFor(
+ node.dri,
+ documentables.flatMap { it.sourceSets }.toSet()
+ ) {
+ header(2, "Sources", kind = ContentKind.Source)
+ +ContentTable(
+ header = emptyList(),
+ children = sources.map {
+ buildGroup(node.dri, setOf(it.first), kind = ContentKind.Source, extra = mainExtra + SymbolAnchorHint(it.second, ContentKind.Source)) {
+ link("${it.first.displayName} source", it.second)
+ }
+ },
+ dci = DCI(node.dri, ContentKind.Source),
+ sourceSets = documentables.flatMap { it.sourceSets }.toDisplaySourceSets(),
+ style = emptySet(),
+ extra = mainExtra + SimpleAttr.header("Sources")
+ )
+ }
}
private fun DocumentableSource.toLink(sourceLink: SourceLink): String {
diff --git a/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt b/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt
index e2aca6f9..c5136c27 100644
--- a/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt
+++ b/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt
@@ -1,9 +1,14 @@
package org.jetbrains.dokka.base.translators.documentables
+import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet
+import org.jetbrains.dokka.base.DokkaBaseConfiguration
+import org.jetbrains.dokka.base.resolvers.anchors.SymbolAnchorHint
import org.jetbrains.dokka.base.signatures.SignatureProvider
import org.jetbrains.dokka.base.transformers.documentables.CallableExtensions
+import org.jetbrains.dokka.base.transformers.documentables.ClashingDriIdentifier
import org.jetbrains.dokka.base.transformers.documentables.InheritorsInfo
import org.jetbrains.dokka.base.transformers.pages.comments.CommentsToContentConverter
+import org.jetbrains.dokka.base.transformers.pages.tags.CustomTagContentProvider
import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder.DocumentableContentBuilder
import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.model.*
@@ -15,11 +20,6 @@ import org.jetbrains.dokka.utilities.DokkaLogger
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import kotlin.reflect.KClass
import kotlin.reflect.full.isSubclassOf
-import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet
-import org.jetbrains.dokka.base.DokkaBaseConfiguration
-import org.jetbrains.dokka.base.resolvers.anchors.SymbolAnchorHint
-import org.jetbrains.dokka.base.transformers.documentables.ClashingDriIdentifier
-import org.jetbrains.dokka.base.transformers.pages.tags.CustomTagContentProvider
private typealias GroupedTags = Map<KClass<out TagWrapper>, List<Pair<DokkaSourceSet?, TagWrapper>>>
@@ -35,66 +35,139 @@ open class DefaultPageCreator(
) {
protected open val contentBuilder = PageContentBuilder(commentsToContentConverter, signatureProvider, logger)
+ protected val mergeImplicitExpectActualDeclarations =
+ configuration?.mergeImplicitExpectActualDeclarations
+ ?: DokkaBaseConfiguration.mergeImplicitExpectActualDeclarationsDefault
+
protected val separateInheritedMembers =
configuration?.separateInheritedMembers ?: DokkaBaseConfiguration.separateInheritedMembersDefault
- open fun pageForModule(m: DModule) =
- ModulePageNode(m.name.ifEmpty { "<root>" }, contentForModule(m), m, m.packages.map(::pageForPackage))
+ open fun pageForModule(m: DModule): ModulePageNode =
+ ModulePageNode(m.name.ifEmpty { "<root>" }, contentForModule(m), listOf(m), m.packages.map(::pageForPackage))
open fun pageForPackage(p: DPackage): PackagePageNode = PackagePageNode(
- p.name, contentForPackage(p), setOf(p.dri), p,
- p.classlikes.renameClashingDocumentable().map(::pageForClasslike) +
- p.functions.renameClashingDocumentable()
- .map(::pageForFunction) + p.properties.mapNotNull(::pageForProperty)
+ p.name, contentForPackage(p), setOf(p.dri), listOf(p),
+ if (mergeImplicitExpectActualDeclarations)
+ p.classlikes.mergeClashingDocumentable().map(::pageForClasslikes) +
+ p.functions.mergeClashingDocumentable().map(::pageForFunctions) +
+ p.properties.mergeClashingDocumentable().map(::pageForProperties)
+ else
+ p.classlikes.renameClashingDocumentable().map(::pageForClasslike) +
+ p.functions.renameClashingDocumentable().map(::pageForFunction) +
+ p.properties.mapNotNull(::pageForProperty)
)
- open fun pageForEnumEntry(e: DEnumEntry): ClasslikePageNode =
- ClasslikePageNode(
- e.nameAfterClash(), contentForEnumEntry(e), setOf(e.dri), e,
- e.classlikes.renameClashingDocumentable().map(::pageForClasslike) +
- e.filteredFunctions.renameClashingDocumentable().map(::pageForFunction) +
- e.filteredProperties.renameClashingDocumentable().mapNotNull(::pageForProperty)
- )
+ open fun pageForEnumEntry(e: DEnumEntry): ClasslikePageNode = pageForEnumEntries(listOf(e))
- open fun pageForClasslike(c: DClasslike): ClasslikePageNode {
- val constructors = if (c is WithConstructors) c.constructors else emptyList()
+ open fun pageForClasslike(c: DClasslike): ClasslikePageNode = pageForClasslikes(listOf(c))
+
+ open fun pageForEnumEntries(documentables: List<DEnumEntry>): ClasslikePageNode {
+ val dri = documentables.dri.also {
+ if (it.size != 1) {
+ logger.error("Documentable dri should have the same one ${it.first()} inside the one page!")
+ }
+ }
+
+ val classlikes = documentables.flatMap { it.classlikes }
+ val functions = documentables.flatMap { it.filteredFunctions }
+ val props = documentables.flatMap { it.filteredProperties }
+
+ val childrenPages = if (mergeImplicitExpectActualDeclarations)
+ functions.mergeClashingDocumentable().map(::pageForFunctions) +
+ props.mergeClashingDocumentable().map(::pageForProperties)
+ else
+ classlikes.renameClashingDocumentable().map(::pageForClasslike) +
+ functions.renameClashingDocumentable().map(::pageForFunction) +
+ props.renameClashingDocumentable().mapNotNull(::pageForProperty)
return ClasslikePageNode(
- c.nameAfterClash(), contentForClasslike(c), setOf(c.dri), c,
- constructors.map(::pageForFunction) +
- c.classlikes.renameClashingDocumentable().map(::pageForClasslike) +
- c.filteredFunctions.renameClashingDocumentable().map(::pageForFunction) +
- c.filteredProperties.renameClashingDocumentable().mapNotNull(::pageForProperty) +
- if (c is DEnum) c.entries.map(::pageForEnumEntry) else emptyList()
+ documentables.first().nameAfterClash(), contentForClasslikesAndEntries(documentables), dri, documentables,
+ childrenPages
+ )
+ }
+
+ open fun pageForClasslikes(documentables: List<DClasslike>): ClasslikePageNode {
+ val dri = documentables.dri.also {
+ if (it.size != 1) {
+ logger.error("Documentable dri should have the same one ${it.first()} inside the one page!")
+ }
+ }
+
+ val constructors = documentables.flatMap { if (it is WithConstructors) it.constructors else emptyList() }
+
+ val classlikes = documentables.flatMap { it.classlikes }
+ val functions = documentables.flatMap { it.filteredFunctions }
+ val props = documentables.flatMap { it.filteredProperties }
+ val entries = documentables.flatMap { if (it is DEnum) it.entries else emptyList() }
+
+ val childrenPages = constructors.map(::pageForFunction) +
+ if (mergeImplicitExpectActualDeclarations)
+ classlikes.mergeClashingDocumentable().map(::pageForClasslikes) +
+ functions.mergeClashingDocumentable().map(::pageForFunctions) +
+ props.mergeClashingDocumentable().map(::pageForProperties) +
+ entries.mergeClashingDocumentable().map(::pageForEnumEntries)
+ else
+ classlikes.renameClashingDocumentable().map(::pageForClasslike) +
+ functions.renameClashingDocumentable().map(::pageForFunction) +
+ props.renameClashingDocumentable().mapNotNull(::pageForProperty) +
+ entries.renameClashingDocumentable().map(::pageForEnumEntry)
+
+ return ClasslikePageNode(
+ documentables.first().nameAfterClash(), contentForClasslikesAndEntries(documentables), dri, documentables,
+ childrenPages
)
}
private fun <T> T.toClashedName() where T : Documentable, T : WithExtraProperties<T> =
(extra[ClashingDriIdentifier]?.value?.joinToString(", ", "[", "]") { it.displayName } ?: "") + name.orEmpty()
- @Suppress("UNCHECKED_CAST")
private fun <T : Documentable> List<T>.renameClashingDocumentable(): List<T> =
groupBy { it.dri }.values.flatMap { elements ->
if (elements.size == 1) elements else elements.mapNotNull { element ->
- when (element) {
- is DClass -> element.copy(extra = element.extra + DriClashAwareName(element.toClashedName()))
- is DObject -> element.copy(extra = element.extra + DriClashAwareName(element.toClashedName()))
- is DAnnotation -> element.copy(extra = element.extra + DriClashAwareName(element.toClashedName()))
- is DInterface -> element.copy(extra = element.extra + DriClashAwareName(element.toClashedName()))
- is DEnum -> element.copy(extra = element.extra + DriClashAwareName(element.toClashedName()))
- is DFunction -> element.copy(extra = element.extra + DriClashAwareName(element.toClashedName()))
- is DProperty -> element.copy(extra = element.extra + DriClashAwareName(element.toClashedName()))
- is DTypeAlias -> element.copy(extra = element.extra + DriClashAwareName(element.toClashedName()))
- else -> null
- } as? T?
+ element.renameClashingDocumentable()
}
}
- open fun pageForFunction(f: DFunction) = MemberPageNode(f.nameAfterClash(), contentForFunction(f), setOf(f.dri), f)
+ @Suppress("UNCHECKED_CAST")
+ private fun <T : Documentable> T.renameClashingDocumentable(): T? = when (this) {
+ is DClass -> copy(extra = this.extra + DriClashAwareName(this.toClashedName()))
+ is DObject -> copy(extra = this.extra + DriClashAwareName(this.toClashedName()))
+ is DAnnotation -> copy(extra = this.extra + DriClashAwareName(this.toClashedName()))
+ is DInterface -> copy(extra = this.extra + DriClashAwareName(this.toClashedName()))
+ is DEnum -> copy(extra = this.extra + DriClashAwareName(this.toClashedName()))
+ is DFunction -> copy(extra = this.extra + DriClashAwareName(this.toClashedName()))
+ is DProperty -> copy(extra = this.extra + DriClashAwareName(this.toClashedName()))
+ is DTypeAlias -> copy(extra = this.extra + DriClashAwareName(this.toClashedName()))
+ else -> null
+ } as? T?
+
+ private fun <T : Documentable> List<T>.mergeClashingDocumentable(): List<List<T>> =
+ groupBy { it.dri }.values.toList()
+
+ open fun pageForFunction(f: DFunction) =
+ MemberPageNode(f.nameAfterClash(), contentForFunction(f), setOf(f.dri), listOf(f))
+
+ open fun pageForFunctions(fs: List<DFunction>): MemberPageNode {
+ val dri = fs.dri.also {
+ if (it.size != 1) {
+ logger.error("Function dri should have the same one ${it.first()} inside the one page!")
+ }
+ }
+ return MemberPageNode(fs.first().nameAfterClash(), contentForMembers(fs), dri, fs)
+ }
open fun pageForProperty(p: DProperty): MemberPageNode? =
- MemberPageNode(p.nameAfterClash(), contentForProperty(p), setOf(p.dri), p)
+ MemberPageNode(p.nameAfterClash(), contentForProperty(p), setOf(p.dri), listOf(p))
+
+ open fun pageForProperties(ps: List<DProperty>): MemberPageNode {
+ val dri = ps.dri.also {
+ if (it.size != 1) {
+ logger.error("Property dri should have the same one ${it.first()} inside the one page!")
+ }
+ }
+ return MemberPageNode(ps.first().nameAfterClash(), contentForMembers(ps), dri, ps)
+ }
private fun <T> T.isInherited(): Boolean where T : Documentable, T : WithExtraProperties<T> =
sourceSets.all { sourceSet -> extra[InheritedMember]?.isInherited(sourceSet) == true }
@@ -168,148 +241,193 @@ open class DefaultPageCreator(
}
}
+ protected open fun contentForScopes(
+ scopes: List<WithScope>,
+ sourceSets: Set<DokkaSourceSet>
+ ): ContentGroup {
+ val types = scopes.flatMap { it.classlikes } + scopes.filterIsInstance<DPackage>().flatMap { it.typealiases }
+ val inheritors = scopes.fold(mutableMapOf<DokkaSourceSet, List<DRI>>()) { acc, scope ->
+ val inheritorsForScope =
+ scope.safeAs<WithExtraProperties<Documentable>>()?.let { it.extra[InheritorsInfo] }?.let { inheritors ->
+ inheritors.value.filter { it.value.isNotEmpty() }
+ }.orEmpty()
+ inheritorsForScope.forEach { (k, v) ->
+ acc.compute(k) { _, value -> value?.plus(v) ?: v }
+ }
+ acc
+ }
+
+ return contentForScope(
+ @Suppress("UNCHECKED_CAST")
+ (scopes as List<Documentable>).dri,
+ sourceSets,
+ types,
+ scopes.flatMap { it.functions },
+ scopes.flatMap { it.properties },
+ inheritors
+ )
+ }
+
protected open fun contentForScope(
s: WithScope,
dri: DRI,
sourceSets: Set<DokkaSourceSet>
- ) = contentBuilder.contentFor(s as Documentable) {
+ ): ContentGroup {
val types = listOf(
s.classlikes,
(s as? DPackage)?.typealiases ?: emptyList()
).flatten()
+ val inheritors =
+ s.safeAs<WithExtraProperties<Documentable>>()?.let { it.extra[InheritorsInfo] }?.let { inheritors ->
+ inheritors.value.filter { it.value.isNotEmpty() }
+ }.orEmpty()
+
+ return contentForScope(setOf(dri), sourceSets, types, s.functions, s.properties, inheritors)
+ }
+
+ protected open fun contentForScope(
+ dri: Set<DRI>,
+ sourceSets: Set<DokkaSourceSet>,
+ types: List<Documentable>,
+ functions: List<DFunction>,
+ properties: List<DProperty>,
+ inheritors: SourceSetDependent<List<DRI>>
+ ) = contentBuilder.contentFor(dri, sourceSets) {
divergentBlock("Types", types, ContentKind.Classlikes, extra = mainExtra + SimpleAttr.header("Types"))
if (separateInheritedMembers) {
- val (inheritedFunctions, memberFunctions) = s.functions.splitInherited()
- val (inheritedProperties, memberProperties) = s.properties.splitInherited()
+ val (inheritedFunctions, memberFunctions) = functions.splitInherited()
+ val (inheritedProperties, memberProperties) = properties.splitInherited()
propertiesBlock("Properties", memberProperties, sourceSets)
propertiesBlock("Inherited properties", inheritedProperties, sourceSets)
functionsBlock("Functions", memberFunctions)
functionsBlock("Inherited functions", inheritedFunctions)
} else {
- functionsBlock("Functions", s.functions)
- propertiesBlock("Properties", s.properties, sourceSets)
+ functionsBlock("Functions", functions)
+ propertiesBlock("Properties", properties, sourceSets)
}
- s.safeAs<WithExtraProperties<Documentable>>()?.let { it.extra[InheritorsInfo] }?.let { inheritors ->
- val map = inheritors.value.filter { it.value.isNotEmpty() }
- if (map.values.any()) {
- header(2, "Inheritors") { }
- +ContentTable(
- header = listOf(contentBuilder.contentFor(mainDRI, mainSourcesetData) {
- text("Name")
- }),
- children = map.entries.flatMap { entry -> entry.value.map { Pair(entry.key, it) } }
- .groupBy({ it.second }, { it.first }).map { (classlike, platforms) ->
- val label = classlike.classNames?.substringAfterLast(".") ?: classlike.toString()
- .also { logger.warn("No class name found for DRI $classlike") }
- buildGroup(
- setOf(classlike),
- platforms.toSet(),
- ContentKind.Inheritors,
- extra = mainExtra + SymbolAnchorHint(label, ContentKind.Inheritors)
- ) {
- link(label, classlike)
- }
- },
- dci = DCI(setOf(dri), ContentKind.Inheritors),
- sourceSets = sourceSets.toDisplaySourceSets(),
- style = emptySet(),
- extra = mainExtra + SimpleAttr.header("Inheritors")
- )
- }
+ if (inheritors.values.any()) {
+ header(2, "Inheritors") { }
+ +ContentTable(
+ header = listOf(contentBuilder.contentFor(mainDRI, mainSourcesetData) {
+ text("Name")
+ }),
+ children = inheritors.entries.flatMap { entry -> entry.value.map { Pair(entry.key, it) } }
+ .groupBy({ it.second }, { it.first }).map { (classlike, platforms) ->
+ val label = classlike.classNames?.substringAfterLast(".") ?: classlike.toString()
+ .also { logger.warn("No class name found for DRI $classlike") }
+ buildGroup(
+ setOf(classlike),
+ platforms.toSet(),
+ ContentKind.Inheritors,
+ extra = mainExtra + SymbolAnchorHint(label, ContentKind.Inheritors)
+ ) {
+ link(label, classlike)
+ }
+ },
+ dci = DCI(dri, ContentKind.Inheritors),
+ sourceSets = sourceSets.toDisplaySourceSets(),
+ style = emptySet(),
+ extra = mainExtra + SimpleAttr.header("Inheritors")
+ )
}
}
private fun Iterable<DFunction>.sorted() =
sortedWith(compareBy({ it.name }, { it.parameters.size }, { it.dri.toString() }))
- protected open fun contentForEnumEntry(e: DEnumEntry) = contentBuilder.contentFor(e) {
- group(kind = ContentKind.Cover) {
- cover(e.name)
- sourceSetDependentHint(e.dri, e.sourceSets.toSet()) {
- +buildSignature(e)
- +contentForDescription(e)
- }
- }
- group(styles = setOf(ContentStyle.TabbedContent)) {
- +contentForComments(e)
- +contentForScope(e, e.dri, e.sourceSets)
- }
- }
-
- protected open fun contentForClasslike(c: DClasslike) = contentBuilder.contentFor(c) {
- @Suppress("UNCHECKED_CAST")
- val extensions = (c as WithExtraProperties<DClasslike>)
- .extra[CallableExtensions]?.extensions
- ?.filterIsInstance<Documentable>().orEmpty()
- // Extensions are added to sourceSets since they can be placed outside the sourceSets from classlike
- // Example would be an Interface in common and extension function in jvm
- group(kind = ContentKind.Cover, sourceSets = mainSourcesetData + extensions.sourceSets) {
- cover(c.name.orEmpty())
- sourceSetDependentHint(c.dri, c.sourceSets) {
- +buildSignature(c)
- +contentForDescription(c)
+ /**
+ * @param documentables a list of [DClasslike] and [DEnumEntry] with the same dri in different sourceSets
+ */
+ protected open fun contentForClasslikesAndEntries(documentables: List<Documentable>): ContentGroup =
+ contentBuilder.contentFor(documentables.dri, documentables.sourceSets) {
+ val classlikes = documentables.filterIsInstance<DClasslike>()
+
+ @Suppress("UNCHECKED_CAST")
+ val extensions = (classlikes as List<WithExtraProperties<DClasslike>>).flatMap {
+ it.extra[CallableExtensions]?.extensions
+ ?.filterIsInstance<Documentable>().orEmpty()
}
- }
- group(styles = setOf(ContentStyle.TabbedContent), sourceSets = mainSourcesetData + extensions.sourceSets) {
- +contentForComments(c)
- if (c is WithConstructors) {
- block(
- "Constructors",
- 2,
- ContentKind.Constructors,
- c.constructors,
- c.sourceSets,
- needsAnchors = true,
- extra = PropertyContainer.empty<ContentNode>() + SimpleAttr.header("Constructors")
- ) {
- link(it.name, it.dri, kind = ContentKind.Main, styles = setOf(ContentStyle.RowTitle))
- sourceSetDependentHint(
- it.dri,
- it.sourceSets.toSet(),
- kind = ContentKind.SourceSetDependentHint,
- styles = emptySet(),
- extra = PropertyContainer.empty()
- ) {
+ // Extensions are added to sourceSets since they can be placed outside the sourceSets from classlike
+ // Example would be an Interface in common and extension function in jvm
+ group(kind = ContentKind.Cover, sourceSets = mainSourcesetData + extensions.sourceSets) {
+ cover(documentables.first().name.orEmpty())
+ sourceSetDependentHint(documentables.dri, documentables.sourceSets) {
+ documentables.forEach {
+buildSignature(it)
- contentForBrief(it)
+ +contentForDescription(it)
}
}
}
- if (c is DEnum) {
- block(
- "Entries",
- 2,
- ContentKind.Classlikes,
- c.entries,
- c.sourceSets.toSet(),
- needsSorting = false,
- needsAnchors = true,
- extra = mainExtra + SimpleAttr.header("Entries"),
- styles = emptySet()
- ) {
- link(it.name, it.dri)
- sourceSetDependentHint(
- it.dri,
- it.sourceSets.toSet(),
- kind = ContentKind.SourceSetDependentHint,
- extra = PropertyContainer.empty()
- ) {
- +buildSignature(it)
- contentForBrief(it)
+
+ group(styles = setOf(ContentStyle.TabbedContent), sourceSets = mainSourcesetData + extensions.sourceSets) {
+ +contentForComments(documentables)
+ val csWithConstructor = classlikes.filterIsInstance<WithConstructors>()
+ if (csWithConstructor.isNotEmpty()) {
+ val constructorsToDocumented = csWithConstructor.flatMap { it.constructors }
+ multiBlock(
+ "Constructors",
+ 2,
+ ContentKind.Constructors,
+ constructorsToDocumented.groupBy { it.parameters.map { it.dri } }
+ .map { (_, v) -> v.first().name to v },
+ @Suppress("UNCHECKED_CAST")
+ (csWithConstructor as List<Documentable>).sourceSets,
+ needsAnchors = true,
+ extra = PropertyContainer.empty<ContentNode>() + SimpleAttr.header("Constructors")
+ ) { key, ds ->
+ link(key, ds.first().dri, kind = ContentKind.Main, styles = setOf(ContentStyle.RowTitle))
+ sourceSetDependentHint(
+ ds.dri,
+ ds.sourceSets,
+ kind = ContentKind.SourceSetDependentHint,
+ styles = emptySet(),
+ extra = PropertyContainer.empty<ContentNode>()
+ ) {
+ ds.forEach {
+ +buildSignature(it)
+ contentForBrief(it)
+ }
+ }
}
}
- }
- +contentForScope(c, c.dri, c.sourceSets)
+ val csEnum = classlikes.filterIsInstance<DEnum>()
+ if (csEnum.isNotEmpty()) {
+ multiBlock(
+ "Entries",
+ 2,
+ ContentKind.Classlikes,
+ csEnum.flatMap { it.entries }.groupBy { it.name }.toList(),
+ csEnum.sourceSets,
+ needsSorting = false,
+ needsAnchors = true,
+ extra = mainExtra + SimpleAttr.header("Entries"),
+ styles = emptySet()
+ ) { key, ds ->
+ link(key, ds.first().dri)
+ sourceSetDependentHint(
+ ds.dri,
+ ds.sourceSets,
+ kind = ContentKind.SourceSetDependentHint,
+ extra = PropertyContainer.empty<ContentNode>()
+ ) {
+ ds.forEach {
+ +buildSignature(it)
+ contentForBrief(it)
+ }
+ }
+ }
+ }
+ +contentForScopes(documentables.filterIsInstance<WithScope>(), documentables.sourceSets)
- divergentBlock(
- "Extensions",
- extensions,
- ContentKind.Extensions,
- extra = mainExtra + SimpleAttr.header("Extensions")
- )
+ divergentBlock(
+ "Extensions",
+ extensions,
+ ContentKind.Extensions,
+ extra = mainExtra + SimpleAttr.header("Extensions")
+ )
+ }
}
- }
@Suppress("UNCHECKED_CAST")
private inline fun <reified T : TagWrapper> GroupedTags.withTypeUnnamed(): SourceSetDependent<T> =
@@ -347,7 +465,7 @@ open class DefaultPageCreator(
if (customTags.isNotEmpty()) {
group(styles = setOf(TextStyle.Block)) {
platforms.forEach { platform ->
- customTags.forEach { (tagName, sourceSetTag) ->
+ customTags.forEach { (_, sourceSetTag) ->
sourceSetTag[platform]?.let { tag ->
customTagContentProviders.filter { it.isApplicable(tag) }.forEach { provider ->
with(provider) {
@@ -379,8 +497,8 @@ open class DefaultPageCreator(
}.children
}
- private fun Documentable.getPossibleFallbackSourcesets(sourceSet: DokkaSourceSet) =
- this.sourceSets.filter { it.sourceSetID in sourceSet.dependentSourceSets }
+ private fun Set<DokkaSourceSet>.getPossibleFallbackSourcesets(sourceSet: DokkaSourceSet) =
+ this.filter { it.sourceSetID in sourceSet.dependentSourceSets }
private fun <V> Map<DokkaSourceSet, V>.fallback(sourceSets: List<DokkaSourceSet>): V? =
sourceSets.firstOrNull { it in this.keys }.let { this[it] }
@@ -388,8 +506,19 @@ open class DefaultPageCreator(
protected open fun contentForComments(
d: Documentable,
isPlatformHintedContent: Boolean = true
+ ) = contentForComments(d.dri, d.sourceSets, d.groupedTags, isPlatformHintedContent)
+
+ protected open fun contentForComments(
+ d: List<Documentable>,
+ isPlatformHintedContent: Boolean = true
+ ) = contentForComments(d.first().dri, d.sourceSets, d.groupedTags, isPlatformHintedContent)
+
+ protected open fun contentForComments(
+ dri: DRI,
+ sourceSets: Set<DokkaSourceSet>,
+ tags: GroupedTags,
+ isPlatformHintedContent: Boolean = true
): List<ContentNode> {
- val tags = d.groupedTags
fun DocumentableContentBuilder.buildContent(
platforms: Set<DokkaSourceSet>,
@@ -417,7 +546,7 @@ open class DefaultPageCreator(
buildContent(availablePlatforms) {
table(kind = ContentKind.Parameters, sourceSets = availablePlatforms) {
availablePlatforms.forEach { platform ->
- val possibleFallbacks = d.getPossibleFallbackSourcesets(platform)
+ val possibleFallbacks = sourceSets.getPossibleFallbackSourcesets(platform)
params.mapNotNull { (_, param) ->
(param[platform] ?: param.fallback(possibleFallbacks))?.let {
row(sourceSets = setOf(platform), kind = ContentKind.Parameters) {
@@ -451,7 +580,7 @@ open class DefaultPageCreator(
buildContent(availablePlatforms) {
table(kind = ContentKind.Sample) {
availablePlatforms.forEach { platform ->
- val possibleFallbacks = d.getPossibleFallbackSourcesets(platform)
+ val possibleFallbacks = sourceSets.getPossibleFallbackSourcesets(platform)
seeAlsoTags.forEach { (_, see) ->
(see[platform] ?: see.fallback(possibleFallbacks))?.let {
row(
@@ -537,12 +666,11 @@ open class DefaultPageCreator(
}
}
- return contentBuilder.contentFor(d) {
+ return contentBuilder.contentFor(dri, sourceSets) {
if (tags.isNotEmpty()) {
contentForSamples()
contentForSeeAlso()
- if (d !is DProperty)
- contentForParams()
+ contentForParams()
contentForThrows()
}
}.children
@@ -558,7 +686,8 @@ open class DefaultPageCreator(
We purposefully ignore all other tags as they should not be visible in brief
*/
- it.firstMemberOfTypeOrNull<Description>() ?: it.firstMemberOfTypeOrNull<Property>().takeIf { documentable is DProperty }
+ it.firstMemberOfTypeOrNull<Description>() ?: it.firstMemberOfTypeOrNull<Property>()
+ .takeIf { documentable is DProperty }
}?.let {
group(sourceSets = setOf(sourceSet), kind = ContentKind.BriefComment) {
if (documentable.hasSeparatePage) createBriefComment(documentable, sourceSet, it)
@@ -568,9 +697,13 @@ open class DefaultPageCreator(
}
}
- private fun DocumentableContentBuilder.createBriefComment(documentable: Documentable, sourceSet: DokkaSourceSet, tag: TagWrapper){
+ private fun DocumentableContentBuilder.createBriefComment(
+ documentable: Documentable,
+ sourceSet: DokkaSourceSet,
+ tag: TagWrapper
+ ) {
(documentable as? WithSources)?.documentableLanguage(sourceSet)?.let {
- when(it){
+ when (it) {
DocumentableLanguage.KOTLIN -> firstParagraphComment(tag.root)
DocumentableLanguage.JAVA -> firstSentenceComment(tag.root)
}
@@ -581,22 +714,27 @@ open class DefaultPageCreator(
protected open fun contentForProperty(p: DProperty) = contentForMember(p)
- protected open fun contentForMember(d: Documentable) = contentBuilder.contentFor(d) {
- group(kind = ContentKind.Cover) {
- cover(d.name.orEmpty())
- }
- divergentGroup(ContentDivergentGroup.GroupID("member")) {
- instance(setOf(d.dri), d.sourceSets.toSet()) {
- divergent {
- +buildSignature(d)
- }
- after {
- +contentForDescription(d)
- +contentForComments(d, isPlatformHintedContent = false)
+ protected open fun contentForMember(d: Documentable) = contentForMembers(listOf(d))
+
+ protected open fun contentForMembers(doumentables: List<Documentable>) =
+ contentBuilder.contentFor(doumentables.dri, doumentables.sourceSets) {
+ group(kind = ContentKind.Cover) {
+ cover(doumentables.first().name.orEmpty())
+ }
+ divergentGroup(ContentDivergentGroup.GroupID("member")) {
+ doumentables.forEach { d ->
+ instance(setOf(d.dri), d.sourceSets) {
+ divergent {
+ +buildSignature(d)
+ }
+ after {
+ +contentForDescription(d)
+ +contentForComments(d, isPlatformHintedContent = false)
+ }
+ }
}
}
}
- }
private fun DocumentableContentBuilder.functionsBlock(name: String, list: Collection<DFunction>) = divergentBlock(
name,
@@ -610,22 +748,24 @@ open class DefaultPageCreator(
list: Collection<DProperty>,
sourceSets: Set<DokkaSourceSet>
) {
- block(
+ multiBlock(
name,
2,
ContentKind.Properties,
- list,
+ list.groupBy { it.name }.toList(),
sourceSets,
needsAnchors = true,
extra = mainExtra + SimpleAttr.header(name),
headers = listOf(
headers("Name", "Summary")
)
- ) {
- link(it.name, it.dri, kind = ContentKind.Main)
- sourceSetDependentHint(it.dri, it.sourceSets.toSet(), kind = ContentKind.SourceSetDependentHint) {
- +buildSignature(it)
- contentForBrief(it)
+ ) { key, props ->
+ link(key, props.first().dri, kind = ContentKind.Main)
+ sourceSetDependentHint(props.dri, props.sourceSets, kind = ContentKind.SourceSetDependentHint) {
+ props.forEach {
+ +buildSignature(it)
+ contentForBrief(it)
+ }
}
}
}
@@ -699,7 +839,7 @@ open class DefaultPageCreator(
if (customTags.isEmpty()) return
documentable.sourceSets.forEach { sourceSet ->
- customTags.forEach { (tagName, sourceSetTag) ->
+ customTags.forEach { (_, sourceSetTag) ->
sourceSetTag[sourceSet]?.let { tag ->
customTagContentProviders.filter { it.isApplicable(tag) }.forEach { provider ->
with(provider) {
@@ -716,9 +856,19 @@ open class DefaultPageCreator(
private val List<Documentable>.sourceSets: Set<DokkaSourceSet>
get() = flatMap { it.sourceSets }.toSet()
+ private val List<Documentable>.dri: Set<DRI>
+ get() = map { it.dri }.toSet()
+
private val Documentable.groupedTags: GroupedTags
get() = documentation.flatMap { (pd, doc) ->
- doc.children.asSequence().map { pd to it }.toList()
+ doc.children.map { pd to it }.toList()
+ }.groupBy { it.second::class }
+
+ private val List<Documentable>.groupedTags: GroupedTags
+ get() = this.flatMap {
+ it.documentation.flatMap { (pd, doc) ->
+ doc.children.map { pd to it }.toList()
+ }
}.groupBy { it.second::class }
private val Documentable.descriptions: SourceSetDependent<Description>
@@ -730,6 +880,7 @@ open class DefaultPageCreator(
private val Documentable.hasSeparatePage: Boolean
get() = this !is DTypeAlias
+ @Suppress("UNCHECKED_CAST")
private fun <T : Documentable> T.nameAfterClash(): String =
((this as? WithExtraProperties<out Documentable>)?.extra?.get(DriClashAwareName)?.value ?: name).orEmpty()
}
diff --git a/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt b/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt
index 8c3fcd84..7b6fbc7a 100644
--- a/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt
+++ b/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt
@@ -227,6 +227,45 @@ open class PageContentBuilder(
}
}
+ fun <T : Pair<String, List<Documentable>>> multiBlock(
+ name: String,
+ level: Int,
+ kind: Kind = ContentKind.Main,
+ groupedElements: Iterable<T>,
+ sourceSets: Set<DokkaSourceSet> = mainSourcesetData,
+ styles: Set<Style> = mainStyles,
+ extra: PropertyContainer<ContentNode> = mainExtra,
+ renderWhenEmpty: Boolean = false,
+ needsSorting: Boolean = true,
+ headers: List<ContentGroup> = emptyList(),
+ needsAnchors: Boolean = false,
+ operation: DocumentableContentBuilder.(String, List<Documentable>) -> Unit
+ ) {
+ if (renderWhenEmpty || groupedElements.any()) {
+ header(level, name, kind = kind) { }
+ contents += ContentTable(
+ header = headers,
+ children = groupedElements
+ .let {
+ if (needsSorting)
+ it.sortedWith(compareBy(nullsLast(String.CASE_INSENSITIVE_ORDER)) { it.first })
+ else it
+ }
+ .map {
+ val newExtra = if (needsAnchors) extra + SymbolAnchorHint(it.first, kind) else extra
+ val documentables = it.second
+ buildGroup(documentables.map { it.dri }.toSet(), documentables.flatMap { it.sourceSets }.toSet(), kind, styles, newExtra) {
+ operation(it.first, documentables)
+ }
+ },
+ dci = DCI(mainDRI, kind),
+ sourceSets = sourceSets.toDisplaySourceSets(),
+ style = styles,
+ extra = extra
+ )
+ }
+ }
+
fun <T> list(
elements: List<T>,
prefix: String = "",
diff --git a/plugins/base/src/test/kotlin/content/functions/ContentForBriefTest.kt b/plugins/base/src/test/kotlin/content/functions/ContentForBriefTest.kt
index 7d8a169b..50f9e357 100644
--- a/plugins/base/src/test/kotlin/content/functions/ContentForBriefTest.kt
+++ b/plugins/base/src/test/kotlin/content/functions/ContentForBriefTest.kt
@@ -1,11 +1,11 @@
package content.functions
-import org.junit.Assert.assertEquals
import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest
import org.jetbrains.dokka.links.TypeConstructor
import org.jetbrains.dokka.model.DClass
import org.jetbrains.dokka.model.dfs
import org.jetbrains.dokka.pages.*
+import org.junit.Assert.assertEquals
import org.junit.jupiter.api.Test
import kotlin.test.assertNull
@@ -60,7 +60,7 @@ class ContentForBriefTest : BaseAbstractTest() {
testInline(codeWithSecondaryAndPrimaryConstructorsDocumented, testConfiguration) {
pagesTransformationStage = { module ->
val classPage =
- module.dfs { it.name == "Example" && (it as ContentPage).documentable is DClass } as ContentPage
+ module.dfs { it.name == "Example" && (it as WithDocumentables).documentables.firstOrNull() is DClass } as ContentPage
val constructorsTable =
classPage.content.dfs { it is ContentTable && it.dci.kind == ContentKind.Constructors } as ContentTable
@@ -84,7 +84,7 @@ class ContentForBriefTest : BaseAbstractTest() {
testInline(codeWithSecondaryAndPrimaryConstructorsDocumented, testConfiguration) {
pagesTransformationStage = { module ->
val classPage =
- module.dfs { it.name == "Example" && (it as ContentPage).documentable is DClass } as ContentPage
+ module.dfs { it.name == "Example" && (it as WithDocumentables).documentables.firstOrNull() is DClass } as ContentPage
val constructorsTable =
classPage.content.dfs { it is ContentTable && it.dci.kind == ContentKind.Constructors } as ContentTable
@@ -108,7 +108,7 @@ class ContentForBriefTest : BaseAbstractTest() {
testInline(codeWithDocumentedParameter, testConfiguration) {
pagesTransformationStage = { module ->
val classPage =
- module.dfs { it.name == "Example" && (it as ContentPage).documentable is DClass } as ContentPage
+ module.dfs { it.name == "Example" && (it as WithDocumentables).documentables.firstOrNull() is DClass } as ContentPage
val constructorsTable =
classPage.content.dfs { it is ContentTable && it.dci.kind == ContentKind.Constructors } as ContentTable
@@ -319,7 +319,7 @@ class ContentForBriefTest : BaseAbstractTest() {
}
private fun RootPageNode.singleFunctionDescription(className: String): ContentGroup {
- val classPage = dfs { it.name == className && (it as ContentPage).documentable is DClass } as ContentPage
+ val classPage = dfs { it.name == className && (it as WithDocumentables).documentables.firstOrNull() is DClass } as ContentPage
val functionsTable =
classPage.content.dfs { it is ContentTable && it.dci.kind == ContentKind.Functions } as ContentTable
diff --git a/plugins/base/src/test/kotlin/content/functions/ContentForConstructors.kt b/plugins/base/src/test/kotlin/content/functions/ContentForConstructors.kt
index 832fa6f6..8da3be54 100644
--- a/plugins/base/src/test/kotlin/content/functions/ContentForConstructors.kt
+++ b/plugins/base/src/test/kotlin/content/functions/ContentForConstructors.kt
@@ -32,7 +32,7 @@ class ContentForConstructors : BaseAbstractTest() {
""".trimIndent(), testConfiguration) {
pagesTransformationStage = { module ->
val classPage =
- module.dfs { it.name == "Example" && (it as ContentPage).documentable is DClass } as ContentPage
+ module.dfs { it.name == "Example" && (it as WithDocumentables).documentables.firstOrNull() is DClass } as ContentPage
val constructorsTable =
classPage.content.dfs { it is ContentTable && it.dci.kind == ContentKind.Constructors } as ContentTable
diff --git a/plugins/base/src/test/kotlin/locationProvider/DokkaLocationProviderTest.kt b/plugins/base/src/test/kotlin/locationProvider/DokkaLocationProviderTest.kt
index 8c96eab3..59406e1e 100644
--- a/plugins/base/src/test/kotlin/locationProvider/DokkaLocationProviderTest.kt
+++ b/plugins/base/src/test/kotlin/locationProvider/DokkaLocationProviderTest.kt
@@ -53,8 +53,7 @@ class DokkaLocationProviderTest : BaseAbstractTest() {
ModulePageNode(
name = name,
children = packages.pages,
- content = stubContentNode,
- documentable = null
+ content = stubContentNode
)
)
}
@@ -69,7 +68,6 @@ class DokkaLocationProviderTest : BaseAbstractTest() {
name = name,
children = packages.pages,
content = stubContentNode,
- documentable = null,
dri = emptySet()
)
)
@@ -84,7 +82,6 @@ class DokkaLocationProviderTest : BaseAbstractTest() {
name = name,
children = emptyList(),
content = stubContentNode,
- documentable = null,
dri = emptySet()
)
)
diff --git a/plugins/base/src/test/kotlin/transformers/MergeImplicitExpectActualDeclarationsTest.kt b/plugins/base/src/test/kotlin/transformers/MergeImplicitExpectActualDeclarationsTest.kt
new file mode 100644
index 00000000..ad3b5d38
--- /dev/null
+++ b/plugins/base/src/test/kotlin/transformers/MergeImplicitExpectActualDeclarationsTest.kt
@@ -0,0 +1,352 @@
+package transformers
+
+import org.jetbrains.dokka.DokkaConfiguration
+import org.jetbrains.dokka.PluginConfigurationImpl
+import org.jetbrains.dokka.base.DokkaBase
+import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest
+import org.jetbrains.dokka.model.childrenOfType
+import org.jetbrains.dokka.model.dfs
+import org.jetbrains.dokka.model.firstChildOfType
+import org.jetbrains.dokka.pages.*
+import org.jetbrains.kotlin.utils.addIfNotNull
+import org.junit.jupiter.api.Test
+import utils.assertNotNull
+import kotlin.test.assertEquals
+import kotlin.test.assertNotNull
+
+class MergeImplicitExpectActualDeclarationsTest : BaseAbstractTest() {
+
+ @Suppress("UNUSED_VARIABLE")
+ private fun configuration(switchOn: Boolean) = dokkaConfiguration {
+ sourceSets {
+ val common = sourceSet {
+ name = "common"
+ displayName = "common"
+ analysisPlatform = "common"
+ sourceRoots = listOf("src/commonMain/kotlin/pageMerger/Test.kt")
+ }
+ val js = sourceSet {
+ name = "js"
+ displayName = "js"
+ analysisPlatform = "js"
+ dependentSourceSets = setOf(common.value.sourceSetID)
+ sourceRoots = listOf("src/jsMain/kotlin/pageMerger/Test.kt")
+ }
+ val jvm = sourceSet {
+ name = "jvm"
+ displayName = "jvm"
+ analysisPlatform = "jvm"
+ sourceRoots = listOf("src/jvmMain/kotlin/pageMerger/Test.kt")
+ }
+ }
+ pluginsConfigurations.addIfNotNull(
+ PluginConfigurationImpl(
+ DokkaBase::class.qualifiedName!!,
+ DokkaConfiguration.SerializationFormat.JSON,
+ """{ "mergeImplicitExpectActualDeclarations": $switchOn }""",
+ )
+ )
+ }
+
+ private fun ClasslikePageNode.findSectionWithName(name: String) : ContentNode? {
+ var sectionHeader: ContentHeader? = null
+ return content.dfs { node ->
+ node.children.filterIsInstance<ContentHeader>().any { header ->
+ header.children.firstOrNull { it is ContentText && it.text == name }?.also { sectionHeader = header } != null
+ }
+ }?.children?.dropWhile { child -> child != sectionHeader }?.drop(1)?.firstOrNull()
+ }
+
+ @Test
+ fun `should merge fun`() {
+ testInline(
+ """
+
+ |/src/jvmMain/kotlin/pageMerger/Test.kt
+ |package pageMerger
+ |
+ |class classA {
+ | fun method1(): String
+ |}
+ |
+ |/src/jsMain/kotlin/pageMerger/Test.kt
+ |package pageMerger
+ |
+ |class classA {
+ | fun method1(): Int
+ |}
+ |
+ """.trimMargin(),
+ configuration(true),
+ cleanupOutput = true
+ ) {
+ pagesTransformationStage = { root ->
+ val classPage = root.dfs { it.name == "classA" } as? ClasslikePageNode
+ assertNotNull(classPage, "Tested class not found!")
+
+ val functions = classPage.findSectionWithName("Functions").assertNotNull("Functions")
+ val method1 = functions.children.singleOrNull().assertNotNull("method1")
+
+ assertEquals(
+ 2,
+ method1.firstChildOfType<ContentDivergentGroup>().childrenOfType<ContentDivergentInstance>().size,
+ "Incorrect number of divergent instances found"
+ )
+
+ val methodPage = root.dfs { it.name == "method1" } as? MemberPageNode
+ assertNotNull(methodPage, "Tested method not found!")
+
+ val divergentGroup = methodPage.content.dfs { it is ContentDivergentGroup } as? ContentDivergentGroup
+
+ assertEquals(
+ 2,
+ divergentGroup?.childrenOfType<ContentDivergentInstance>()?.size,
+ "Incorrect number of divergent instances found in method page"
+ )
+ }
+ }
+ }
+
+ @Test
+ fun `should merge method and prop`() {
+ testInline(
+ """
+ |/src/jvmMain/kotlin/pageMerger/Test.kt
+ |package pageMerger
+ |
+ |class classA {
+ | fun method1(): String
+ |}
+ |
+ |/src/jsMain/kotlin/pageMerger/Test.kt
+ |package pageMerger
+ |
+ |class classA {
+ | val prop1: Int
+ |}
+ |
+ """.trimMargin(),
+ configuration(true),
+ cleanupOutput = true
+ ) {
+ pagesTransformationStage = { root ->
+ val classPage = root.dfs { it.name == "classA" } as? ClasslikePageNode
+ assertNotNull(classPage, "Tested class not found!")
+
+ val props = classPage.findSectionWithName("Properties").assertNotNull("Properties")
+ val prop1 = props.children.singleOrNull().assertNotNull("prop1")
+
+ val functions = classPage.findSectionWithName("Functions").assertNotNull("Functions")
+ val method1 = functions.children.singleOrNull().assertNotNull("method1")
+ }
+ }
+ }
+
+ @Test
+ fun `should merge prop`() {
+ testInline(
+ """
+ |/src/jvmMain/kotlin/pageMerger/Test.kt
+ |package pageMerger
+ |
+ |class classA {
+ | val prop1: String
+ |}
+ |
+ |/src/jsMain/kotlin/pageMerger/Test.kt
+ |package pageMerger
+ |
+ |class classA {
+ | val prop1: Int
+ |}
+ |
+ """.trimMargin(),
+ configuration(true),
+ cleanupOutput = true
+ ) {
+ pagesTransformationStage = { root ->
+ val classPage = root.dfs { it.name == "classA" } as? ClasslikePageNode
+ assertNotNull(classPage, "Tested class not found!")
+
+ val props = classPage.findSectionWithName("Properties").assertNotNull("Properties")
+ val prop1 = props.children.singleOrNull().assertNotNull("prop1")
+
+ assertEquals(
+ 2,
+ prop1.firstChildOfType<PlatformHintedContent>().inner.children.size,
+ "Incorrect number of divergent instances found"
+ )
+
+ val propPage = root.dfs { it.name == "prop1" } as? MemberPageNode
+ assertNotNull(propPage, "Tested method not found!")
+
+ val divergentGroup = propPage.content.dfs { it is ContentDivergentGroup } as? ContentDivergentGroup
+
+ assertEquals(
+ 2,
+ divergentGroup?.childrenOfType<ContentDivergentInstance>()?.size,
+ "Incorrect number of divergent instances found in method page"
+ )
+ }
+ }
+ }
+
+ @Test
+ fun `should merge enum and class`() {
+ testInline(
+ """
+ |/src/jvmMain/kotlin/pageMerger/Test.kt
+ |package pageMerger
+ |
+ |class classA {
+ | val prop1: String
+ |}
+ |
+ |/src/jsMain/kotlin/pageMerger/Test.kt
+ |package pageMerger
+ |
+ |enum class classA {
+ | ENTRY
+ |}
+ |
+ """.trimMargin(),
+ configuration(true),
+ cleanupOutput = true
+ ) {
+ pagesTransformationStage = { root ->
+ val classPage = root.dfs { it.name == "classA" } as? ClasslikePageNode
+ assertNotNull(classPage, "Tested class not found!")
+
+ val entries = classPage.findSectionWithName("Entries").assertNotNull("Entries")
+ val entry = entries.children.singleOrNull().assertNotNull("ENTRY")
+
+ val props = classPage.findSectionWithName("Properties").assertNotNull("Properties")
+ assertEquals(
+ 3,
+ props.children.size,
+ "Incorrect number of properties found in method page"
+ )
+ }
+ }
+ }
+
+ fun PageNode.childrenRec(): List<PageNode> = listOf(this) + children.flatMap { it.childrenRec() }
+
+ @Test
+ fun `should merge enum entries`() {
+ testInline(
+ """
+ |/src/jvmMain/kotlin/pageMerger/Test.kt
+ |package pageMerger
+ |
+ |enum class classA {
+ | SMTH;
+ | fun method1(): Int
+ |}
+ |
+ |/src/jsMain/kotlin/pageMerger/Test.kt
+ |package pageMerger
+ |
+ |enum class classA {
+ | SMTH;
+ | fun method1(): Int
+ |}
+ |
+ """.trimMargin(),
+ configuration(true),
+ cleanupOutput = true
+ ) {
+ pagesTransformationStage = { root ->
+ val classPage = root.dfs { it.name == "SMTH" } as? ClasslikePageNode
+ assertNotNull(classPage, "Tested class not found!")
+
+ val functions = classPage.findSectionWithName("Functions").assertNotNull("Functions")
+ val method1 = functions.children.singleOrNull().assertNotNull("method1")
+
+ assertEquals(
+ 2,
+ method1.firstChildOfType<ContentDivergentGroup>().childrenOfType<ContentDivergentInstance>().size,
+ "Incorrect number of divergent instances found"
+ )
+ }
+ }
+ }
+
+ /**
+ * There is a case when a property and fun from different source sets
+ * have the same name so pages have the same urls respectively.
+ */
+ @Test
+ fun `should no merge prop and method with the same name`() {
+ testInline(
+ """
+ |/src/jvmMain/kotlin/pageMerger/Test.kt
+ |package pageMerger
+ |
+ |class classA {
+ | fun merged():String
+ |}
+ |
+ |/src/jsMain/kotlin/pageMerger/Test.kt
+ |package pageMerger
+ |
+ |class classA {
+ | val merged:String
+ |}
+ |
+ """.trimMargin(),
+ configuration(true),
+ cleanupOutput = true
+ ) {
+ pagesTransformationStage = { root ->
+ val allChildren = root.childrenRec().filterIsInstance<MemberPageNode>()
+
+ assertEquals(
+ 1,
+ allChildren.filter { it.name == "merged" }.size,
+ "Incorrect number of fun pages"
+ )
+ }
+ }
+ }
+
+ @Test
+ fun `should always merge constructor`() {
+ testInline(
+ """
+ |/src/commonMain/kotlin/pageMerger/Test.kt
+ |package pageMerger
+ |
+ |expect class classA(a: Int)
+ |
+ |/src/jsMain/kotlin/pageMerger/Test.kt
+ |package pageMerger
+ |
+ |actual class classA(a: Int)
+ """.trimMargin(),
+ configuration(false),
+ cleanupOutput = true
+ ) {
+ pagesTransformationStage = { root ->
+ val classPage = root.dfs { it.name == "classA" } as? ClasslikePageNode
+ assertNotNull(classPage, "Tested class not found!")
+
+ val constructors = classPage.findSectionWithName("Constructors").assertNotNull("Constructors")
+
+ assertEquals(
+ 1,
+ constructors.children.size,
+ "Incorrect number of constructors"
+ )
+
+ val platformHinted = constructors.dfs { it is PlatformHintedContent } as? PlatformHintedContent
+
+ assertEquals(
+ 2,
+ platformHinted?.sourceSets?.size,
+ "Incorrect number of source sets"
+ )
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/javadoc/api/javadoc.api b/plugins/javadoc/api/javadoc.api
index bfea687a..0eabce5c 100644
--- a/plugins/javadoc/api/javadoc.api
+++ b/plugins/javadoc/api/javadoc.api
@@ -56,6 +56,7 @@ public final class org/jetbrains/dokka/javadoc/pages/AllClassesPage : org/jetbra
public final fun getClasses ()Ljava/util/List;
public fun getContent ()Lorg/jetbrains/dokka/pages/ContentNode;
public fun getDocumentable ()Lorg/jetbrains/dokka/model/Documentable;
+ public fun getDocumentables ()Ljava/util/List;
public fun getDri ()Ljava/util/Set;
public fun getEmbeddedResources ()Ljava/util/List;
public fun getName ()Ljava/lang/String;
@@ -90,6 +91,7 @@ public final class org/jetbrains/dokka/javadoc/pages/DeprecatedPage : org/jetbra
public fun getChildren ()Ljava/util/List;
public fun getContent ()Lorg/jetbrains/dokka/pages/ContentNode;
public fun getDocumentable ()Lorg/jetbrains/dokka/model/Documentable;
+ public fun getDocumentables ()Ljava/util/List;
public fun getDri ()Ljava/util/Set;
public final fun getElements ()Ljava/util/Map;
public fun getEmbeddedResources ()Ljava/util/List;
@@ -158,6 +160,7 @@ public final class org/jetbrains/dokka/javadoc/pages/IndexPage : org/jetbrains/d
public fun getChildren ()Ljava/util/List;
public fun getContent ()Lorg/jetbrains/dokka/pages/ContentNode;
public fun getDocumentable ()Lorg/jetbrains/dokka/model/Documentable;
+ public fun getDocumentables ()Ljava/util/List;
public fun getDri ()Ljava/util/Set;
public final fun getElements ()Ljava/util/List;
public fun getEmbeddedResources ()Ljava/util/List;
@@ -176,8 +179,8 @@ public final class org/jetbrains/dokka/javadoc/pages/JavaContentGroupBuilder {
}
public final class org/jetbrains/dokka/javadoc/pages/JavadocClasslikePageNode : org/jetbrains/dokka/javadoc/pages/JavadocPageNode, org/jetbrains/dokka/javadoc/pages/NavigableJavadocNode, org/jetbrains/dokka/javadoc/pages/WithBrief, org/jetbrains/dokka/javadoc/pages/WithJavadocExtra, org/jetbrains/dokka/javadoc/pages/WithNavigable, org/jetbrains/dokka/pages/ClasslikePage {
- public fun <init> (Ljava/lang/String;Lorg/jetbrains/dokka/javadoc/pages/JavadocContentNode;Ljava/util/Set;Lorg/jetbrains/dokka/javadoc/pages/JavadocSignatureContentNode;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Lorg/jetbrains/dokka/model/Documentable;Ljava/util/List;Ljava/util/List;Lorg/jetbrains/dokka/model/properties/PropertyContainer;)V
- public synthetic fun <init> (Ljava/lang/String;Lorg/jetbrains/dokka/javadoc/pages/JavadocContentNode;Ljava/util/Set;Lorg/jetbrains/dokka/javadoc/pages/JavadocSignatureContentNode;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Lorg/jetbrains/dokka/model/Documentable;Ljava/util/List;Ljava/util/List;Lorg/jetbrains/dokka/model/properties/PropertyContainer;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+ public fun <init> (Ljava/lang/String;Lorg/jetbrains/dokka/javadoc/pages/JavadocContentNode;Ljava/util/Set;Lorg/jetbrains/dokka/javadoc/pages/JavadocSignatureContentNode;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Lorg/jetbrains/dokka/model/properties/PropertyContainer;)V
+ public synthetic fun <init> (Ljava/lang/String;Lorg/jetbrains/dokka/javadoc/pages/JavadocContentNode;Ljava/util/Set;Lorg/jetbrains/dokka/javadoc/pages/JavadocSignatureContentNode;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Lorg/jetbrains/dokka/model/properties/PropertyContainer;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun getAllNavigables ()Ljava/util/List;
public final fun getAnchorables ()Ljava/util/List;
public fun getBrief ()Ljava/util/List;
@@ -189,6 +192,7 @@ public final class org/jetbrains/dokka/javadoc/pages/JavadocClasslikePageNode :
public fun getDRI ()Lorg/jetbrains/dokka/links/DRI;
public final fun getDescription ()Ljava/util/List;
public fun getDocumentable ()Lorg/jetbrains/dokka/model/Documentable;
+ public fun getDocumentables ()Ljava/util/List;
public fun getDri ()Ljava/util/Set;
public fun getEmbeddedResources ()Ljava/util/List;
public final fun getEntries ()Ljava/util/List;
@@ -353,6 +357,7 @@ public final class org/jetbrains/dokka/javadoc/pages/JavadocModulePageNode : org
public synthetic fun getContent ()Lorg/jetbrains/dokka/pages/ContentNode;
public fun getDRI ()Lorg/jetbrains/dokka/links/DRI;
public fun getDocumentable ()Lorg/jetbrains/dokka/model/Documentable;
+ public fun getDocumentables ()Ljava/util/List;
public fun getDri ()Ljava/util/Set;
public fun getEmbeddedResources ()Ljava/util/List;
public fun getExtra ()Lorg/jetbrains/dokka/model/properties/PropertyContainer;
@@ -367,14 +372,15 @@ public final class org/jetbrains/dokka/javadoc/pages/JavadocModulePageNode : org
}
public final class org/jetbrains/dokka/javadoc/pages/JavadocPackagePageNode : org/jetbrains/dokka/javadoc/pages/JavadocPageNode, org/jetbrains/dokka/javadoc/pages/NavigableJavadocNode, org/jetbrains/dokka/javadoc/pages/WithNavigable, org/jetbrains/dokka/pages/PackagePage {
- public fun <init> (Ljava/lang/String;Lorg/jetbrains/dokka/javadoc/pages/JavadocContentNode;Ljava/util/Set;Lorg/jetbrains/dokka/model/Documentable;Ljava/util/List;Ljava/util/List;)V
- public synthetic fun <init> (Ljava/lang/String;Lorg/jetbrains/dokka/javadoc/pages/JavadocContentNode;Ljava/util/Set;Lorg/jetbrains/dokka/model/Documentable;Ljava/util/List;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+ public fun <init> (Ljava/lang/String;Lorg/jetbrains/dokka/javadoc/pages/JavadocContentNode;Ljava/util/Set;Ljava/util/List;Ljava/util/List;Ljava/util/List;)V
+ public synthetic fun <init> (Ljava/lang/String;Lorg/jetbrains/dokka/javadoc/pages/JavadocContentNode;Ljava/util/Set;Ljava/util/List;Ljava/util/List;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun getAllNavigables ()Ljava/util/List;
public fun getChildren ()Ljava/util/List;
public fun getContent ()Lorg/jetbrains/dokka/javadoc/pages/JavadocContentNode;
public synthetic fun getContent ()Lorg/jetbrains/dokka/pages/ContentNode;
public fun getDRI ()Lorg/jetbrains/dokka/links/DRI;
public fun getDocumentable ()Lorg/jetbrains/dokka/model/Documentable;
+ public fun getDocumentables ()Ljava/util/List;
public fun getDri ()Ljava/util/Set;
public fun getEmbeddedResources ()Ljava/util/List;
public fun getId ()Ljava/lang/String;
@@ -383,7 +389,11 @@ public final class org/jetbrains/dokka/javadoc/pages/JavadocPackagePageNode : or
public fun modified (Ljava/lang/String;Lorg/jetbrains/dokka/pages/ContentNode;Ljava/util/Set;Ljava/util/List;Ljava/util/List;)Lorg/jetbrains/dokka/pages/ContentPage;
}
-public abstract interface class org/jetbrains/dokka/javadoc/pages/JavadocPageNode : org/jetbrains/dokka/pages/ContentPage {
+public abstract interface class org/jetbrains/dokka/javadoc/pages/JavadocPageNode : org/jetbrains/dokka/pages/ContentPage, org/jetbrains/dokka/pages/WithDocumentables {
+}
+
+public final class org/jetbrains/dokka/javadoc/pages/JavadocPageNode$DefaultImpls {
+ public static fun getDocumentable (Lorg/jetbrains/dokka/javadoc/pages/JavadocPageNode;)Lorg/jetbrains/dokka/model/Documentable;
}
public final class org/jetbrains/dokka/javadoc/pages/JavadocParameterNode : org/jetbrains/dokka/javadoc/pages/AnchorableJavadocNode, org/jetbrains/dokka/javadoc/pages/WithJavadocExtra {
@@ -573,11 +583,13 @@ public final class org/jetbrains/dokka/javadoc/pages/TreeViewInstaller : org/jet
}
public final class org/jetbrains/dokka/javadoc/pages/TreeViewPage : org/jetbrains/dokka/javadoc/pages/JavadocPageNode {
- public fun <init> (Ljava/lang/String;Ljava/util/List;Ljava/util/List;Ljava/util/Set;Lorg/jetbrains/dokka/model/Documentable;Lorg/jetbrains/dokka/pages/PageNode;)V
+ public fun <init> (Ljava/lang/String;Ljava/util/List;Ljava/util/List;Ljava/util/Set;Ljava/util/List;Lorg/jetbrains/dokka/pages/PageNode;)V
+ public synthetic fun <init> (Ljava/lang/String;Ljava/util/List;Ljava/util/List;Ljava/util/Set;Ljava/util/List;Lorg/jetbrains/dokka/pages/PageNode;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun getChildren ()Ljava/util/List;
public final fun getClasses ()Ljava/util/List;
public fun getContent ()Lorg/jetbrains/dokka/pages/ContentNode;
public fun getDocumentable ()Lorg/jetbrains/dokka/model/Documentable;
+ public fun getDocumentables ()Ljava/util/List;
public fun getDri ()Ljava/util/Set;
public fun getEmbeddedResources ()Ljava/util/List;
public final fun getKind ()Ljava/lang/String;
diff --git a/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/JavadocPageCreator.kt b/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/JavadocPageCreator.kt
index 96bcec70..61d45ae1 100644
--- a/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/JavadocPageCreator.kt
+++ b/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/JavadocPageCreator.kt
@@ -33,7 +33,7 @@ open class JavadocPageCreator(context: DokkaContext) {
)
fun pageForPackage(p: DPackage) =
- JavadocPackagePageNode(p.name, contentForPackage(p), setOf(p.dri), p,
+ JavadocPackagePageNode(p.name, contentForPackage(p), setOf(p.dri), listOf(p),
p.classlikes.mapNotNull { pageForClasslike(it) }
)
@@ -68,7 +68,7 @@ open class JavadocPageCreator(context: DokkaContext) {
PropertyContainer.withAll(it.indexesInDocumentation())
)
},
- documentable = c,
+ documentables = listOf(c),
children = children,
extra = ((c as? WithExtraProperties<Documentable>)?.extra
?: PropertyContainer.empty()) + c.indexesInDocumentation()
diff --git a/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/pages/JavadocPageNodes.kt b/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/pages/JavadocPageNodes.kt
index 572c5dec..6c7691cd 100644
--- a/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/pages/JavadocPageNodes.kt
+++ b/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/pages/JavadocPageNodes.kt
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.resolve.DescriptorUtils.getClassDescriptorForType
-interface JavadocPageNode : ContentPage
+interface JavadocPageNode : ContentPage, WithDocumentables
interface WithJavadocExtra<T : Documentable> : WithExtraProperties<T> {
override fun withNewExtras(newExtras: PropertyContainer<T>): T =
@@ -43,7 +43,7 @@ class JavadocModulePageNode(
JavadocPageNode,
ModulePage {
- override val documentable: Documentable? = null
+ override val documentables: List<Documentable> = emptyList()
override val embeddedResources: List<String> = emptyList()
override fun modified(name: String, children: List<PageNode>): RootPageNode =
JavadocModulePageNode(name, content, children, dri, extra)
@@ -66,7 +66,7 @@ class JavadocPackagePageNode(
override val content: JavadocContentNode,
override val dri: Set<DRI>,
- override val documentable: Documentable? = null,
+ override val documentables: List<Documentable> = emptyList(),
override val children: List<PageNode> = emptyList(),
override val embeddedResources: List<String> = listOf()
) : JavadocPageNode,
@@ -91,7 +91,7 @@ class JavadocPackagePageNode(
name,
content,
dri,
- documentable,
+ documentables,
children,
embeddedResources
)
@@ -107,7 +107,7 @@ class JavadocPackagePageNode(
name,
content as JavadocContentNode,
dri,
- documentable,
+ documentables,
children,
embeddedResources
)
@@ -182,7 +182,7 @@ class JavadocClasslikePageNode(
val classlikes: List<JavadocClasslikePageNode>,
val properties: List<JavadocPropertyNode>,
override val brief: List<ContentNode>,
- override val documentable: Documentable? = null,
+ override val documentables: List<Documentable> = emptyList(),
override val children: List<PageNode> = emptyList(),
override val embeddedResources: List<String> = listOf(),
override val extra: PropertyContainer<DClasslike> = PropertyContainer.empty(),
@@ -194,7 +194,7 @@ class JavadocClasslikePageNode(
fun getAnchorables(): List<AnchorableJavadocNode> =
constructors + methods + entries + properties
- val kind: String? = documentable?.kind()
+ val kind: String? = documentables.firstOrNull()?.kind()
val packageName = dri.first().packageName
override fun getId(): String = name
@@ -215,7 +215,7 @@ class JavadocClasslikePageNode(
classlikes,
properties,
brief,
- documentable,
+ documentables,
children,
embeddedResources,
extra
@@ -240,7 +240,7 @@ class JavadocClasslikePageNode(
classlikes,
properties,
brief,
- documentable,
+ documentables,
children,
embeddedResources,
extra
@@ -254,7 +254,7 @@ class AllClassesPage(val classes: List<JavadocClasslikePageNode>) : JavadocPageN
override val name: String = "All Classes"
override val dri: Set<DRI> = setOf(DRI.topLevel)
- override val documentable: Documentable? = null
+ override val documentables: List<Documentable> = emptyList()
override val embeddedResources: List<String> = emptyList()
override val content: ContentNode =
@@ -285,7 +285,7 @@ class DeprecatedPage(
) : JavadocPageNode {
override val name: String = "deprecated"
override val dri: Set<DRI> = setOf(DRI.topLevel)
- override val documentable: Documentable? = null
+ override val documentables: List<Documentable> = emptyList()
override val children: List<PageNode> = emptyList()
override val embeddedResources: List<String> = listOf()
@@ -339,7 +339,7 @@ class IndexPage(
) : JavadocPageNode {
override val name: String = "index-$id"
override val dri: Set<DRI> = setOf(DRI.topLevel)
- override val documentable: Documentable? = null
+ override val documentables: List<Documentable> = emptyList()
override val children: List<PageNode> = emptyList()
override val embeddedResources: List<String> = listOf()
val title: String = "${keys[id - 1]}-index"
@@ -370,7 +370,7 @@ class TreeViewPage(
val packages: List<JavadocPackagePageNode>?,
val classes: List<JavadocClasslikePageNode>?,
override val dri: Set<DRI>,
- override val documentable: Documentable?,
+ override val documentables: List<Documentable> = emptyList(),
val root: PageNode
) : JavadocPageNode {
init {
@@ -378,7 +378,7 @@ class TreeViewPage(
assert(packages != null || classes != null)
}
- private val documentables = root.children.filterIsInstance<ContentPage>().flatMap { node ->
+ private val childrenDocumentables = root.children.filterIsInstance<WithDocumentables>().flatMap { node ->
getDocumentableEntries(node)
}.groupBy({ it.first }) { it.second }.map { (l, r) -> l to r.first() }.toMap()
@@ -389,12 +389,12 @@ class TreeViewPage(
override val children: List<PageNode> = emptyList()
- val title = when (documentable) {
+ val title = when (documentables.firstOrNull()) {
is DPackage -> "$name Class Hierarchy"
else -> "All packages"
}
- val kind = when (documentable) {
+ val kind = when (documentables.firstOrNull()) {
is DPackage -> "package"
else -> "main"
}
@@ -411,7 +411,7 @@ class TreeViewPage(
packages = children.filterIsInstance<JavadocPackagePageNode>().takeIf { it.isNotEmpty() },
classes = children.filterIsInstance<JavadocClasslikePageNode>().takeIf { it.isNotEmpty() },
dri = dri,
- documentable = documentable,
+ documentables,
root = root
)
@@ -421,7 +421,7 @@ class TreeViewPage(
packages = children.filterIsInstance<JavadocPackagePageNode>().takeIf { it.isNotEmpty() },
classes = children.filterIsInstance<JavadocClasslikePageNode>().takeIf { it.isNotEmpty() },
dri = dri,
- documentable = documentable,
+ documentables,
root = root
)
@@ -473,23 +473,25 @@ class TreeViewPage(
listOf(psi to l) + l.flatMap { gatherPsiClasses(it) }
}
- val psiInheritanceTree = documentables.flatMap { (_, v) -> (v as? WithSources)?.sources?.values.orEmpty() }
- .filterIsInstance<PsiDocumentableSource>().mapNotNull { it.psi as? PsiClass }.flatMap(::gatherPsiClasses)
- .flatMap { entry -> entry.second.map { it to entry.first } }
- .let {
- it + it.map { it.second to null }
- }
- .groupBy({ it.first }) { it.second }
- .map { it.key to it.value.filterNotNull().distinct() }
- .map { (k, v) ->
- InheritanceNode(
- DRI.from(k),
- v.map { InheritanceNode(DRI.from(it)) },
- k.supers.filter { it.isInterface }.map { DRI.from(it) },
- k.isInterface
- )
-
- }
+ val psiInheritanceTree =
+ childrenDocumentables.flatMap { (_, v) -> (v as? WithSources)?.sources?.values.orEmpty() }
+ .filterIsInstance<PsiDocumentableSource>().mapNotNull { it.psi as? PsiClass }
+ .flatMap(::gatherPsiClasses)
+ .flatMap { entry -> entry.second.map { it to entry.first } }
+ .let {
+ it + it.map { it.second to null }
+ }
+ .groupBy({ it.first }) { it.second }
+ .map { it.key to it.value.filterNotNull().distinct() }
+ .map { (k, v) ->
+ InheritanceNode(
+ DRI.from(k),
+ v.map { InheritanceNode(DRI.from(it)) },
+ k.supers.filter { it.isInterface }.map { DRI.from(it) },
+ k.isInterface
+ )
+
+ }
val descriptorInheritanceTree = descriptorMap.flatMap { (_, v) ->
v.typeConstructor.supertypes
@@ -523,16 +525,17 @@ class TreeViewPage(
}
private fun generateInterfaceGraph() {
- documentables.values.filterIsInstance<DInterface>()
+ childrenDocumentables.values.filterIsInstance<DInterface>()
}
- private fun getDocumentableEntries(node: ContentPage): List<Pair<DRI, Documentable>> =
- listOfNotNull(node.documentable?.let { it.dri to it }) +
- node.children.filterIsInstance<ContentPage>().flatMap(::getDocumentableEntries)
+ private fun getDocumentableEntries(node: WithDocumentables): List<Pair<DRI, Documentable>> =
+ node.documentables.map { it.dri to it } +
+ (node as? ContentPage)?.children?.filterIsInstance<WithDocumentables>()
+ ?.flatMap(::getDocumentableEntries).orEmpty()
private fun getDescriptorMap(): Map<DRI, ClassDescriptor> {
val map: MutableMap<DRI, ClassDescriptor> = mutableMapOf()
- documentables
+ childrenDocumentables
.mapNotNull { (k, v) ->
v.descriptorForPlatform()?.let { k to it }?.also { (k, v) -> map[k] = v }
}.map { it.second }.forEach { gatherSupertypes(it, map) }
diff --git a/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/pages/htmlPreprocessors.kt b/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/pages/htmlPreprocessors.kt
index c04c7538..bef4108c 100644
--- a/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/pages/htmlPreprocessors.kt
+++ b/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/pages/htmlPreprocessors.kt
@@ -4,12 +4,10 @@ import org.jetbrains.dokka.base.renderers.sourceSets
import org.jetbrains.dokka.base.transformers.documentables.deprecatedAnnotation
import org.jetbrains.dokka.base.transformers.documentables.isDeprecated
import org.jetbrains.dokka.base.transformers.documentables.isException
-import org.jetbrains.dokka.model.Documentable
import org.jetbrains.dokka.model.BooleanValue
-import org.jetbrains.dokka.model.WithSupertypes
+import org.jetbrains.dokka.model.Documentable
import org.jetbrains.dokka.pages.*
import org.jetbrains.dokka.transformers.pages.PageTransformer
-import kotlin.collections.HashMap
object ResourcesInstaller : PageTransformer {
override fun invoke(input: RootPageNode): RootPageNode = input.modified(
@@ -37,7 +35,7 @@ object TreeViewInstaller : PageTransformer {
packages = node.children<JavadocPackagePageNode>().map { installPackageTreeNode(it, root) },
classes = null,
dri = node.dri,
- documentable = node.documentable,
+ documentables = node.documentables,
root = root
)
@@ -55,7 +53,7 @@ object TreeViewInstaller : PageTransformer {
packages = null,
classes = node.children.filterIsInstance<JavadocClasslikePageNode>(),
dri = node.dri,
- documentable = node.documentable,
+ documentables = node.documentables,
root = root
)
diff --git a/plugins/mathjax/src/main/kotlin/MathjaxPlugin.kt b/plugins/mathjax/src/main/kotlin/MathjaxPlugin.kt
index 89c13202..669238ff 100644
--- a/plugins/mathjax/src/main/kotlin/MathjaxPlugin.kt
+++ b/plugins/mathjax/src/main/kotlin/MathjaxPlugin.kt
@@ -9,6 +9,7 @@ import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder.Doc
import org.jetbrains.dokka.model.doc.CustomTagWrapper
import org.jetbrains.dokka.pages.ContentPage
import org.jetbrains.dokka.pages.RootPageNode
+import org.jetbrains.dokka.pages.WithDocumentables
import org.jetbrains.dokka.plugability.DokkaPlugin
import org.jetbrains.dokka.transformers.pages.PageTransformer
@@ -35,12 +36,10 @@ object MathjaxTransformer : PageTransformer {
}
private val ContentPage.isNeedingMathjax
- get() = documentable?.documentation?.values
- ?.flatMap { it.children }
- .orEmpty()
- .any { (it as? CustomTagWrapper)?.name == ANNOTATION }
+ get() = (this as WithDocumentables).documentables.any { it.documentation.values
+ .flatMap { it.children }
+ .any { (it as? CustomTagWrapper)?.name == ANNOTATION } }
}
-
object MathjaxTagContentProvider : CustomTagContentProvider {
override fun isApplicable(customTag: CustomTagWrapper) = customTag.name == ANNOTATION