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

Custom doctag extension #2343

Merged
merged 8 commits into from Feb 17, 2022
1 change: 1 addition & 0 deletions core/api/core.api
Expand Up @@ -4216,6 +4216,7 @@ public final class org/jetbrains/dokka/pages/TextStyle : java/lang/Enum, org/jet
public static final field BreakableAfter Lorg/jetbrains/dokka/pages/TextStyle;
public static final field Cover Lorg/jetbrains/dokka/pages/TextStyle;
public static final field Indented Lorg/jetbrains/dokka/pages/TextStyle;
public static final field InlineComment Lorg/jetbrains/dokka/pages/TextStyle;
public static final field Italic Lorg/jetbrains/dokka/pages/TextStyle;
public static final field Monospace Lorg/jetbrains/dokka/pages/TextStyle;
public static final field Paragraph Lorg/jetbrains/dokka/pages/TextStyle;
Expand Down
3 changes: 2 additions & 1 deletion core/src/main/kotlin/pages/ContentNodes.kt
Expand Up @@ -383,7 +383,8 @@ enum class TokenStyle : Style {
}

enum class TextStyle : Style {
Bold, Italic, Strong, Strikethrough, Paragraph, Block, Span, Monospace, Indented, Cover, UnderCoverText, BreakableAfter, Breakable
Bold, Italic, Strong, Strikethrough, Paragraph,
Block, Span, Monospace, Indented, Cover, UnderCoverText, BreakableAfter, Breakable, InlineComment
}

enum class ContentStyle : Style {
Expand Down
25 changes: 23 additions & 2 deletions plugins/base/api/base.api
Expand Up @@ -5,6 +5,7 @@ public final class org/jetbrains/dokka/base/DokkaBase : org/jetbrains/dokka/plug
public final fun getBaseSearchbarDataInstaller ()Lorg/jetbrains/dokka/plugability/Extension;
public final fun getCommentsToContentConverter ()Lorg/jetbrains/dokka/plugability/ExtensionPoint;
public final fun getCustomResourceInstaller ()Lorg/jetbrains/dokka/plugability/Extension;
public final fun getCustomTagContentProvider ()Lorg/jetbrains/dokka/plugability/ExtensionPoint;
public final fun getDefaultExternalClasslikesTranslator ()Lorg/jetbrains/dokka/plugability/Extension;
public final fun getDefaultExternalDocumentablesProvider ()Lorg/jetbrains/dokka/plugability/Extension;
public final fun getDefaultKotlinAnalysis ()Lorg/jetbrains/dokka/plugability/Extension;
Expand Down Expand Up @@ -52,6 +53,7 @@ public final class org/jetbrains/dokka/base/DokkaBase : org/jetbrains/dokka/plug
public final fun getSameMethodNameMerger ()Lorg/jetbrains/dokka/plugability/Extension;
public final fun getScriptsInstaller ()Lorg/jetbrains/dokka/plugability/Extension;
public final fun getSignatureProvider ()Lorg/jetbrains/dokka/plugability/ExtensionPoint;
public final fun getSinceKotlinTagContentProvider ()Lorg/jetbrains/dokka/plugability/Extension;
public final fun getSinceKotlinTransformer ()Lorg/jetbrains/dokka/plugability/Extension;
public final fun getSingleGeneration ()Lorg/jetbrains/dokka/plugability/Extension;
public final fun getSourceLinksTransformer ()Lorg/jetbrains/dokka/plugability/Extension;
Expand Down Expand Up @@ -1267,6 +1269,24 @@ public final class org/jetbrains/dokka/base/transformers/pages/sourcelinks/Sourc
public static final fun hasTabbedContent (Lorg/jetbrains/dokka/pages/ContentGroup;)Z
}

public abstract interface class org/jetbrains/dokka/base/transformers/pages/tags/CustomTagContentProvider {
public abstract fun contentForBrief (Lorg/jetbrains/dokka/base/translators/documentables/PageContentBuilder$DocumentableContentBuilder;Lorg/jetbrains/dokka/DokkaConfiguration$DokkaSourceSet;Lorg/jetbrains/dokka/model/doc/CustomTagWrapper;)V
public abstract fun contentForDescription (Lorg/jetbrains/dokka/base/translators/documentables/PageContentBuilder$DocumentableContentBuilder;Lorg/jetbrains/dokka/DokkaConfiguration$DokkaSourceSet;Lorg/jetbrains/dokka/model/doc/CustomTagWrapper;)V
public abstract fun isApplicable (Lorg/jetbrains/dokka/model/doc/CustomTagWrapper;)Z
}

public final class org/jetbrains/dokka/base/transformers/pages/tags/CustomTagContentProvider$DefaultImpls {
public static fun contentForBrief (Lorg/jetbrains/dokka/base/transformers/pages/tags/CustomTagContentProvider;Lorg/jetbrains/dokka/base/translators/documentables/PageContentBuilder$DocumentableContentBuilder;Lorg/jetbrains/dokka/DokkaConfiguration$DokkaSourceSet;Lorg/jetbrains/dokka/model/doc/CustomTagWrapper;)V
public static fun contentForDescription (Lorg/jetbrains/dokka/base/transformers/pages/tags/CustomTagContentProvider;Lorg/jetbrains/dokka/base/translators/documentables/PageContentBuilder$DocumentableContentBuilder;Lorg/jetbrains/dokka/DokkaConfiguration$DokkaSourceSet;Lorg/jetbrains/dokka/model/doc/CustomTagWrapper;)V
}

public final class org/jetbrains/dokka/base/transformers/pages/tags/SinceKotlinTagContentProvider : org/jetbrains/dokka/base/transformers/pages/tags/CustomTagContentProvider {
public static final field INSTANCE Lorg/jetbrains/dokka/base/transformers/pages/tags/SinceKotlinTagContentProvider;
public fun contentForBrief (Lorg/jetbrains/dokka/base/translators/documentables/PageContentBuilder$DocumentableContentBuilder;Lorg/jetbrains/dokka/DokkaConfiguration$DokkaSourceSet;Lorg/jetbrains/dokka/model/doc/CustomTagWrapper;)V
public fun contentForDescription (Lorg/jetbrains/dokka/base/translators/documentables/PageContentBuilder$DocumentableContentBuilder;Lorg/jetbrains/dokka/DokkaConfiguration$DokkaSourceSet;Lorg/jetbrains/dokka/model/doc/CustomTagWrapper;)V
public fun isApplicable (Lorg/jetbrains/dokka/model/doc/CustomTagWrapper;)Z
}

public final class org/jetbrains/dokka/base/translators/descriptors/DRIWithPlatformInfo {
public fun <init> (Lorg/jetbrains/dokka/links/DRI;Ljava/util/Map;)V
public final fun component1 ()Lorg/jetbrains/dokka/links/DRI;
Expand Down Expand Up @@ -1319,7 +1339,8 @@ public final class org/jetbrains/dokka/base/translators/documentables/DefaultDoc
}

public class org/jetbrains/dokka/base/translators/documentables/DefaultPageCreator {
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;)V
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 contentForComments (Lorg/jetbrains/dokka/model/Documentable;Z)Ljava/util/List;
Expand All @@ -1332,10 +1353,10 @@ public class org/jetbrains/dokka/base/translators/documentables/DefaultPageCreat
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 (Lorg/jetbrains/dokka/model/WithScope;Lorg/jetbrains/dokka/links/DRI;Ljava/util/Set;)Lorg/jetbrains/dokka/pages/ContentGroup;
protected fun contentForSinceKotlin (Lorg/jetbrains/dokka/base/translators/documentables/PageContentBuilder$DocumentableContentBuilder;Lorg/jetbrains/dokka/model/Documentable;)V
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 getSeparateInheritedMembers ()Z
public fun pageForClasslike (Lorg/jetbrains/dokka/model/DClasslike;)Lorg/jetbrains/dokka/pages/ClasslikePageNode;
Expand Down
7 changes: 7 additions & 0 deletions plugins/base/src/main/kotlin/DokkaBase.kt
Expand Up @@ -29,6 +29,8 @@ import org.jetbrains.dokka.base.translators.documentables.DefaultDocumentableToP
import org.jetbrains.dokka.base.translators.psi.DefaultPsiToDocumentableTranslator
import org.jetbrains.dokka.base.generation.SingleModuleGeneration
import org.jetbrains.dokka.base.renderers.html.command.consumers.ReplaceVersionsConsumer
import org.jetbrains.dokka.base.transformers.pages.tags.CustomTagContentProvider
import org.jetbrains.dokka.base.transformers.pages.tags.SinceKotlinTagContentProvider
import org.jetbrains.dokka.base.translators.descriptors.DefaultExternalDocumentablesProvider
import org.jetbrains.dokka.base.translators.descriptors.ExternalClasslikesTranslator
import org.jetbrains.dokka.base.translators.descriptors.ExternalDocumentablesProvider
Expand All @@ -41,6 +43,7 @@ class DokkaBase : DokkaPlugin() {
val preMergeDocumentableTransformer by extensionPoint<PreMergeDocumentableTransformer>()
val pageMergerStrategy by extensionPoint<PageMergerStrategy>()
val commentsToContentConverter by extensionPoint<CommentsToContentConverter>()
val customTagContentProvider by extensionPoint<CustomTagContentProvider>()
val signatureProvider by extensionPoint<SignatureProvider>()
val locationProviderFactory by extensionPoint<LocationProviderFactory>()
val externalLocationProviderFactory by extensionPoint<ExternalLocationProviderFactory>()
Expand Down Expand Up @@ -151,6 +154,10 @@ class DokkaBase : DokkaPlugin() {
commentsToContentConverter with DocTagToContentConverter()
}

val sinceKotlinTagContentProvider by extending {
customTagContentProvider with SinceKotlinTagContentProvider
}

val pageMerger by extending {
CoreExtensions.pageTransformer providing ::PageMerger
}
Expand Down
Expand Up @@ -113,6 +113,7 @@ open class HtmlRenderer(
childrenCallback()
}
}
node.hasStyle(TextStyle.InlineComment) -> div("inline-comment") { childrenCallback() }
node.dci.kind == ContentKind.BriefComment -> div("brief $additionalClasses") { childrenCallback() }
node.dci.kind == ContentKind.Cover -> div("cover $additionalClasses") { //TODO this can be removed
childrenCallback()
Expand Down
@@ -0,0 +1,59 @@
package org.jetbrains.dokka.base.transformers.pages.tags

import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet
import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder.DocumentableContentBuilder
import org.jetbrains.dokka.model.doc.CustomTagWrapper
import org.jetbrains.dokka.model.doc.DocTag

/**
* Provides an ability to render custom doc tags
*
* Custom tags can be generated during build, for instance via transformers from converting an annotation
* (such as in [org.jetbrains.dokka.base.transformers.pages.annotations.SinceKotlinTransformer])
*
* Also, custom tags can come from the kdoc itself, where "custom" is defined as unknown to the compiler/spec.
* `@property` and `@throws` are not custom tags - they are defined by the spec and have special meaning
* and separate blocks on the documentation page, it's clear how to render it. Whereas `@usesMathJax` is
* a custom tag - it's application/plugin specific and is not handled by dokka by default.
*
* Using this provider, we can map custom tags (such as `@usesMathJax`) and generate content for it that
* will be displayed on the pages.
*/
interface CustomTagContentProvider {

/**
* Whether this content provider supports given [CustomTagWrapper].
*
* Tags can be filtered out either by name or by nested [DocTag] type
*/
fun isApplicable(customTag: CustomTagWrapper): Boolean

/**
* Full blown content description, most likely to be on a separate page
* dedicated to just one element (i.e one class/function), so any
* amount of detail should be fine.
*/
fun DocumentableContentBuilder.contentForDescription(
sourceSet: DokkaSourceSet,
customTag: CustomTagWrapper
) {}

/**
* Brief comment section, usually displayed as a summary/preview.
*
* For instance, when listing all functions of a class on one page,
* it'll be too much to display complete documentation for each function.
* Instead, a small brief is shown for each one (i.e the first paragraph
* or some other important information) - the user can go to the dedicated
* page for more details if they find the brief interesting.
*
* Tag-wise, it would make sense to include `Since Kotlin`, since it's
* important information for the users of stdlib. It would make little
* sense to include `@usesMathjax` here, as this information seems
* to be more specific and detailed than is needed for a brief.
*/
fun DocumentableContentBuilder.contentForBrief(
sourceSet: DokkaSourceSet,
customTag: CustomTagWrapper
) {}
}
@@ -0,0 +1,34 @@
package org.jetbrains.dokka.base.transformers.pages.tags

import org.jetbrains.dokka.DokkaConfiguration
import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder.DocumentableContentBuilder
import org.jetbrains.dokka.model.doc.CustomTagWrapper
import org.jetbrains.dokka.pages.ContentKind
import org.jetbrains.dokka.pages.TextStyle

object SinceKotlinTagContentProvider : CustomTagContentProvider {

private const val SINCE_KOTLIN_TAG_NAME = "Since Kotlin"

override fun isApplicable(customTag: CustomTagWrapper) = customTag.name == SINCE_KOTLIN_TAG_NAME

override fun DocumentableContentBuilder.contentForDescription(
sourceSet: DokkaConfiguration.DokkaSourceSet,
customTag: CustomTagWrapper
) {
group(sourceSets = setOf(sourceSet), kind = ContentKind.Comment, styles = setOf(TextStyle.Block)) {
header(4, customTag.name)
comment(customTag.root)
}
}

override fun DocumentableContentBuilder.contentForBrief(
sourceSet: DokkaConfiguration.DokkaSourceSet,
customTag: CustomTagWrapper
) {
group(sourceSets = setOf(sourceSet), styles = setOf(TextStyle.InlineComment)) {
text(customTag.name + " ", styles = setOf(TextStyle.Bold))
comment(customTag.root, styles = emptySet())
}
}
}
Expand Up @@ -4,10 +4,7 @@ import org.jetbrains.dokka.base.DokkaBase
import org.jetbrains.dokka.base.DokkaBaseConfiguration
import org.jetbrains.dokka.model.DModule
import org.jetbrains.dokka.pages.ModulePageNode
import org.jetbrains.dokka.plugability.configuration
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.plugability.plugin
import org.jetbrains.dokka.plugability.querySingle
import org.jetbrains.dokka.plugability.*
import org.jetbrains.dokka.transformers.documentation.DocumentableToPageTranslator

class DefaultDocumentableToPageTranslator(
Expand All @@ -16,8 +13,15 @@ class DefaultDocumentableToPageTranslator(
private val configuration = configuration<DokkaBase, DokkaBaseConfiguration>(context)
private val commentsToContentConverter = context.plugin<DokkaBase>().querySingle { commentsToContentConverter }
private val signatureProvider = context.plugin<DokkaBase>().querySingle { signatureProvider }
private val customTagContentProviders = context.plugin<DokkaBase>().query { customTagContentProvider }
private val logger = context.logger

override fun invoke(module: DModule): ModulePageNode =
DefaultPageCreator(configuration, commentsToContentConverter, signatureProvider, logger).pageForModule(module)
DefaultPageCreator(
configuration,
commentsToContentConverter,
signatureProvider,
logger,
customTagContentProviders
).pageForModule(module)
}