Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to merge implicit expect-actual declarations #2316

Merged
merged 17 commits into from Feb 21, 2022
53 changes: 41 additions & 12 deletions core/api/core.api
Expand Up @@ -3440,15 +3440,20 @@ public abstract interface class org/jetbrains/dokka/model/properties/WithExtraPr
public abstract fun withNewExtras (Lorg/jetbrains/dokka/model/properties/PropertyContainer;)Ljava/lang/Object;
}

public abstract interface class org/jetbrains/dokka/pages/ClasslikePage : org/jetbrains/dokka/pages/ContentPage {
public abstract interface class org/jetbrains/dokka/pages/ClasslikePage : org/jetbrains/dokka/pages/ContentPage, org/jetbrains/dokka/pages/WithDocumentables {
}

public final class org/jetbrains/dokka/pages/ClasslikePage$DefaultImpls {
public static fun getDocumentable (Lorg/jetbrains/dokka/pages/ClasslikePage;)Lorg/jetbrains/dokka/model/Documentable;
}

public final class org/jetbrains/dokka/pages/ClasslikePageNode : org/jetbrains/dokka/pages/ClasslikePage {
public fun <init> (Ljava/lang/String;Lorg/jetbrains/dokka/pages/ContentNode;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/pages/ContentNode;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/pages/ContentNode;Ljava/util/Set;Ljava/util/List;Ljava/util/List;Ljava/util/List;)V
public synthetic fun <init> (Ljava/lang/String;Lorg/jetbrains/dokka/pages/ContentNode;Ljava/util/Set;Ljava/util/List;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;
public fun getDocumentables ()Ljava/util/List;
public fun getDri ()Ljava/util/Set;
public fun getEmbeddedResources ()Ljava/util/List;
public fun getName ()Ljava/lang/String;
Expand Down Expand Up @@ -3846,6 +3851,7 @@ public abstract interface class org/jetbrains/dokka/pages/ContentPage : org/jetb
}

public final class org/jetbrains/dokka/pages/ContentPage$DefaultImpls {
public static fun getDocumentable (Lorg/jetbrains/dokka/pages/ContentPage;)Lorg/jetbrains/dokka/model/Documentable;
public static synthetic fun modified$default (Lorg/jetbrains/dokka/pages/ContentPage;Ljava/lang/String;Lorg/jetbrains/dokka/pages/ContentNode;Ljava/util/Set;Ljava/util/List;Ljava/util/List;ILjava/lang/Object;)Lorg/jetbrains/dokka/pages/ContentPage;
}

Expand Down Expand Up @@ -3982,15 +3988,20 @@ public final class org/jetbrains/dokka/pages/ListStyle : java/lang/Enum, org/jet
public static fun values ()[Lorg/jetbrains/dokka/pages/ListStyle;
}

public abstract interface class org/jetbrains/dokka/pages/MemberPage : org/jetbrains/dokka/pages/ContentPage {
public abstract interface class org/jetbrains/dokka/pages/MemberPage : org/jetbrains/dokka/pages/ContentPage, org/jetbrains/dokka/pages/WithDocumentables {
}

public final class org/jetbrains/dokka/pages/MemberPage$DefaultImpls {
public static fun getDocumentable (Lorg/jetbrains/dokka/pages/MemberPage;)Lorg/jetbrains/dokka/model/Documentable;
}

public final class org/jetbrains/dokka/pages/MemberPageNode : org/jetbrains/dokka/pages/MemberPage {
public fun <init> (Ljava/lang/String;Lorg/jetbrains/dokka/pages/ContentNode;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/pages/ContentNode;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/pages/ContentNode;Ljava/util/Set;Ljava/util/List;Ljava/util/List;Ljava/util/List;)V
public synthetic fun <init> (Ljava/lang/String;Lorg/jetbrains/dokka/pages/ContentNode;Ljava/util/Set;Ljava/util/List;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;
public fun getDocumentables ()Ljava/util/List;
public fun getDri ()Ljava/util/Set;
public fun getEmbeddedResources ()Ljava/util/List;
public fun getName ()Ljava/lang/String;
Expand All @@ -4000,15 +4011,20 @@ public final class org/jetbrains/dokka/pages/MemberPageNode : org/jetbrains/dokk
public fun modified (Ljava/lang/String;Lorg/jetbrains/dokka/pages/ContentNode;Ljava/util/Set;Ljava/util/List;Ljava/util/List;)Lorg/jetbrains/dokka/pages/MemberPageNode;
}

public abstract interface class org/jetbrains/dokka/pages/ModulePage : org/jetbrains/dokka/pages/ContentPage {
public abstract interface class org/jetbrains/dokka/pages/ModulePage : org/jetbrains/dokka/pages/ContentPage, org/jetbrains/dokka/pages/WithDocumentables {
}

public final class org/jetbrains/dokka/pages/ModulePage$DefaultImpls {
public static fun getDocumentable (Lorg/jetbrains/dokka/pages/ModulePage;)Lorg/jetbrains/dokka/model/Documentable;
}

public final class org/jetbrains/dokka/pages/ModulePageNode : org/jetbrains/dokka/pages/RootPageNode, org/jetbrains/dokka/pages/ModulePage {
public fun <init> (Ljava/lang/String;Lorg/jetbrains/dokka/pages/ContentNode;Lorg/jetbrains/dokka/model/Documentable;Ljava/util/List;Ljava/util/List;)V
public synthetic fun <init> (Ljava/lang/String;Lorg/jetbrains/dokka/pages/ContentNode;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/pages/ContentNode;Ljava/util/List;Ljava/util/List;Ljava/util/List;)V
public synthetic fun <init> (Ljava/lang/String;Lorg/jetbrains/dokka/pages/ContentNode;Ljava/util/List;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;
public fun getDocumentables ()Ljava/util/List;
public fun getDri ()Ljava/util/Set;
public fun getEmbeddedResources ()Ljava/util/List;
public fun getName ()Ljava/lang/String;
Expand All @@ -4022,6 +4038,10 @@ public final class org/jetbrains/dokka/pages/ModulePageNode : org/jetbrains/dokk
public abstract interface class org/jetbrains/dokka/pages/MultimoduleRootPage : org/jetbrains/dokka/pages/ContentPage {
}

public final class org/jetbrains/dokka/pages/MultimoduleRootPage$DefaultImpls {
public static fun getDocumentable (Lorg/jetbrains/dokka/pages/MultimoduleRootPage;)Lorg/jetbrains/dokka/model/Documentable;
}

public final class org/jetbrains/dokka/pages/MultimoduleRootPageNode : org/jetbrains/dokka/pages/RootPageNode, org/jetbrains/dokka/pages/MultimoduleRootPage {
public fun <init> (Ljava/util/Set;Lorg/jetbrains/dokka/pages/ContentNode;Ljava/util/List;)V
public synthetic fun <init> (Ljava/util/Set;Lorg/jetbrains/dokka/pages/ContentNode;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
Expand All @@ -4041,15 +4061,20 @@ public final class org/jetbrains/dokka/pages/MultimoduleTable : org/jetbrains/do
public static final field INSTANCE Lorg/jetbrains/dokka/pages/MultimoduleTable;
}

public abstract interface class org/jetbrains/dokka/pages/PackagePage : org/jetbrains/dokka/pages/ContentPage {
public abstract interface class org/jetbrains/dokka/pages/PackagePage : org/jetbrains/dokka/pages/ContentPage, org/jetbrains/dokka/pages/WithDocumentables {
}

public final class org/jetbrains/dokka/pages/PackagePage$DefaultImpls {
public static fun getDocumentable (Lorg/jetbrains/dokka/pages/PackagePage;)Lorg/jetbrains/dokka/model/Documentable;
}

public final class org/jetbrains/dokka/pages/PackagePageNode : org/jetbrains/dokka/pages/PackagePage {
public fun <init> (Ljava/lang/String;Lorg/jetbrains/dokka/pages/ContentNode;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/pages/ContentNode;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/pages/ContentNode;Ljava/util/Set;Ljava/util/List;Ljava/util/List;Ljava/util/List;)V
public synthetic fun <init> (Ljava/lang/String;Lorg/jetbrains/dokka/pages/ContentNode;Ljava/util/Set;Ljava/util/List;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;
public fun getDocumentables ()Ljava/util/List;
public fun getDri ()Ljava/util/Set;
public fun getEmbeddedResources ()Ljava/util/List;
public fun getName ()Ljava/lang/String;
Expand Down Expand Up @@ -4264,6 +4289,10 @@ public final class org/jetbrains/dokka/pages/UtilsKt {
public static final fun recursiveMapTransform (Lorg/jetbrains/dokka/pages/ContentNode;Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/dokka/pages/ContentNode;
}

public abstract interface class org/jetbrains/dokka/pages/WithDocumentables {
public abstract fun getDocumentables ()Ljava/util/List;
}

public final class org/jetbrains/dokka/pages/WrongRendererTypeException : java/lang/Exception {
public fun <init> (Lkotlin/reflect/KClass;)V
public final fun component1 ()Lkotlin/reflect/KClass;
Expand Down
29 changes: 18 additions & 11 deletions core/src/main/kotlin/pages/PageNodes.kt
Expand Up @@ -18,9 +18,14 @@ interface PageNode : WithChildren<PageNode> {
interface ContentPage : PageNode {
val content: ContentNode
val dri: Set<DRI>
val documentable: Documentable?
vmishenev marked this conversation as resolved.
Show resolved Hide resolved
val embeddedResources: List<String>

@Deprecated("Deprecated. Remove its usages from your code.",
ReplaceWith("documentables.firstOrNull()")
)
val documentable: Documentable?
get() = if (this is WithDocumentables) this.documentables.firstOrNull() else null

fun modified(
name: String = this.name,
content: ContentNode = this.content,
Expand All @@ -30,6 +35,10 @@ interface ContentPage : PageNode {
): ContentPage
}

interface WithDocumentables {
val documentables: List<Documentable>
}

abstract class RootPageNode(val forceTopLevelName: Boolean = false) : PageNode {
val parentMap: Map<PageNode, PageNode> by lazy {
IdentityHashMap<PageNode, PageNode>().apply {
Expand Down Expand Up @@ -64,7 +73,7 @@ abstract class RootPageNode(val forceTopLevelName: Boolean = false) : PageNode {
class ModulePageNode(
override val name: String,
override val content: ContentNode,
override val documentable: Documentable?,
override val documentables: List<Documentable> = listOf(),
override val children: List<PageNode>,
override val embeddedResources: List<String> = listOf()
) : RootPageNode(), ModulePage {
Expand All @@ -81,14 +90,14 @@ class ModulePageNode(
children: List<PageNode>
): ModulePageNode =
if (name == this.name && content === this.content && embeddedResources === this.embeddedResources && children shallowEq this.children) this
else ModulePageNode(name, content, documentable, children, embeddedResources)
else ModulePageNode(name, content, documentables, children, embeddedResources)
}

class PackagePageNode(
override val name: String,
override val content: ContentNode,
override val dri: Set<DRI>,
override val documentable: Documentable?,
override val documentables: List<Documentable> = listOf(),
override val children: List<PageNode>,
override val embeddedResources: List<String> = listOf()
) : PackagePage {
Expand All @@ -108,14 +117,14 @@ class PackagePageNode(
children: List<PageNode>
): PackagePageNode =
if (name == this.name && content === this.content && embeddedResources === this.embeddedResources && children shallowEq this.children) this
else PackagePageNode(name, content, dri, documentable, children, embeddedResources)
else PackagePageNode(name, content, dri, documentables, children, embeddedResources)
}

class ClasslikePageNode(
override val name: String,
override val content: ContentNode,
override val dri: Set<DRI>,
override val documentable: Documentable?,
override val documentables: List<Documentable> = listOf(),
override val children: List<PageNode>,
override val embeddedResources: List<String> = listOf()
) : ClasslikePage {
Expand All @@ -130,14 +139,14 @@ class ClasslikePageNode(
children: List<PageNode>
): ClasslikePageNode =
if (name == this.name && content === this.content && embeddedResources === this.embeddedResources && children shallowEq this.children) this
else ClasslikePageNode(name, content, dri, documentable, children, embeddedResources)
else ClasslikePageNode(name, content, dri, documentables, children, embeddedResources)
}

class MemberPageNode(
override val name: String,
override val content: ContentNode,
override val dri: Set<DRI>,
override val documentable: Documentable?,
override val documentables: List<Documentable> = listOf(),
override val children: List<PageNode> = emptyList(),
override val embeddedResources: List<String> = listOf()
) : MemberPage {
Expand All @@ -152,7 +161,7 @@ class MemberPageNode(
children: List<PageNode>
): MemberPageNode =
if (name == this.name && content === this.content && embeddedResources === this.embeddedResources && children shallowEq this.children) this
else MemberPageNode(name, content, dri, documentable, children, embeddedResources)
else MemberPageNode(name, content, dri, documentables, children, embeddedResources)
}


Expand All @@ -165,8 +174,6 @@ class MultimoduleRootPageNode(

override val children: List<PageNode> = emptyList()

override val documentable: Documentable? = null

override fun modified(name: String, children: List<PageNode>): RootPageNode =
MultimoduleRootPageNode(dri, content, embeddedResources)

Expand Down
8 changes: 4 additions & 4 deletions core/src/main/kotlin/pages/Pages.kt
Expand Up @@ -2,10 +2,10 @@ package org.jetbrains.dokka.pages

interface MultimoduleRootPage : ContentPage

interface ModulePage : ContentPage
interface ModulePage : ContentPage, WithDocumentables

interface PackagePage : ContentPage
interface PackagePage : ContentPage, WithDocumentables

interface ClasslikePage : ContentPage
interface ClasslikePage : ContentPage, WithDocumentables

interface MemberPage : ContentPage
interface MemberPage : ContentPage, WithDocumentables
6 changes: 6 additions & 0 deletions docs/src/doc/docs/user_guide/base-specific/frontend.md
Expand Up @@ -39,6 +39,12 @@ Keep in mind that this value will be passed exactly to the output html, so it ha
By setting a boolean property `separateInheritedMembers` dokka will split inherited members (like functions, properties etc.)
from ones declared in viewed class. Separated members will have it's own tabs on the page.

## Merging declarations with name clashing

By setting a boolean property `mergeImplicitExpectActualDeclarations` dokka will merge declarations that do not have `expect`/`actual` keywords but have the same fully qualified name.
The declarations will be displayed on one page.
By default, it is disabled. The page names of such declaration have a prefix that is the name of source set.

### Examples
In order to override a logo and style it accordingly a css file named `logo-styles.css` is needed:
```css
Expand Down
18 changes: 17 additions & 1 deletion integration-tests/gradle/projects/stdlib/stdlib.diff
Expand Up @@ -37,7 +37,7 @@ diff --git a/build.gradle b/build.gradle
index aa8f21b..dd6a2ae 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,80 +1,428 @@
@@ -1,80 +1,444 @@
+import org.jetbrains.dokka.Platform
+
plugins {
Expand Down Expand Up @@ -163,6 +163,7 @@ index aa8f21b..dd6a2ae 100644
+ task dokkaStdlib(type: org.jetbrains.dokka.gradle.DokkaTask) {
+ outputDirectory.set(new File(outputDir, "/kotlin-stdlib"))
+ moduleName.set("kotlin-stdlib")
+ pluginsMapConfiguration.set(["org.jetbrains.dokka.base.DokkaBase": """{ "mergeImplicitExpectActualDeclarations": "true" }"""])
+ dokkaSourceSets {
+ register("kotlin-stdlib-common") {
+ skipDeprecated.set(false)
Expand All @@ -179,6 +180,16 @@ index aa8f21b..dd6a2ae 100644
+ sourceRoots.from("$kotlin_root/core/builtins/native")
+ sourceRoots.from("$kotlin_root/core/builtins/src")
+ sourceRoots.from("$kotlin_sources/kotlin-stdlib-common")
+ sourceLink {
+ localDirectory.set(file("$kotlin_sources/kotlin-stdlib-common"))
+ remoteUrl.set(new URL("https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib/common/src"))
+ remoteLineSuffix.set("#L")
+ }
+ sourceLink {
+ localDirectory.set(file("$kotlin_root/core/builtins/src"))
+ remoteUrl.set(new URL("https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib/src"))
+ remoteLineSuffix.set("#L")
+ }
+ }
+
+ register("kotlin-stdlib-java-common") {
Expand Down Expand Up @@ -220,6 +231,11 @@ index aa8f21b..dd6a2ae 100644
+ matchingRegex.set("kotlin.coroutines.experimental.migration(\$|\\.).*")
+ suppress.set(true)
+ }
+ sourceLink {
+ localDirectory.set(file("$kotlin_sources/kotlin-stdlib"))
+ remoteUrl.set(new URL("https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib/jvm/src"))
+ remoteLineSuffix.set("#L")
+ }
+ }
+
+
Expand Down
Expand Up @@ -52,8 +52,8 @@ class StdlibGradleIntegrationTest(override val versions: BuildVersions) : Abstra

projectOutputLocation.allHtmlFiles().forEach { file ->
assertContainsNoErrorClass(file)
// assertNoUnresolvedLinks(file)
// assertNoHrefToMissingLocalFileOrDirectory(file)
assertNoUnresolvedLinks(file)
assertNoHrefToMissingLocalFileOrDirectory(file)
assertNoEmptyLinks(file)
assertNoEmptySpans(file)
assertNoUnsubstitutedTemplatesInHtml(file)
Expand Down
Expand Up @@ -71,7 +71,7 @@ abstract class AbstractIntegrationTest {
hrefSplits.first()
} else href

val targetFile = if (href.startsWith("file")) {
val targetFile = if (href.startsWith("file:/")) {
File(URL(hrefWithoutAnchors).path)
} else {
File(file.parent, hrefWithoutAnchors)
Expand Down