Skip to content

Commit

Permalink
Make documentables in page interface
Browse files Browse the repository at this point in the history
  • Loading branch information
vmishenev committed Feb 12, 2022
1 parent 106e3e1 commit 4524224
Show file tree
Hide file tree
Showing 15 changed files with 120 additions and 113 deletions.
29 changes: 18 additions & 11 deletions core/src/main/kotlin/pages/PageNodes.kt
Expand Up @@ -18,7 +18,6 @@ interface PageNode : WithChildren<PageNode> {
interface ContentPage : PageNode {
val content: ContentNode
val dri: Set<DRI>
val documentable: Documentable?
val embeddedResources: List<String>

fun modified(
Expand All @@ -30,6 +29,16 @@ interface ContentPage : PageNode {
): ContentPage
}

interface WithDocumentables {
val documentables: List<Documentable>

@Deprecated("Deprecated. Remove its usages from your code.",
ReplaceWith("documentables.firstOrNull()")
)
val documentable: Documentable?
get() = documentables.firstOrNull()
}

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
@@ -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(
Expand All @@ -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 {
Expand Down
19 changes: 9 additions & 10 deletions 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
Expand All @@ -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
Expand Down
Expand Up @@ -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)
Expand Down
Expand Up @@ -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, sample ->
acc.modified(
content = acc.content.addSample(page, entry.key, sample.name, analysis),
content = acc.content.addSample(page, sample.first, sample.second.name, analysis),
embeddedResources = acc.embeddedResources + kotlinPlaygroundScript
)
}
} ?: page
} ?: page
}
}

Expand Down
@@ -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.*
Expand All @@ -32,10 +32,11 @@ 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) }
?.let { (node as ContentPage).addSourcesContent(it) }
?: node
else -> node
}
Expand Down Expand Up @@ -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 {
Expand Down
Expand Up @@ -40,10 +40,10 @@ open class DefaultPageCreator(
configuration?.separateInheritedMembers ?: DokkaBaseConfiguration.separateInheritedMembersDefault

open fun pageForModule(m: DModule): ModulePageNode =
ModulePageNode(m.name.ifEmpty { "<root>" }, contentForModule(m), m, m.packages.map(::pageForPackage))
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.name, contentForPackage(p), setOf(p.dri), listOf(p),
if (mergeNoExpectActualDeclarations)
p.classlikes.mergeClashingDocumentable().map(::pageForClasslikesAndEntries) +
p.functions.mergeClashingDocumentable().map(::pageForFunctions) +
Expand All @@ -55,7 +55,7 @@ open class DefaultPageCreator(

open fun pageForEnumEntry(e: DEnumEntry): ClasslikePageNode =
ClasslikePageNode(
e.nameAfterClash(), contentForEnumEntry(e), setOf(e.dri), e,
e.nameAfterClash(), contentForEnumEntry(e), setOf(e.dri), listOf(e),
e.classlikes.renameClashingDocumentable().map(::pageForClasslike) +
e.filteredFunctions.renameClashingDocumentable().map(::pageForFunction) +
e.filteredProperties.renameClashingDocumentable().mapNotNull(::pageForProperty)
Expand All @@ -65,7 +65,7 @@ open class DefaultPageCreator(
val constructors = if (c is WithConstructors) c.constructors else emptyList()

return ClasslikePageNode(
c.nameAfterClash(), contentForClasslike(c), setOf(c.dri), c,
c.nameAfterClash(), contentForClasslike(c), setOf(c.dri), listOf(c),
constructors.map(::pageForFunction) +
c.classlikes.renameClashingDocumentable().map(::pageForClasslike) +
c.filteredFunctions.renameClashingDocumentable().map(::pageForFunction) +
Expand Down Expand Up @@ -104,7 +104,7 @@ open class DefaultPageCreator(


return ClasslikePageNode(
documentables.first().nameAfterClash(), contentForClasslikesAndEntries(documentables), dri, documentables.singleOrNull(),
documentables.first().nameAfterClash(), contentForClasslikesAndEntries(documentables), dri, documentables,
childrenPages
)
}
Expand Down Expand Up @@ -138,23 +138,23 @@ open class DefaultPageCreator(
private fun <T : Documentable> List<T>.mergeClashingDocumentable(): List<List<T>> =
groupBy { it.dri.copy(extra = null) }.values.toList()

open fun pageForFunction(f: DFunction) = MemberPageNode(f.nameAfterClash(), contentForFunction(f), setOf(f.dri), f)
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.singleOrNull())
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.singleOrNull())
return MemberPageNode(ps.first().nameAfterClash(), contentForMembers(ps), dri, ps)
}

private fun <T> T.isInherited(): Boolean where T : Documentable, T : WithExtraProperties<T> =
Expand Down

0 comments on commit 4524224

Please sign in to comment.