diff options
Diffstat (limited to 'plugins/base/src/main/kotlin')
4 files changed, 93 insertions, 48 deletions
diff --git a/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt index a5d6540e..b69c43d3 100644 --- a/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt @@ -2,6 +2,8 @@ package org.jetbrains.dokka.base.transformers.documentables import org.jetbrains.dokka.model.DModule import org.jetbrains.dokka.model.PlatformDependent +import org.jetbrains.dokka.model.doc.DocumentationNode +import org.jetbrains.dokka.pages.PlatformData import org.jetbrains.dokka.parsers.MarkdownParser import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.transformers.documentation.PreMergeDocumentableTransformer @@ -66,15 +68,15 @@ internal object ModuleAndPackageDocumentationTransformer : PreMergeDocumentableT } }.toMap() - val packagesDocumentation = module.packages.map { - it.name to it.platformData.mapNotNull { pd -> - val doc = modulesAndPackagesDocumentation[Pair(module.name, pd)] - val facade = context.platforms[pd]?.facade - ?: return@mapNotNull null.also { context.logger.warn("Could not find platform data for ${pd.name}") } - val descriptor = facade.resolveSession.getPackageFragment(FqName(it.name)) - ?: return@mapNotNull null.also { context.logger.warn("Could not find descriptor for $") } - doc?.get("Package")?.get(it.name)?.run { - pd to MarkdownParser( + val packagesDocumentation = module.packages.map { dPackage -> + dPackage.name to dPackage.platformData.mapNotNull { platformData -> + val doc = modulesAndPackagesDocumentation[Pair(module.name, platformData)] + val facade = context.platforms[platformData]?.facade + ?: return@mapNotNull null.also { context.logger.warn("Could not find platform data for ${platformData.name}") } + val descriptor = facade.resolveSession.getPackageFragment(FqName(dPackage.name)) + ?: return@mapNotNull null.also { context.logger.warn("Could not find descriptor for ${dPackage.name}") } + doc?.get("Package")?.get(dPackage.name)?.run { + platformData to MarkdownParser( facade, descriptor, context.logger @@ -84,11 +86,12 @@ internal object ModuleAndPackageDocumentationTransformer : PreMergeDocumentableT }.toMap() module.copy( - documentation = module.documentation.let { PlatformDependent(it.map + moduleDocumentation) }, + documentation = module.documentation.let { mergeDocumentation(it.map, moduleDocumentation) }, packages = module.packages.map { - if (packagesDocumentation[it.name] != null) + val packageDocumentation = packagesDocumentation[it.name] + if (packageDocumentation != null && packageDocumentation.isNotEmpty()) it.copy(documentation = it.documentation.let { value -> - PlatformDependent(value.map + packagesDocumentation[it.name]!!) + mergeDocumentation(value.map, packageDocumentation) }) else it @@ -96,4 +99,11 @@ internal object ModuleAndPackageDocumentationTransformer : PreMergeDocumentableT ) } } + + private fun mergeDocumentation(origin: Map<PlatformData, DocumentationNode>, new: Map<PlatformData, DocumentationNode>) = PlatformDependent( + (origin.asSequence() + new.asSequence()) + .distinct() + .groupBy({ it.key }, { it.value }) + .mapValues { (_, values) -> DocumentationNode(values.flatMap { it.children }) } + ) } 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 bd10a923..b41b07f5 100644 --- a/plugins/base/src/main/kotlin/transformers/pages/samples/SamplesTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/pages/samples/SamplesTransformer.kt @@ -6,6 +6,7 @@ import org.jetbrains.dokka.EnvironmentAndFacade import org.jetbrains.dokka.Platform import org.jetbrains.dokka.analysis.AnalysisEnvironment import org.jetbrains.dokka.analysis.DokkaResolutionFacade +import org.jetbrains.dokka.base.renderers.platforms import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.model.doc.Sample import org.jetbrains.dokka.model.properties.PropertyContainer @@ -30,9 +31,9 @@ abstract class SamplesTransformer(val context: DokkaContext) : PageTransformer { val analysis = setUpAnalysis(context) return input.transformContentPagesTree { page -> - page.documentable?.documentation?.map?.entries?.fold(page) { acc, entry -> - entry.value.children.filterIsInstance<Sample>().fold(acc) { acc, sample -> - acc.modified(content = acc.content.addSample(page, entry.key, sample.name, analysis)) + page.documentable?.documentation?.allEntries?.fold(page) { acc, entry -> + entry.second.children.filterIsInstance<Sample>().fold(acc) { acc, sample -> + acc.modified(content = acc.content.addSample(page, entry.first, sample.name, analysis)) } } ?: page } @@ -55,19 +56,35 @@ abstract class SamplesTransformer(val context: DokkaContext) : PageTransformer { } }.toMap() - private fun ContentNode.addSample(contentPage: ContentPage, platform: PlatformData, fqName: String, analysis: Map<PlatformData, EnvironmentAndFacade>): ContentNode { - val facade = analysis[platform]?.facade ?: - return this.also { context.logger.warn("Cannot resolve facade for platform ${platform.name}")} + private fun ContentNode.addSample(contentPage: ContentPage, platform: PlatformData?, fqName: String, analysis: Map<PlatformData, EnvironmentAndFacade>): ContentNode { + val facade = if(platform == null) { + analysis.entries.find { it.key.platformType.name == "common" }?.value + } else { + analysis[platform] + }?.facade ?: return this.also { context.logger.warn("Cannot resolve facade for platform ${platform?.name ?: "expect"}") } val psiElement = fqNameToPsiElement(facade, fqName) ?: return this.also { context.logger.warn("Cannot find PsiElement corresponding to $fqName") } val imports = processImports(psiElement) // TODO: Process somehow imports. Maybe just attach them at the top of each body val body = processBody(psiElement) - val node = platformHintedContentCode(platform, contentPage.dri, body, "kotlin") - return this.safeAs<ContentGroup>()?.run { copy( - children = children.indexOfFirst { contentNode -> - contentNode.safeAs<ContentHeader>()?.children?.firstOrNull()?.safeAs<ContentText>()?.text == "Sample" - }.takeIf { it != -1 }?.let { children.apply { this.safeAs<MutableList<ContentNode>>()?.add(it+1, node) } } ?: children.also { context.logger.warn("Not found Sample block in ${contentPage.dri}")} - ) } ?: this.also { context.logger.warn("ContentPage ${contentPage.dri} cannot be cast to ContentGroup") } + val node = contentCode(contentPage.platforms(), contentPage.dri, body, "kotlin") + + return bfs(fqName, node) + } + + private fun ContentNode.bfs(fqName: String, node: ContentCode): ContentNode { + return when(this) { + is ContentHeader -> copy(children.map { it.bfs(fqName, node) }) + is ContentCode -> copy(children.map { it.bfs(fqName, node) }) + is ContentDRILink -> copy(children.map { it.bfs(fqName, node) }) + is ContentResolvedLink -> copy(children.map { it.bfs(fqName, node) }) + is ContentEmbeddedResource -> copy(children.map { it.bfs(fqName, node) }) + is ContentTable -> copy(children.map { it.bfs(fqName, node) as ContentGroup }) + is ContentList -> copy(children.map { it.bfs(fqName, node) }) + is ContentGroup -> copy(children.map { it.bfs(fqName, node) }) + is PlatformHintedContent -> copy(inner.bfs(fqName, node)) + is ContentText -> if (text == fqName) node else this + else -> this + } } private fun fqNameToPsiElement(resolutionFacade: DokkaResolutionFacade, functionName: String): PsiElement? { @@ -79,24 +96,21 @@ abstract class SamplesTransformer(val context: DokkaContext) : PageTransformer { return DescriptorToSourceUtils.descriptorToDeclaration(symbol) } - private fun platformHintedContentCode(platformData: PlatformData, dri: Set<DRI>, content: String, language: String) = - PlatformHintedContent( - inner = ContentCode( - children = listOf( - ContentText( - text = content, - dci = DCI(dri, ContentKind.BriefComment), - platforms = setOf(platformData), - style = emptySet(), - extra = PropertyContainer.empty() - ) - ), - language = language, - extra = PropertyContainer.empty(), - dci = DCI(dri, ContentKind.Source), - platforms = setOf(platformData), - style = emptySet() + private fun contentCode(platforms: List<PlatformData>, dri: Set<DRI>, content: String, language: String) = + ContentCode( + children = listOf( + ContentText( + text = content, + dci = DCI(dri, ContentKind.BriefComment), + platforms = platforms.toSet(), + style = emptySet(), + extra = PropertyContainer.empty() + ) ), - platforms = setOf(platformData) + language = language, + extra = PropertyContainer.empty(), + dci = DCI(dri, ContentKind.Source), + platforms = platforms.toSet(), + style = emptySet() ) }
\ No newline at end of file diff --git a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt index be18c592..00e3239c 100644 --- a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt +++ b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt @@ -500,12 +500,15 @@ private class DokkaDescriptorVisitor( .filter { it.kind == ClassKind.ENUM_ENTRY } .map { enumEntryDescriptor(it, parent) } - - private fun DeclarationDescriptor.resolveDescriptorData(platformData: PlatformData?): PlatformDependent<DocumentationNode> = - if (platformData != null) PlatformDependent.from( - platformData, - getDocumentation() - ) else PlatformDependent.expectFrom(getDocumentation()) + private fun DeclarationDescriptor.resolveDescriptorData(platformData: PlatformData?): PlatformDependent<DocumentationNode> { + val documentation = getDocumentation() + return if (documentation.children.isEmpty()) + PlatformDependent.empty() + else if (platformData != null) + PlatformDependent.from(platformData, documentation) + else + PlatformDependent.expectFrom(documentation) + } private fun ClassDescriptor.resolveClassDescriptionData(platformData: PlatformData?): ClassInfo { return ClassInfo( diff --git a/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt b/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt index 424e6aa4..dd28b533 100644 --- a/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt +++ b/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt @@ -284,6 +284,23 @@ open class DefaultPageCreator( } } + fun DocumentableContentBuilder.contentForSamples() { + val samples = tags.withTypeNamed<Sample>() + if (samples.isNotEmpty()) { + platforms.forEach { platformData -> + val content = samples.filter { it.value.isEmpty() || platformData in it.value } + if (content.isNotEmpty()) { + group(platformData = setOf(platformData)) { + header(4, kind = ContentKind.Comment) { text("Samples") } + content.forEach { + comment(Text(it.key)) + } + } + } + } + } + } + fun DocumentableContentBuilder.contentForUnnamedTags() { val unnamedTags: List<PlatformDependent<TagWrapper>> = tags.filterNot { (k, _) -> k.isSubclassOf(NamedTagWrapper::class) || k in specialTags } @@ -305,6 +322,7 @@ open class DefaultPageCreator( header(3) { text("Description") } platformDependentHint(platformData = platforms.toSet()) { contentForDescription() + contentForSamples() contentForParams() contentForUnnamedTags() contentForSeeAlso() |