aboutsummaryrefslogtreecommitdiff
path: root/plugins/base/src
diff options
context:
space:
mode:
authorvmishenev <vad-mishenev@yandex.ru>2021-08-25 17:14:31 +0300
committerGitHub <noreply@github.com>2021-08-25 16:14:31 +0200
commit4fa9524e52d8ff422bb355336e3810ab28ae135c (patch)
tree66d2bc381ffc7d5c598cee4ea9e0ba13f81b1d7b /plugins/base/src
parent742f96bdf5c0b842e68dfaf43f4ab3446e87e3df (diff)
downloaddokka-4fa9524e52d8ff422bb355336e3810ab28ae135c.tar.gz
dokka-4fa9524e52d8ff422bb355336e3810ab28ae135c.tar.bz2
dokka-4fa9524e52d8ff422bb355336e3810ab28ae135c.zip
Manual highlighting webhelp (#2079)
* Add manual code highlighting * Fix test * Add kotlinAsJava highlighting * Add runtime highlighting via Prism * Add copy-button for code block * Add tests and refactor * Replace `<br>` for prism.js * Parse trivial default values Co-authored-by: Marcin Aman <marcin.aman@gmail.com>
Diffstat (limited to 'plugins/base/src')
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt15
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt4
-rw-r--r--plugins/base/src/main/kotlin/signatures/JvmSignatureUtils.kt25
-rw-r--r--plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt165
-rw-r--r--plugins/base/src/main/kotlin/transformers/pages/comments/DocTagToContentConverter.kt2
-rw-r--r--plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt31
-rw-r--r--plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt18
-rw-r--r--plugins/base/src/main/resources/dokka/scripts/prism.js13
-rw-r--r--plugins/base/src/main/resources/dokka/styles/prism.css92
-rw-r--r--plugins/base/src/main/resources/dokka/styles/style.css12
-rw-r--r--plugins/base/src/test/kotlin/content/HighlightingTest.kt79
-rw-r--r--plugins/base/src/test/kotlin/enums/EnumsTest.kt8
-rw-r--r--plugins/base/src/test/kotlin/model/FunctionsTest.kt4
-rw-r--r--plugins/base/src/test/kotlin/renderers/html/TextStylesTest.kt17
-rw-r--r--plugins/base/src/test/kotlin/signatures/FunctionalTypeConstructorsSignatureTest.kt33
-rw-r--r--plugins/base/src/test/kotlin/signatures/SignatureTest.kt74
-rw-r--r--plugins/base/src/test/kotlin/signatures/VarianceSignatureTest.kt12
17 files changed, 450 insertions, 154 deletions
diff --git a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt
index 3cf914ce..31753332 100644
--- a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt
+++ b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt
@@ -677,13 +677,15 @@ open class HtmlRenderer(
pageContext: ContentPage
) {
div("sample-container") {
- val stylesWithBlock = code.style + TextStyle.Block
- code(stylesWithBlock.joinToString(" ") { it.toString().toLowerCase() }) {
- attributes["theme"] = "idea"
- pre {
+ val codeLang = "lang-" + code.language.ifEmpty { "kotlin" }
+ val stylesWithBlock = code.style + TextStyle.Block + codeLang
+ pre {
+ code(stylesWithBlock.joinToString(" ") { it.toString().toLowerCase() }) {
+ attributes["theme"] = "idea"
code.children.forEach { buildContentNode(it, pageContext) }
}
}
+ copyButton()
}
}
@@ -691,7 +693,9 @@ open class HtmlRenderer(
code: ContentCodeInline,
pageContext: ContentPage
) {
- code {
+ val codeLang = "lang-" + code.language.ifEmpty { "kotlin" }
+ val stylesWithBlock = code.style + codeLang
+ code(stylesWithBlock.joinToString(" ") { it.toString().toLowerCase() }) {
code.children.forEach { buildContentNode(it, pageContext) }
}
}
@@ -725,6 +729,7 @@ open class HtmlRenderer(
TextStyle.Italic -> i { body() }
TextStyle.Strikethrough -> strike { body() }
TextStyle.Strong -> strong { body() }
+ is TokenStyle -> span("token " + styleToApply.toString().toLowerCase()) { body() }
else -> body()
}
}
diff --git a/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt b/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt
index 9faf4d17..347e16bf 100644
--- a/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt
+++ b/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt
@@ -87,6 +87,7 @@ class ScriptsInstaller(private val dokkaContext: DokkaContext) : PageTransformer
"scripts/navigation-loader.js",
"scripts/platform-content-handler.js",
"scripts/main.js",
+ "scripts/prism.js"
)
override fun invoke(input: RootPageNode): RootPageNode =
@@ -104,7 +105,8 @@ class StylesInstaller(private val dokkaContext: DokkaContext) : PageTransformer
private val stylesPages = listOf(
"styles/style.css",
"styles/jetbrains-mono.css",
- "styles/main.css"
+ "styles/main.css",
+ "styles/prism.css"
)
override fun invoke(input: RootPageNode): RootPageNode =
diff --git a/plugins/base/src/main/kotlin/signatures/JvmSignatureUtils.kt b/plugins/base/src/main/kotlin/signatures/JvmSignatureUtils.kt
index d17fa276..94af96e2 100644
--- a/plugins/base/src/main/kotlin/signatures/JvmSignatureUtils.kt
+++ b/plugins/base/src/main/kotlin/signatures/JvmSignatureUtils.kt
@@ -8,7 +8,6 @@ import org.jetbrains.dokka.pages.*
import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet
import org.jetbrains.dokka.base.signatures.KotlinSignatureUtils.drisOfAllNestedBounds
import org.jetbrains.dokka.model.AnnotationTarget
-import org.jetbrains.dokka.model.doc.DocumentationNode
interface JvmSignatureUtils {
@@ -80,21 +79,22 @@ interface JvmSignatureUtils {
when (renderAtStrategy) {
is All, is OnlyOnce -> {
- text("@")
when(a.scope) {
- Annotations.AnnotationScope.GETTER -> text("get:")
- Annotations.AnnotationScope.SETTER -> text("set:")
+ Annotations.AnnotationScope.GETTER -> text("@get:", styles = mainStyles + TokenStyle.Annotation)
+ Annotations.AnnotationScope.SETTER -> text("@set:", styles = mainStyles + TokenStyle.Annotation)
+ else -> text("@", styles = mainStyles + TokenStyle.Annotation)
}
+ link(a.dri.classNames!!, a.dri, styles = mainStyles + TokenStyle.Annotation)
}
- is Never -> Unit
+ is Never -> link(a.dri.classNames!!, a.dri)
}
- link(a.dri.classNames!!, a.dri)
val isNoWrappedBrackets = a.params.entries.isEmpty() && renderAtStrategy is OnlyOnce
listParams(
a.params.entries,
if (isNoWrappedBrackets) null else Pair('(', ')')
) {
- text(it.key + " = ")
+ text(it.key)
+ text(" = ", styles = mainStyles + TokenStyle.Operator)
when (renderAtStrategy) {
is All -> All
is Never, is OnlyOnce -> Never
@@ -116,8 +116,9 @@ interface JvmSignatureUtils {
}
is EnumValue -> link(a.enumName, a.enumDri)
is ClassValue -> link(a.className + classExtension, a.classDRI)
- is StringValue -> group(styles = setOf(TextStyle.Breakable)) { text( "\"${a.text()}\"") }
- is LiteralValue -> group(styles = setOf(TextStyle.Breakable)) { text(a.text()) }
+ is StringValue -> group(styles = setOf(TextStyle.Breakable)) { stringLiteral( "\"${a.text()}\"") }
+ is BooleanValue -> group(styles = setOf(TextStyle.Breakable)) { booleanLiteral(a.value) }
+ is LiteralValue -> group(styles = setOf(TextStyle.Breakable)) { constant(a.text()) }
}
private fun<T> PageContentBuilder.DocumentableContentBuilder.listParams(
@@ -125,14 +126,14 @@ interface JvmSignatureUtils {
listBrackets: Pair<Char, Char>?,
outFn: PageContentBuilder.DocumentableContentBuilder.(T) -> Unit
) {
- listBrackets?.let{ text(it.first.toString()) }
+ listBrackets?.let{ punctuation(it.first.toString()) }
params.forEachIndexed { i, it ->
group(styles = setOf(TextStyle.BreakableAfter)) {
this.outFn(it)
- if (i != params.size - 1) text(", ")
+ if (i != params.size - 1) punctuation(", ")
}
}
- listBrackets?.let{ text(it.second.toString()) }
+ listBrackets?.let{ punctuation(it.second.toString()) }
}
fun PageContentBuilder.DocumentableContentBuilder.annotationsBlockWithIgnored(
diff --git a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt
index bd967518..8db37012 100644
--- a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt
+++ b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt
@@ -15,6 +15,7 @@ import org.jetbrains.dokka.model.properties.WithExtraProperties
import org.jetbrains.dokka.pages.ContentKind
import org.jetbrains.dokka.pages.ContentNode
import org.jetbrains.dokka.pages.TextStyle
+import org.jetbrains.dokka.pages.TokenStyle
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.plugability.plugin
import org.jetbrains.dokka.plugability.querySingle
@@ -60,7 +61,7 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog
it !in ignoredExtraModifiers || entry.key.analysisPlatform in (platformSpecificModifiers[it]
?: emptySet())
}
- }
+ }, styles = mainStyles + TokenStyle.Keyword
) {
it.toSignatureString()
}
@@ -78,8 +79,15 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog
annotationsBlock(e)
link(e.name, e.dri, styles = emptySet())
e.extra[ConstructorValues]?.let { constructorValues ->
- constructorValues.values[it]
- text(constructorValues.values[it]?.joinToString(prefix = "(", postfix = ")") ?: "")
+ constructorValues.values[it]?.let { values ->
+ punctuation("(")
+ list(
+ elements = values,
+ separator = ", ",
+ separatorStyles = mainStyles + TokenStyle.Punctuation,
+ ) { highlightValue(it) }
+ punctuation(")")
+ }
}
}
}
@@ -93,9 +101,9 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog
?: emptySet()),
sourceSets = setOf(sourceSet)
) {
- text("typealias ")
+ keyword("typealias ")
link(c.name.orEmpty(), c.dri)
- text(" = ")
+ operator(" = ")
signatureForProjection(aliasedType)
}
@@ -118,10 +126,9 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog
sourceSets = setOf(sourceSet)
) {
annotationsBlock(c)
- text(c.visibility[sourceSet]?.takeIf { it !in ignoredVisibilities }?.name?.let { "$it " } ?: "")
+ c.visibility[sourceSet]?.takeIf { it !in ignoredVisibilities }?.name?.let { keyword("$it ") }
if (c is DClass) {
- text(
- if (c.modifier[sourceSet] !in ignoredModifiers)
+ val modifier = if (c.modifier[sourceSet] !in ignoredModifiers)
when {
c.extra[AdditionalModifiers]?.content?.get(sourceSet)?.contains(ExtraModifiers.KotlinOnlyModifiers.Data) == true -> ""
c.modifier[sourceSet] is JavaModifier.Empty -> "${KotlinModifier.Open.name} "
@@ -129,33 +136,35 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog
}
else
""
- )
+ modifier.takeIf { it.isNotEmpty() }?.let { keyword(it) }
}
when (c) {
is DClass -> {
processExtraModifiers(c)
- text("class ")
+ keyword("class ")
}
is DInterface -> {
processExtraModifiers(c)
- text("interface ")
+ keyword("interface ")
}
is DEnum -> {
processExtraModifiers(c)
- text("enum ")
+ keyword("enum ")
}
is DObject -> {
processExtraModifiers(c)
- text("object ")
+ keyword("object ")
}
is DAnnotation -> {
processExtraModifiers(c)
- text("annotation class ")
+ keyword("annotation class ")
}
}
link(c.name!!, c.dri)
if (c is WithGenerics) {
- list(c.generics, prefix = "<", suffix = ">") {
+ list(c.generics, prefix = "<", suffix = ">",
+ separatorStyles = mainStyles + TokenStyle.Punctuation,
+ surroundingCharactersStyle = mainStyles + TokenStyle.Operator) {
annotationsInline(it)
+buildSignature(it)
}
@@ -166,18 +175,20 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog
if (pConstructor.annotations().values.any { it.isNotEmpty() }) {
text(nbsp.toString())
annotationsInline(pConstructor)
- text("constructor")
+ keyword("constructor")
}
list(
- pConstructor.parameters,
- "(",
- ")",
- ", ",
- pConstructor.sourceSets.toSet()
+ elements = pConstructor.parameters,
+ prefix = "(",
+ suffix = ")",
+ separator = ", ",
+ separatorStyles = mainStyles + TokenStyle.Punctuation,
+ surroundingCharactersStyle = mainStyles + TokenStyle.Punctuation,
+ sourceSets = pConstructor.sourceSets.toSet()
) {
annotationsInline(it)
text(it.name.orEmpty())
- text(": ")
+ operator(": ")
signatureForProjection(it.type)
}
}
@@ -186,7 +197,9 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog
c.supertypes.filter { it.key == sourceSet }.map { (s, typeConstructors) ->
list(typeConstructors, prefix = " : ", sourceSets = setOf(s)) {
link(it.typeConstructor.dri.sureClassNames, it.typeConstructor.dri, sourceSets = setOf(s))
- list(it.typeConstructor.projections, prefix = "<", suffix = "> ") {
+ list(it.typeConstructor.projections, prefix = "<", suffix = "> ",
+ separatorStyles = mainStyles + TokenStyle.Punctuation,
+ surroundingCharactersStyle = mainStyles + TokenStyle.Operator) {
signatureForProjection(it)
}
}
@@ -203,31 +216,42 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog
sourceSets = setOf(it)
) {
annotationsBlock(p)
- text(p.visibility[it].takeIf { it !in ignoredVisibilities }?.name?.let { "$it " } ?: "")
- text(
- p.modifier[it].takeIf { it !in ignoredModifiers }?.let {
+ p.visibility[it].takeIf { it !in ignoredVisibilities }?.name?.let { keyword("$it ") }
+ p.modifier[it].takeIf { it !in ignoredModifiers }?.let {
if (it is JavaModifier.Empty) KotlinModifier.Open else it
- }?.name?.let { "$it " } ?: ""
- )
- text(p.modifiers()[it]?.toSignatureString() ?: "")
- p.setter?.let { text("var ") } ?: text("val ")
- list(p.generics, prefix = "<", suffix = "> ") {
+ }?.name?.let { keyword("$it ") }
+ p.modifiers()[it]?.toSignatureString()?.let { keyword(it) }
+ p.setter?.let { keyword("var ") } ?: keyword("val ")
+ list(p.generics, prefix = "<", suffix = "> ",
+ separatorStyles = mainStyles + TokenStyle.Punctuation,
+ surroundingCharactersStyle = mainStyles + TokenStyle.Operator) {
annotationsInline(it)
+buildSignature(it)
}
p.receiver?.also {
signatureForProjection(it.type)
- text(".")
+ punctuation(".")
}
link(p.name, p.dri)
- text(": ")
+ operator(": ")
signatureForProjection(p.type)
p.extra[DefaultValue]?.run {
- text(" = $value")
+ operator(" = ")
+ highlightValue(value)
}
}
}
+ private fun PageContentBuilder.DocumentableContentBuilder.highlightValue(expr: Expression) = when (expr) {
+ is IntegerConstant -> constant(expr.value.toString())
+ is FloatConstant -> constant(expr.value.toString() + "f")
+ is DoubleConstant -> constant(expr.value.toString())
+ is BooleanConstant -> booleanLiteral(expr.value)
+ is StringConstant -> stringLiteral("\"${expr.value}\"")
+ is ComplexExpression -> text(expr.value)
+ else -> Unit
+ }
+
private fun functionSignature(f: DFunction) =
f.sourceSets.map {
contentBuilder.contentFor(
@@ -237,37 +261,40 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog
sourceSets = setOf(it)
) {
annotationsBlock(f)
- text(f.visibility[it]?.takeIf { it !in ignoredVisibilities }?.name?.let { "$it " } ?: "")
- text(f.modifier[it]?.takeIf { it !in ignoredModifiers }?.let {
+ f.visibility[it]?.takeIf { it !in ignoredVisibilities }?.name?.let { keyword("$it ") }
+ f.modifier[it]?.takeIf { it !in ignoredModifiers }?.let {
if (it is JavaModifier.Empty) KotlinModifier.Open else it
- }?.name?.let { "$it " } ?: ""
- )
- text(f.modifiers()[it]?.toSignatureString() ?: "")
- text("fun ")
+ }?.name?.let { keyword("$it ") }
+ f.modifiers()[it]?.toSignatureString()?.let { keyword(it) }
+ keyword("fun ")
val usedGenerics = if (f.isConstructor) f.generics.filter { f uses it } else f.generics
- list(usedGenerics, prefix = "<", suffix = "> ") {
+ list(usedGenerics, prefix = "<", suffix = "> ",
+ separatorStyles = mainStyles + TokenStyle.Punctuation,
+ surroundingCharactersStyle = mainStyles + TokenStyle.Operator) {
annotationsInline(it)
+buildSignature(it)
}
f.receiver?.also {
signatureForProjection(it.type)
- text(".")
+ punctuation(".")
}
- link(f.name, f.dri)
- text("(")
- list(f.parameters) {
+ link(f.name, f.dri, styles = mainStyles + TokenStyle.Function)
+ punctuation("(")
+ list(f.parameters,
+ separatorStyles = mainStyles + TokenStyle.Punctuation) {
annotationsInline(it)
processExtraModifiers(it)
text(it.name!!)
- text(": ")
+ operator(": ")
signatureForProjection(it.type)
it.extra[DefaultValue]?.run {
- text(" = $value")
+ operator(" = ")
+ highlightValue(value)
}
}
- text(")")
+ punctuation(")")
if (f.documentReturnType()) {
- text(": ")
+ operator(": ")
signatureForProjection(f.type)
}
}
@@ -291,11 +318,11 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog
sourceSets = platforms.toSet()
) {
annotationsBlock(t)
- text(t.visibility[it]?.takeIf { it !in ignoredVisibilities }?.name?.let { "$it " } ?: "")
+ t.visibility[it]?.takeIf { it !in ignoredVisibilities }?.name?.let { keyword("$it ") }
processExtraModifiers(t)
- text("typealias ")
+ keyword("typealias ")
signatureForProjection(t.type)
- text(" = ")
+ operator(" = ")
signatureForTypealiasTarget(t, type)
}
}
@@ -306,7 +333,8 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog
t.sourceSets.map {
contentBuilder.contentFor(t, styles = t.stylesIfDeprecated(it), sourceSets = setOf(it)) {
signatureForProjection(t.variantTypeParameter.withDri(t.dri.withTargetToDeclaration()))
- list(t.nontrivialBounds, prefix = " : ") { bound ->
+ list(t.nontrivialBounds, prefix = " : ",
+ surroundingCharactersStyle = mainStyles + TokenStyle.Operator) { bound ->
signatureForProjection(bound)
}
}
@@ -338,24 +366,29 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog
val linkText = if (showFullyQualifiedName && p.dri.packageName != null) {
"${p.dri.packageName}.${p.dri.classNames.orEmpty()}"
} else p.dri.classNames.orEmpty()
- if (p.presentableName != null) text(p.presentableName + ": ")
+ if (p.presentableName != null) {
+ text(p.presentableName!!)
+ operator(": ")
+ }
annotationsInline(p)
link(linkText, p.dri)
- list(p.projections, prefix = "<", suffix = ">") {
+ list(p.projections, prefix = "<", suffix = ">",
+ separatorStyles = mainStyles + TokenStyle.Punctuation,
+ surroundingCharactersStyle = mainStyles + TokenStyle.Operator) {
signatureForProjection(it, showFullyQualifiedName)
}
}
is Variance<*> -> group(styles = emptySet()) {
- text("$p ".takeIf { it.isNotBlank() } ?: "")
+ keyword("$p ".takeIf { it.isNotBlank() } ?: "")
signatureForProjection(p.inner, showFullyQualifiedName)
}
- is Star -> text("*")
+ is Star -> operator("*")
is Nullable -> group(styles = emptySet()) {
signatureForProjection(p.inner, showFullyQualifiedName)
- text("?")
+ operator("?")
}
is TypeAliased -> signatureForProjection(p.typeAlias)
@@ -373,12 +406,15 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog
private fun funType(dri: DRI, sourceSets: Set<DokkaSourceSet>, type: FunctionalTypeConstructor) =
contentBuilder.contentFor(dri, sourceSets, ContentKind.Main) {
- if (type.presentableName != null) text(type.presentableName + ": ")
- if (type.isSuspendable) text("suspend ")
+ if (type.presentableName != null) {
+ text(type.presentableName!!)
+ operator(": ")
+ }
+ if (type.isSuspendable) keyword("suspend ")
if (type.isExtensionFunction) {
signatureForProjection(type.projections.first())
- text(".")
+ punctuation(".")
}
val args = if (type.isExtensionFunction)
@@ -386,12 +422,13 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog
else
type.projections
- text("(")
+ punctuation("(")
args.subList(0, args.size - 1).forEachIndexed { i, arg ->
signatureForProjection(arg)
- if (i < args.size - 2) text(", ")
+ if (i < args.size - 2) punctuation(", ")
}
- text(") -> ")
+ punctuation(")")
+ operator(" -> ")
signatureForProjection(args.last())
}
}
diff --git a/plugins/base/src/main/kotlin/transformers/pages/comments/DocTagToContentConverter.kt b/plugins/base/src/main/kotlin/transformers/pages/comments/DocTagToContentConverter.kt
index a02f1b53..8c2e1c99 100644
--- a/plugins/base/src/main/kotlin/transformers/pages/comments/DocTagToContentConverter.kt
+++ b/plugins/base/src/main/kotlin/transformers/pages/comments/DocTagToContentConverter.kt
@@ -108,7 +108,7 @@ open class DocTagToContentConverter : CommentsToContentConverter {
is BlockQuote, is Pre, is CodeBlock -> listOf(
ContentCodeBlock(
buildChildren(docTag),
- "",
+ docTag.params.getOrDefault("lang", ""),
dci,
sourceSets.toDisplaySourceSets(),
styles
diff --git a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt
index 3ff8ffc3..d986056c 100644
--- a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt
+++ b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt
@@ -1,6 +1,7 @@
package org.jetbrains.dokka.base.translators.descriptors
import com.intellij.psi.PsiNamedElement
+import com.intellij.psi.util.PsiLiteralUtil.*
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.runBlocking
@@ -29,6 +30,8 @@ import org.jetbrains.dokka.transformers.sources.AsyncSourceToDocumentableTransla
import org.jetbrains.dokka.utilities.DokkaLogger
import org.jetbrains.dokka.utilities.parallelMap
import org.jetbrains.dokka.utilities.parallelMapNotNull
+import org.jetbrains.kotlin.KtNodeTypes
+import org.jetbrains.dokka.model.BooleanConstant
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
import org.jetbrains.kotlin.builtins.isBuiltinExtensionFunctionalType
import org.jetbrains.kotlin.builtins.isExtensionFunctionType
@@ -38,7 +41,6 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.annotations.Annotated
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
-import org.jetbrains.kotlin.idea.core.getDirectlyOverriddenDeclarations
import org.jetbrains.kotlin.idea.kdoc.findKDoc
import org.jetbrains.kotlin.idea.kdoc.resolveKDocLink
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
@@ -53,7 +55,6 @@ import org.jetbrains.kotlin.resolve.constants.KClassValue.Value.LocalClass
import org.jetbrains.kotlin.resolve.constants.KClassValue.Value.NormalClass
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
-import org.jetbrains.kotlin.resolve.descriptorUtil.overriddenTreeUniqueAsSequence
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
@@ -1011,25 +1012,33 @@ private class DokkaDescriptorVisitor(
if (kind != CallableMemberDescriptor.Kind.FAKE_OVERRIDE) this
else overriddenDescriptors.first().getConcreteDescriptor() as T
- private fun ValueParameterDescriptor.getDefaultValue(): String? =
- (source as? KotlinSourceElement)?.psi?.children?.find { it is KtExpression }?.text
+ private fun ValueParameterDescriptor.getDefaultValue(): Expression? =
+ ((source as? KotlinSourceElement)?.psi as? KtParameter)?.defaultValue?.toDefaultValueExpression()
- private suspend fun PropertyDescriptor.getDefaultValue(): String? =
- (source as? KotlinSourceElement)?.psi?.children?.find { it is KtConstantExpression }?.text
+ private suspend fun PropertyDescriptor.getDefaultValue(): Expression? =
+ (source as? KotlinSourceElement)?.psi?.children?.filterIsInstance<KtConstantExpression>()?.firstOrNull()
+ ?.toDefaultValueExpression()
private suspend fun ClassDescriptor.getAppliedConstructorParameters() =
(source as PsiSourceElement).psi?.children?.flatMap {
- it.safeAs<KtInitializerList>()?.initializersAsText().orEmpty()
+ it.safeAs<KtInitializerList>()?.initializersAsExpression().orEmpty()
}.orEmpty()
- private suspend fun KtInitializerList.initializersAsText() =
+ private suspend fun KtInitializerList.initializersAsExpression() =
initializers.firstIsInstanceOrNull<KtCallElement>()
?.getValueArgumentsInParentheses()
- ?.flatMap { it.childrenAsText() }
+ ?.map { it.getArgumentExpression()?.toDefaultValueExpression() ?: ComplexExpression("") }
.orEmpty()
- private fun ValueArgument.childrenAsText() =
- this.safeAs<KtValueArgument>()?.children?.map { it.text }.orEmpty()
+ private fun KtExpression.toDefaultValueExpression(): Expression? = when (node?.elementType) {
+ KtNodeTypes.INTEGER_CONSTANT -> parseLong(node?.text)?.let { IntegerConstant(it) }
+ KtNodeTypes.FLOAT_CONSTANT -> if (node?.text?.toLowerCase()?.endsWith('f') == true)
+ parseFloat(node?.text)?.let { FloatConstant(it) }
+ else parseDouble(node?.text)?.let { DoubleConstant(it) }
+ KtNodeTypes.BOOLEAN_CONSTANT -> BooleanConstant(node?.text == "true")
+ KtNodeTypes.STRING_TEMPLATE -> StringConstant(node.findChildByType(KtNodeTypes.LITERAL_STRING_TEMPLATE_ENTRY)?.text.orEmpty())
+ else -> node?.text?.let { ComplexExpression(it) }
+ }
private data class ClassInfo(val ancestry: List<AncestryLevel>, val docs: SourceSetDependent<DocumentationNode>) {
val supertypes: List<TypeConstructorWithKind>
diff --git a/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt b/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt
index f98e284f..cbab6273 100644
--- a/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt
+++ b/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt
@@ -122,6 +122,13 @@ open class PageContentBuilder(
header(1, text, sourceSets = sourceSets, styles = styles, extra = extra, block = block)
}
+ fun constant(text: String) = text(text, styles = mainStyles + TokenStyle.Constant)
+ fun keyword(text: String) = text(text, styles = mainStyles + TokenStyle.Keyword)
+ fun stringLiteral(text: String) = text(text, styles = mainStyles + TokenStyle.String)
+ fun booleanLiteral(value: Boolean) = text(value.toString(), styles = mainStyles + TokenStyle.Boolean)
+ fun punctuation(text: String) = text(text, styles = mainStyles + TokenStyle.Punctuation)
+ fun operator(text: String) = text(text, styles = mainStyles + TokenStyle.Operator)
+
fun text(
text: String,
kind: Kind = ContentKind.Main,
@@ -194,16 +201,18 @@ open class PageContentBuilder(
suffix: String = "",
separator: String = ", ",
sourceSets: Set<DokkaSourceSet> = mainSourcesetData, // TODO: children should be aware of this platform data
+ surroundingCharactersStyle: Set<Style> = mainStyles,
+ separatorStyles: Set<Style> = mainStyles,
operation: DocumentableContentBuilder.(T) -> Unit
) {
if (elements.isNotEmpty()) {
- if (prefix.isNotEmpty()) text(prefix, sourceSets = sourceSets)
+ if (prefix.isNotEmpty()) text(prefix, sourceSets = sourceSets, styles = surroundingCharactersStyle)
elements.dropLast(1).forEach {
operation(it)
- text(separator, sourceSets = sourceSets)
+ text(separator, sourceSets = sourceSets, styles = separatorStyles)
}
operation(elements.last())
- if (suffix.isNotEmpty()) text(suffix, sourceSets = sourceSets)
+ if (suffix.isNotEmpty()) text(suffix, sourceSets = sourceSets, styles = surroundingCharactersStyle)
}
}
@@ -380,11 +389,12 @@ open class PageContentBuilder(
fun <T> sourceSetDependentText(
value: SourceSetDependent<T>,
sourceSets: Set<DokkaSourceSet> = value.keys,
+ styles: Set<Style> = mainStyles,
transform: (T) -> String
) = value.entries.filter { it.key in sourceSets }.mapNotNull { (p, v) ->
transform(v).takeIf { it.isNotBlank() }?.let { it to p }
}.groupBy({ it.first }) { it.second }.forEach {
- text(it.key, sourceSets = it.value.toSet())
+ text(it.key, sourceSets = it.value.toSet(), styles = styles)
}
}
diff --git a/plugins/base/src/main/resources/dokka/scripts/prism.js b/plugins/base/src/main/resources/dokka/scripts/prism.js
new file mode 100644
index 00000000..88fee76e
--- /dev/null
+++ b/plugins/base/src/main/resources/dokka/scripts/prism.js
@@ -0,0 +1,13 @@
+/* PrismJS 1.24.1
+https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+java+javadoc+javadoclike+kotlin&plugins=keep-markup */
+var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(u){var c=/\blang(?:uage)?-([\w-]+)\b/i,n=0,e={},M={manual:u.Prism&&u.Prism.manual,disableWorkerMessageHandler:u.Prism&&u.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof W?new W(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++n}),e.__id},clone:function t(e,r){var a,n;switch(r=r||{},M.util.type(e)){case"Object":if(n=M.util.objId(e),r[n])return r[n];for(var i in a={},r[n]=a,e)e.hasOwnProperty(i)&&(a[i]=t(e[i],r));return a;case"Array":return n=M.util.objId(e),r[n]?r[n]:(a=[],r[n]=a,e.forEach(function(e,n){a[n]=t(e,r)}),a);default:return e}},getLanguage:function(e){for(;e&&!c.test(e.className);)e=e.parentElement;return e?(e.className.match(c)||[,"none"])[1].toLowerCase():"none"},currentScript:function(){if("undefined"==typeof document)return null;if("currentScript"in document)return document.currentScript;try{throw new Error}catch(e){var n=(/at [^(\r\n]*\((.*):.+:.+\)$/i.exec(e.stack)||[])[1];if(n){var t=document.getElementsByTagName("script");for(var r in t)if(t[r].src==n)return t[r]}return null}},isActive:function(e,n,t){for(var r="no-"+n;e;){var a=e.classList;if(a.contains(n))return!0;if(a.contains(r))return!1;e=e.parentElement}return!!t}},languages:{plain:e,plaintext:e,text:e,txt:e,extend:function(e,n){var t=M.util.clone(M.languages[e]);for(var r in n)t[r]=n[r];return t},insertBefore:function(t,e,n,r){var a=(r=r||M.languages)[t],i={};for(var l in a)if(a.hasOwnProperty(l)){if(l==e)for(var o in n)n.hasOwnProperty(o)&&(i[o]=n[o]);n.hasOwnProperty(l)||(i[l]=a[l])}var s=r[t];return r[t]=i,M.languages.DFS(M.languages,function(e,n){n===s&&e!=t&&(this[e]=i)}),i},DFS:function e(n,t,r,a){a=a||{};var i=M.util.objId;for(var l in n)if(n.hasOwnProperty(l)){t.call(n,l,n[l],r||l);var o=n[l],s=M.util.type(o);"Object"!==s||a[i(o)]?"Array"!==s||a[i(o)]||(a[i(o)]=!0,e(o,t,l,a)):(a[i(o)]=!0,e(o,t,null,a))}}},plugins:{},highlightAll:function(e,n){M.highlightAllUnder(document,e,n)},highlightAllUnder:function(e,n,t){var r={callback:t,container:e,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};M.hooks.run("before-highlightall",r),r.elements=Array.prototype.slice.apply(r.container.querySelectorAll(r.selector)),M.hooks.run("before-all-elements-highlight",r);for(var a,i=0;a=r.elements[i++];)M.highlightElement(a,!0===n,r.callback)},highlightElement:function(e,n,t){var r=M.util.getLanguage(e),a=M.languages[r];e.className=e.className.replace(c,"").replace(/\s+/g," ")+" language-"+r;var i=e.parentElement;i&&"pre"===i.nodeName.toLowerCase()&&(i.className=i.className.replace(c,"").replace(/\s+/g," ")+" language-"+r);var l={element:e,language:r,grammar:a,code:e.textContent};function o(e){l.highlightedCode=e,M.hooks.run("before-insert",l),l.element.innerHTML=l.highlightedCode,M.hooks.run("after-highlight",l),M.hooks.run("complete",l),t&&t.call(l.element)}if(M.hooks.run("before-sanity-check",l),(i=l.element.parentElement)&&"pre"===i.nodeName.toLowerCase()&&!i.hasAttribute("tabindex")&&i.setAttribute("tabindex","0"),!l.code)return M.hooks.run("complete",l),void(t&&t.call(l.element));if(M.hooks.run("before-highlight",l),l.grammar)if(n&&u.Worker){var s=new Worker(M.filename);s.onmessage=function(e){o(e.data)},s.postMessage(JSON.stringify({language:l.language,code:l.code,immediateClose:!0}))}else o(M.highlight(l.code,l.grammar,l.language));else o(M.util.encode(l.code))},highlight:function(e,n,t){var r={code:e,grammar:n,language:t};return M.hooks.run("before-tokenize",r),r.tokens=M.tokenize(r.code,r.grammar),M.hooks.run("after-tokenize",r),W.stringify(M.util.encode(r.tokens),r.language)},tokenize:function(e,n){var t=n.rest;if(t){for(var r in t)n[r]=t[r];delete n.rest}var a=new i;return I(a,a.head,e),function e(n,t,r,a,i,l){for(var o in r)if(r.hasOwnProperty(o)&&r[o]){var s=r[o];s=Array.isArray(s)?s:[s];for(var u=0;u<s.length;++u){if(l&&l.cause==o+","+u)return;var c=s[u],g=c.inside,f=!!c.lookbehind,h=!!c.greedy,d=c.alias;if(h&&!c.pattern.global){var p=c.pattern.toString().match(/[imsuy]*$/)[0];c.pattern=RegExp(c.pattern.source,p+"g")}for(var v=c.pattern||c,m=a.next,y=i;m!==t.tail&&!(l&&y>=l.reach);y+=m.value.length,m=m.next){var b=m.value;if(t.length>n.length)return;if(!(b instanceof W)){var k,x=1;if(h){if(!(k=z(v,y,n,f)))break;var w=k.index,A=k.index+k[0].length,P=y;for(P+=m.value.length;P<=w;)m=m.next,P+=m.value.length;if(P-=m.value.length,y=P,m.value instanceof W)continue;for(var E=m;E!==t.tail&&(P<A||"string"==typeof E.value);E=E.next)x++,P+=E.value.length;x--,b=n.slice(y,P),k.index-=y}else if(!(k=z(v,0,b,f)))continue;var w=k.index,S=k[0],O=b.slice(0,w),L=b.slice(w+S.length),N=y+b.length;l&&N>l.reach&&(l.reach=N);var j=m.prev;O&&(j=I(t,j,O),y+=O.length),q(t,j,x);var C=new W(o,g?M.tokenize(S,g):S,d,S);if(m=I(t,j,C),L&&I(t,m,L),1<x){var _={cause:o+","+u,reach:N};e(n,t,r,m.prev,y,_),l&&_.reach>l.reach&&(l.reach=_.reach)}}}}}}(e,a,n,a.head,0),function(e){var n=[],t=e.head.next;for(;t!==e.tail;)n.push(t.value),t=t.next;return n}(a)},hooks:{all:{},add:function(e,n){var t=M.hooks.all;t[e]=t[e]||[],t[e].push(n)},run:function(e,n){var t=M.hooks.all[e];if(t&&t.length)for(var r,a=0;r=t[a++];)r(n)}},Token:W};function W(e,n,t,r){this.type=e,this.content=n,this.alias=t,this.length=0|(r||"").length}function z(e,n,t,r){e.lastIndex=n;var a=e.exec(t);if(a&&r&&a[1]){var i=a[1].length;a.index+=i,a[0]=a[0].slice(i)}return a}function i(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function I(e,n,t){var r=n.next,a={value:t,prev:n,next:r};return n.next=a,r.prev=a,e.length++,a}function q(e,n,t){for(var r=n.next,a=0;a<t&&r!==e.tail;a++)r=r.next;(n.next=r).prev=n,e.length-=a}if(u.Prism=M,W.stringify=function n(e,t){if("string"==typeof e)return e;if(Array.isArray(e)){var r="";return e.forEach(function(e){r+=n(e,t)}),r}var a={type:e.type,content:n(e.content,t),tag:"span",classes:["token",e.type],attributes:{},language:t},i=e.alias;i&&(Array.isArray(i)?Array.prototype.push.apply(a.classes,i):a.classes.push(i)),M.hooks.run("wrap",a);var l="";for(var o in a.attributes)l+=" "+o+'="'+(a.attributes[o]||"").replace(/"/g,"&quot;")+'"';return"<"+a.tag+' class="'+a.classes.join(" ")+'"'+l+">"+a.content+"</"+a.tag+">"},!u.document)return u.addEventListener&&(M.disableWorkerMessageHandler||u.addEventListener("message",function(e){var n=JSON.parse(e.data),t=n.language,r=n.code,a=n.immediateClose;u.postMessage(M.highlight(r,M.languages[t],t)),a&&u.close()},!1)),M;var t=M.util.currentScript();function r(){M.manual||M.highlightAll()}if(t&&(M.filename=t.src,t.hasAttribute("data-manual")&&(M.manual=!0)),!M.manual){var a=document.readyState;"loading"===a||"interactive"===a&&t&&t.defer?document.addEventListener("DOMContentLoaded",r):window.requestAnimationFrame?window.requestAnimationFrame(r):window.setTimeout(r,16)}return M}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism);
+Prism.languages.markup={comment:/<!--[\s\S]*?-->/,prolog:/<\?[\s\S]+?\?>/,doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/,name:/[^\s<>'"]+/}},cdata:/<!\[CDATA\[[\s\S]*?\]\]>/i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.languages.markup.doctype.inside["internal-subset"].inside=Prism.languages.markup,Prism.hooks.add("wrap",function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&amp;/,"&"))}),Object.defineProperty(Prism.languages.markup.tag,"addInlined",{value:function(a,e){var s={};s["language-"+e]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:Prism.languages[e]},s.cdata=/^<!\[CDATA\[|\]\]>$/i;var t={"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:s}};t["language-"+e]={pattern:/[\s\S]+/,inside:Prism.languages[e]};var n={};n[a]={pattern:RegExp("(<__[^>]*>)(?:<!\\[CDATA\\[(?:[^\\]]|\\](?!\\]>))*\\]\\]>|(?!<!\\[CDATA\\[)[^])*?(?=</__>)".replace(/__/g,function(){return a}),"i"),lookbehind:!0,greedy:!0,inside:t},Prism.languages.insertBefore("markup","cdata",n)}}),Object.defineProperty(Prism.languages.markup.tag,"addAttribute",{value:function(a,e){Prism.languages.markup.tag.inside["special-attr"].push({pattern:RegExp("(^|[\"'\\s])(?:"+a+")\\s*=\\s*(?:\"[^\"]*\"|'[^']*'|[^\\s'\">=]+(?=[\\s>]))","i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[e,"language-"+e],inside:Prism.languages[e]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup,Prism.languages.xml=Prism.languages.extend("markup",{}),Prism.languages.ssml=Prism.languages.xml,Prism.languages.atom=Prism.languages.xml,Prism.languages.rss=Prism.languages.xml;
+!function(s){var e=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;s.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+e.source+"|(?:[^\\\\\r\n()\"']|\\\\[^])*)\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+e.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+e.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:e,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},s.languages.css.atrule.inside.rest=s.languages.css;var t=s.languages.markup;t&&(t.tag.addInlined("style","css"),t.tag.addAttribute("style","css"))}(Prism);
+Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|interface|extends|implements|trait|instanceof|new)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,boolean:/\b(?:true|false)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/};
+Prism.languages.javascript=Prism.languages.extend("clike",{"class-name":[Prism.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:prototype|constructor))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:/\b(?:(?:0[xX](?:[\dA-Fa-f](?:_[\dA-Fa-f])?)+|0[bB](?:[01](?:_[01])?)+|0[oO](?:[0-7](?:_[0-7])?)+)n?|(?:\d(?:_\d)?)+n|NaN|Infinity)\b|(?:\b(?:\d(?:_\d)?)+\.?(?:\d(?:_\d)?)*|\B\.(?:\d(?:_\d)?)+)(?:[Ee][+-]?(?:\d(?:_\d)?)+)?/,operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),Prism.languages.javascript["class-name"][0].pattern=/(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/,Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:Prism.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:Prism.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),Prism.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}}}),Prism.languages.markup&&(Prism.languages.markup.tag.addInlined("script","javascript"),Prism.languages.markup.tag.addAttribute("on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)","javascript")),Prism.languages.js=Prism.languages.javascript;
+!function(e){var t=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,n="(^|[^\\w.])(?:[a-z]\\w*\\s*\\.\\s*)*(?:[A-Z]\\w*\\s*\\.\\s*)*",a={pattern:RegExp(n+"[A-Z](?:[\\d_A-Z]*[a-z]\\w*)?\\b"),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}};e.languages.java=e.languages.extend("clike",{"class-name":[a,{pattern:RegExp(n+"[A-Z]\\w*(?=\\s+\\w+\\s*[;,=()])"),lookbehind:!0,inside:a.inside}],keyword:t,function:[e.languages.clike.function,{pattern:/(::\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0}}),e.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"}}),e.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/,inside:{"class-name":a,keyword:t,punctuation:/[<>(),.:]/,operator:/[?&|]/}},namespace:{pattern:RegExp("(\\b(?:exports|import(?:\\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\\s+)(?!<keyword>)[a-z]\\w*(?:\\.[a-z]\\w*)*\\.?".replace(/<keyword>/g,function(){return t.source})),lookbehind:!0,inside:{punctuation:/\./}}})}(Prism);
+!function(p){var a=p.languages.javadoclike={parameter:{pattern:/(^[\t ]*(?:\/{3}|\*|\/\*\*)\s*@(?:param|arg|arguments)\s+)\w+/m,lookbehind:!0},keyword:{pattern:/(^[\t ]*(?:\/{3}|\*|\/\*\*)\s*|\{)@[a-z][a-zA-Z-]+\b/m,lookbehind:!0},punctuation:/[{}]/};Object.defineProperty(a,"addSupport",{value:function(a,e){"string"==typeof a&&(a=[a]),a.forEach(function(a){!function(a,e){var n="doc-comment",t=p.languages[a];if(t){var r=t[n];if(!r){var o={"doc-comment":{pattern:/(^|[^\\])\/\*\*[^/][\s\S]*?(?:\*\/|$)/,lookbehind:!0,alias:"comment"}};r=(t=p.languages.insertBefore(a,"comment",o))[n]}if(r instanceof RegExp&&(r=t[n]={pattern:r}),Array.isArray(r))for(var i=0,s=r.length;i<s;i++)r[i]instanceof RegExp&&(r[i]={pattern:r[i]}),e(r[i]);else e(r)}}(a,function(a){a.inside||(a.inside={}),a.inside.rest=e})})}}),a.addSupport(["java","javascript","php"],a)}(Prism);
+!function(a){var e=/(^(?:[\t ]*(?:\*\s*)*))[^*\s].*$/m,n="(?:\\b[a-zA-Z]\\w+\\s*\\.\\s*)*\\b[A-Z]\\w*(?:\\s*<mem>)?|<mem>".replace(/<mem>/g,function(){return"#\\s*\\w+(?:\\s*\\([^()]*\\))?"});a.languages.javadoc=a.languages.extend("javadoclike",{}),a.languages.insertBefore("javadoc","keyword",{reference:{pattern:RegExp("(@(?:exception|throws|see|link|linkplain|value)\\s+(?:\\*\\s*)?)(?:"+n+")"),lookbehind:!0,inside:{function:{pattern:/(#\s*)\w+(?=\s*\()/,lookbehind:!0},field:{pattern:/(#\s*)\w+/,lookbehind:!0},namespace:{pattern:/\b(?:[a-z]\w*\s*\.\s*)+/,inside:{punctuation:/\./}},"class-name":/\b[A-Z]\w*/,keyword:a.languages.java.keyword,punctuation:/[#()[\],.]/}},"class-name":{pattern:/(@param\s+)<[A-Z]\w*>/,lookbehind:!0,inside:{punctuation:/[.<>]/}},"code-section":[{pattern:/(\{@code\s+(?!\s))(?:[^\s{}]|\s+(?![\s}])|\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*\})+(?=\s*\})/,lookbehind:!0,inside:{code:{pattern:e,lookbehind:!0,inside:a.languages.java,alias:"language-java"}}},{pattern:/(<(code|pre|tt)>(?!<code>)\s*)\S(?:\S|\s+\S)*?(?=\s*<\/\2>)/,lookbehind:!0,inside:{line:{pattern:e,lookbehind:!0,inside:{tag:a.languages.markup.tag,entity:a.languages.markup.entity,code:{pattern:/.+/,inside:a.languages.java,alias:"language-java"}}}}}],tag:a.languages.markup.tag,entity:a.languages.markup.entity}),a.languages.javadoclike.addSupport("java",a.languages.javadoc)}(Prism);
+!function(e){e.languages.kotlin=e.languages.extend("clike",{keyword:{pattern:/(^|[^.])\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\b/,lookbehind:!0},function:[{pattern:/(?:`[^\r\n`]+`|\b\w+)(?=\s*\()/,greedy:!0},{pattern:/(\.)(?:`[^\r\n`]+`|\w+)(?=\s*\{)/,lookbehind:!0,greedy:!0}],number:/\b(?:0[xX][\da-fA-F]+(?:_[\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?[fFL]?)\b/,operator:/\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/}),delete e.languages.kotlin["class-name"],e.languages.insertBefore("kotlin","string",{"raw-string":{pattern:/("""|''')[\s\S]*?\1/,alias:"string"}}),e.languages.insertBefore("kotlin","keyword",{annotation:{pattern:/\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,alias:"builtin"}}),e.languages.insertBefore("kotlin","function",{label:{pattern:/\b\w+@|@\w+\b/,alias:"symbol"}});var n=[{pattern:/\$\{[^}]+\}/,inside:{delimiter:{pattern:/^\$\{|\}$/,alias:"variable"},rest:e.languages.kotlin}},{pattern:/\$\w+/,alias:"variable"}];e.languages.kotlin.string.inside=e.languages.kotlin["raw-string"].inside={interpolation:n},e.languages.kt=e.languages.kotlin,e.languages.kts=e.languages.kotlin}(Prism);
+"undefined"!=typeof Prism&&"undefined"!=typeof document&&document.createRange&&(Prism.plugins.KeepMarkup=!0,Prism.hooks.add("before-highlight",function(e){if(e.element.children.length&&Prism.util.isActive(e.element,"keep-markup",!0)){var a=0,s=[],p=function(e,n){var o={};n||(o.clone=e.cloneNode(!1),o.posOpen=a,s.push(o));for(var t=0,d=e.childNodes.length;t<d;t++){var r=e.childNodes[t];1===r.nodeType?p(r):3===r.nodeType&&(a+=r.data.length)}n||(o.posClose=a)};p(e.element,!0),s&&s.length&&(e.keepMarkup=s)}}),Prism.hooks.add("after-highlight",function(n){if(n.keepMarkup&&n.keepMarkup.length){var a=function(e,n){for(var o=0,t=e.childNodes.length;o<t;o++){var d=e.childNodes[o];if(1===d.nodeType){if(!a(d,n))return!1}else 3===d.nodeType&&(!n.nodeStart&&n.pos+d.data.length>n.node.posOpen&&(n.nodeStart=d,n.nodeStartPos=n.node.posOpen-n.pos),n.nodeStart&&n.pos+d.data.length>=n.node.posClose&&(n.nodeEnd=d,n.nodeEndPos=n.node.posClose-n.pos),n.pos+=d.data.length);if(n.nodeStart&&n.nodeEnd){var r=document.createRange();return r.setStart(n.nodeStart,n.nodeStartPos),r.setEnd(n.nodeEnd,n.nodeEndPos),n.node.clone.appendChild(r.extractContents()),r.insertNode(n.node.clone),r.detach(),!1}}return!0};n.keepMarkup.forEach(function(e){a(n.element,{node:e,pos:0})}),n.highlightedCode=n.element.innerHTML}}));
+Prism.hooks.add('before-sanity-check', function (env){env.element.innerHTML = env.element.innerHTML.replace(/<br>/g, '\n');env.code = env.element.textContent;});
diff --git a/plugins/base/src/main/resources/dokka/styles/prism.css b/plugins/base/src/main/resources/dokka/styles/prism.css
new file mode 100644
index 00000000..62ade383
--- /dev/null
+++ b/plugins/base/src/main/resources/dokka/styles/prism.css
@@ -0,0 +1,92 @@
+code .token {
+ white-space: pre-line;
+}
+
+/* PrismJS 1.24.1
+https://prismjs.com/download.html#themes=prism&languages=clike+java+javadoclike+kotlin&plugins=keep-markup */
+/**
+ * prism.js default theme for JavaScript, CSS and HTML
+ * Based on dabblet (http://dabblet.com)
+ * @author Lea Verou
+ */
+
+.token.comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+ color: slategray;
+}
+
+.token.punctuation {
+ color: #999;
+}
+
+.token.namespace {
+ opacity: .7;
+}
+
+.token.property,
+.token.tag,
+.token.boolean,
+.token.number,
+.token.constant,
+.token.symbol,
+.token.deleted {
+ color: #905;
+}
+
+.token.selector,
+.token.attr-name,
+.token.string,
+.token.char,
+.token.builtin,
+.token.annotation,
+.token.inserted {
+ color: #690;
+}
+
+.token.operator,
+.token.entity,
+.token.url,
+.language-css .token.string,
+.style .token.string {
+ color: #9a6e3a;
+ /* This background color was intended by the author of this theme. */
+ background: hsla(0, 0%, 100%, .5);
+}
+
+.token.atrule,
+.token.attr-value,
+.token.keyword {
+ color: #07a;
+ font-size: inherit; /* to override .keyword */
+}
+
+.token.function,
+.token.class-name {
+ color: #DD4A68;
+}
+
+.token.regex,
+.token.important,
+.token.variable {
+ color: #e90;
+}
+
+.token.important,
+.token.bold {
+ font-weight: bold;
+}
+.token.italic {
+ font-style: italic;
+}
+
+.token.entity {
+ cursor: help;
+}
+
+.annotation,.control,.field,.filename,.keyword,.menupath,.property,.string,.value {
+ color: #27282c;
+ color: var(--wh-color-text-bold);
+ font-weight: 700;
+} \ No newline at end of file
diff --git a/plugins/base/src/main/resources/dokka/styles/style.css b/plugins/base/src/main/resources/dokka/styles/style.css
index b9d22c3d..7a2dfae0 100644
--- a/plugins/base/src/main/resources/dokka/styles/style.css
+++ b/plugins/base/src/main/resources/dokka/styles/style.css
@@ -276,6 +276,7 @@ html ::-webkit-scrollbar-thumb {
}
.sample-container, div.CodeMirror {
+ position: relative;
display: flex;
flex-direction: column;
}
@@ -315,6 +316,7 @@ code.paragraph {
padding: 12px 32px 12px 12px;
border-radius: 8px;
line-height: 24px;
+ position: relative;
}
.symbol > a {
@@ -325,15 +327,15 @@ code.paragraph {
cursor: pointer;
}
-.symbol span.copy-icon {
+.symbol span.copy-icon, .sample-container span.copy-icon {
display: none;
}
-.symbol:hover span.copy-icon {
+.symbol:hover span.copy-icon, .sample-container:hover span.copy-icon {
display: inline-block;
}
-.symbol span.copy-icon::before {
+.symbol span.copy-icon::before, .sample-container span.copy-icon::before {
width: 24px;
height: 24px;
display: inline-block;
@@ -346,7 +348,7 @@ code.paragraph {
background-color: var(--secondary-text-color);
}
-.symbol span.copy-icon:hover::before {
+.symbol span.copy-icon:hover::before, .sample-container span.copy-icon:hover::before {
background-color: var(--color-dark);
}
@@ -394,7 +396,7 @@ code.paragraph {
padding-right: 14px;
}
-.symbol .top-right-position {
+.symbol .top-right-position, .sample-container .top-right-position {
/* it is important for a parent to have a position: relative */
position: absolute;
top: 8px;
diff --git a/plugins/base/src/test/kotlin/content/HighlightingTest.kt b/plugins/base/src/test/kotlin/content/HighlightingTest.kt
new file mode 100644
index 00000000..39acd2ca
--- /dev/null
+++ b/plugins/base/src/test/kotlin/content/HighlightingTest.kt
@@ -0,0 +1,79 @@
+package content
+
+import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest
+import org.jetbrains.dokka.model.dfs
+import org.jetbrains.dokka.pages.*
+import org.junit.jupiter.api.Test
+import kotlin.test.assertTrue
+
+class HighlightingTest : BaseAbstractTest() {
+ private val configuration = dokkaConfiguration {
+ sourceSets {
+ sourceSet {
+ sourceRoots = listOf("src/")
+ classpath = listOf(commonStdlibPath!!)
+ externalDocumentationLinks = listOf(stdlibExternalDocumentationLink)
+ }
+ }
+ }
+
+ @Test
+ fun `open suspend fun`() {
+ testInline(
+ """
+ |/src/main/kotlin/test/Test.kt
+ |package example
+ |
+ | open suspend fun simpleFun(): String = "Celebrimbor"
+ """,
+ configuration
+ ) {
+ pagesTransformationStage = { module ->
+ val symbol = (module.dfs { it.name == "simpleFun" } as MemberPageNode).content
+ .dfs { it is ContentGroup && it.dci.kind == ContentKind.Symbol }
+ val children = symbol?.children
+
+ for (it in listOf(
+ Pair(0, TokenStyle.Keyword), Pair(1, TokenStyle.Keyword), Pair(2, TokenStyle.Keyword),
+ Pair(4, TokenStyle.Punctuation), Pair(5, TokenStyle.Punctuation), Pair(6, TokenStyle.Operator)
+ ))
+ assertTrue(children?.get(it.first)?.style?.contains(it.second) == true)
+ assertTrue(children?.get(3)?.children?.first()?.style?.contains(TokenStyle.Function) == true)
+ }
+ }
+ }
+
+ @Test
+ fun `plain typealias of plain class with annotation`() {
+ testInline(
+ """
+ |/src/main/kotlin/common/Test.kt
+ |package example
+ |
+ |@MustBeDocumented
+ |@Target(AnnotationTarget.TYPEALIAS)
+ |annotation class SomeAnnotation
+ |
+ |@SomeAnnotation
+ |typealias PlainTypealias = Int
+ |
+ """.trimMargin(),
+ configuration
+ ) {
+ pagesTransformationStage = { module ->
+ val symbol = (module.dfs { it.name == "example" } as PackagePageNode).content
+ .dfs { it is ContentGroup && it.dci.kind == ContentKind.Symbol }
+ val children = symbol?.children
+
+ for (it in listOf(
+ Pair(1, TokenStyle.Keyword), Pair(3, TokenStyle.Operator)
+ ))
+ assertTrue(children?.get(it.first)?.style?.contains(it.second) == true)
+ val annotation = children?.first()?.children?.first()
+
+ assertTrue(annotation?.children?.get(0)?.style?.contains(TokenStyle.Annotation) == true)
+ assertTrue(annotation?.children?.get(1)?.children?.first()?.style?.contains(TokenStyle.Annotation) == true)
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/base/src/test/kotlin/enums/EnumsTest.kt b/plugins/base/src/test/kotlin/enums/EnumsTest.kt
index 2535140c..59a4c6f2 100644
--- a/plugins/base/src/test/kotlin/enums/EnumsTest.kt
+++ b/plugins/base/src/test/kotlin/enums/EnumsTest.kt
@@ -1,11 +1,9 @@
package enums
import matchers.content.*
-import org.jetbrains.dokka.model.ConstructorValues
-import org.jetbrains.dokka.model.DEnum
-import org.jetbrains.dokka.model.dfs
import org.jetbrains.dokka.pages.*
import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest
+import org.jetbrains.dokka.model.*
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.Test
@@ -119,8 +117,8 @@ class EnumsTest : BaseAbstractTest() {
assertEquals(1, first.extra.allOfType<ConstructorValues>().size)
assertEquals(1, second.extra.allOfType<ConstructorValues>().size)
- assertEquals(listOf("\"e1\"", "1", "true"), first.extra.allOfType<ConstructorValues>().first().values.values.first())
- assertEquals(listOf("\"e2\"", "2", "false"), second.extra.allOfType<ConstructorValues>().first().values.values.first())
+ assertEquals(listOf(StringConstant("e1"), IntegerConstant(1), BooleanConstant(true)), first.extra.allOfType<ConstructorValues>().first().values.values.first())
+ assertEquals(listOf(StringConstant("e2"), IntegerConstant(2), BooleanConstant(false)), second.extra.allOfType<ConstructorValues>().first().values.values.first())
}
}
}
diff --git a/plugins/base/src/test/kotlin/model/FunctionsTest.kt b/plugins/base/src/test/kotlin/model/FunctionsTest.kt
index 10ff29b4..eca5daea 100644
--- a/plugins/base/src/test/kotlin/model/FunctionsTest.kt
+++ b/plugins/base/src/test/kotlin/model/FunctionsTest.kt
@@ -344,7 +344,7 @@ class FunctionTest : AbstractModelTest("/src/main/kotlin/function/Test.kt", "fun
parameters.forEach { p ->
p.name equals "x"
p.type.name.assertNotNull("Parameter type: ") equals "String"
- p.extra[DefaultValue]?.value equals "\"\""
+ p.extra[DefaultValue]?.value equals StringConstant("")
}
}
}
@@ -363,7 +363,7 @@ class FunctionTest : AbstractModelTest("/src/main/kotlin/function/Test.kt", "fun
parameters.forEach { p ->
p.name equals "x"
p.type.name.assertNotNull("Parameter type: ") equals "Float"
- p.extra[DefaultValue]?.value equals "3.14f"
+ p.extra[DefaultValue]?.value equals FloatConstant(3.14f)
}
}
}
diff --git a/plugins/base/src/test/kotlin/renderers/html/TextStylesTest.kt b/plugins/base/src/test/kotlin/renderers/html/TextStylesTest.kt
index 3c38e68c..d65a4f6e 100644
--- a/plugins/base/src/test/kotlin/renderers/html/TextStylesTest.kt
+++ b/plugins/base/src/test/kotlin/renderers/html/TextStylesTest.kt
@@ -2,14 +2,13 @@ package renderers.html
import org.jetbrains.dokka.base.renderers.html.HtmlRenderer
import org.jetbrains.dokka.pages.TextStyle
+import org.jetbrains.dokka.pages.TokenStyle
import org.jsoup.Jsoup
import org.jsoup.nodes.Element
import org.junit.jupiter.api.Test
import renderers.testPage
-import utils.B
-import utils.I
-import utils.STRIKE
-import utils.match
+import utils.*
+import kotlin.test.assertEquals
class TextStylesTest : HtmlRenderingOnlyTestBase() {
@Test
@@ -40,6 +39,16 @@ class TextStylesTest : HtmlRenderingOnlyTestBase() {
}
@Test
+ fun `should include token styles`(){
+ val page = testPage {
+ text("keyword", styles = setOf(TokenStyle.Keyword))
+ }
+ HtmlRenderer(context).render(page)
+ renderedContent.match(Span("keyword"))
+ assertEquals(renderedContent.children().last().attr("class"), "token keyword")
+ }
+
+ @Test
fun `should include multiple styles at one`(){
val page = testPage {
text(
diff --git a/plugins/base/src/test/kotlin/signatures/FunctionalTypeConstructorsSignatureTest.kt b/plugins/base/src/test/kotlin/signatures/FunctionalTypeConstructorsSignatureTest.kt
index 35d91175..e631117f 100644
--- a/plugins/base/src/test/kotlin/signatures/FunctionalTypeConstructorsSignatureTest.kt
+++ b/plugins/base/src/test/kotlin/signatures/FunctionalTypeConstructorsSignatureTest.kt
@@ -44,7 +44,8 @@ class FunctionalTypeConstructorsSignatureTest : BaseAbstractTest() {
) {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/index.html").firstSignature().match(
- "val ", A("nF"), ": (", A("Int"), ") -> ", A("String"), Span()
+ "val ", A("nF"), ": (", A("Int"), ") -> ", A("String"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -62,7 +63,8 @@ class FunctionalTypeConstructorsSignatureTest : BaseAbstractTest() {
) {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/index.html").firstSignature().match(
- "val ", A("nF"), ": (", A("Int"), ") -> ", A("String"), Span()
+ "val ", A("nF"), ": (", A("Int"), ") -> ", A("String"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -80,7 +82,8 @@ class FunctionalTypeConstructorsSignatureTest : BaseAbstractTest() {
) {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/index.html").firstSignature().match(
- "val ", A("nF"), ": ", A("Boolean"), ".(", A("Int"), ") -> ", A("String"), Span()
+ "val ", A("nF"), ": ", A("Boolean"), ".(", A("Int"), ") -> ", A("String"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -98,7 +101,8 @@ class FunctionalTypeConstructorsSignatureTest : BaseAbstractTest() {
) {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/index.html").firstSignature().match(
- "val ", A("nF"), ": (param: ", A("Int"), ") -> ", A("String"), Span()
+ "val ", A("nF"), ": (param: ", A("Int"), ") -> ", A("String"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -117,7 +121,8 @@ class FunctionalTypeConstructorsSignatureTest : BaseAbstractTest() {
) {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/index.html").firstSignature().match(
- "val ", A("nF"), ": suspend (", A("Int"), ") -> ", A("String"), Span()
+ "val ", A("nF"), ": suspend (", A("Int"), ") -> ", A("String"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -135,7 +140,8 @@ class FunctionalTypeConstructorsSignatureTest : BaseAbstractTest() {
) {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/index.html").firstSignature().match(
- "val ", A("nF"), ": suspend (", A("Int"), ") -> ", A("String"), Span()
+ "val ", A("nF"), ": suspend (", A("Int"), ") -> ", A("String"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -153,7 +159,8 @@ class FunctionalTypeConstructorsSignatureTest : BaseAbstractTest() {
) {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/index.html").firstSignature().match(
- "val ", A("nF"), ": suspend ", A("Boolean"), ".(", A("Int"), ") -> ", A("String"), Span()
+ "val ", A("nF"), ": suspend ", A("Boolean"), ".(", A("Int"), ") -> ", A("String"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -171,7 +178,8 @@ class FunctionalTypeConstructorsSignatureTest : BaseAbstractTest() {
) {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/index.html").firstSignature().match(
- "val ", A("nF"), ": suspend (param: ", A("Int"), ") -> ", A("String"), Span()
+ "val ", A("nF"), ": suspend (param: ", A("Int"), ") -> ", A("String"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -202,7 +210,8 @@ class FunctionalTypeConstructorsSignatureTest : BaseAbstractTest() {
A("Boolean"),
") -> ",
A("String"),
- Span()
+ Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -227,7 +236,8 @@ class FunctionalTypeConstructorsSignatureTest : BaseAbstractTest() {
) {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/-java-class/index.html").signature().last().match(
- "open val ", A("javaFunction"), ": (", A("Integer"), ") -> ", A("String"), Span()
+ "open val ", A("javaFunction"), ": (", A("Integer"), ") -> ", A("String"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -252,7 +262,8 @@ class FunctionalTypeConstructorsSignatureTest : BaseAbstractTest() {
) {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/-java-class/index.html").signature().last().match(
- "open val ", A("kotlinFunction"), ": (", A("Integer"), ") -> ", A("String"), Span()
+ "open val ", A("kotlinFunction"), ": (", A("Integer"), ") -> ", A("String"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
diff --git a/plugins/base/src/test/kotlin/signatures/SignatureTest.kt b/plugins/base/src/test/kotlin/signatures/SignatureTest.kt
index a56c408b..d8b23d77 100644
--- a/plugins/base/src/test/kotlin/signatures/SignatureTest.kt
+++ b/plugins/base/src/test/kotlin/signatures/SignatureTest.kt
@@ -36,7 +36,8 @@ class SignatureTest : BaseAbstractTest() {
) {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/simple-fun.html").firstSignature().match(
- "fun ", A("simpleFun"), "(): ", A("String"), Span()
+ "fun ", A("simpleFun"), "(): ", A("String"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -54,7 +55,8 @@ class SignatureTest : BaseAbstractTest() {
) {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/simple-fun.html").firstSignature().match(
- "open fun ", A("simpleFun"), "(): ", A("String"), Span()
+ "open fun ", A("simpleFun"), "(): ", A("String"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -72,7 +74,8 @@ class SignatureTest : BaseAbstractTest() {
) {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/simple-fun.html").firstSignature().match(
- "open suspend fun ", A("simpleFun"), "(): ", A("String"), Span()
+ "open suspend fun ", A("simpleFun"), "(): ", A("String"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -92,7 +95,8 @@ class SignatureTest : BaseAbstractTest() {
writerPlugin.writer.renderedContent("root/example/simple-fun.html").firstSignature().match(
"fun ", A("simpleFun"), "(a: ", A("Int"),
", b: ", A("Boolean"), ", c: ", A("Any"),
- "): ", A("String"), Span()
+ "): ", A("String"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -111,7 +115,8 @@ class SignatureTest : BaseAbstractTest() {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/simple-fun.html").firstSignature().match(
"fun ", A("simpleFun"), "(a: (", A("Int"),
- ") -> ", A("String"), "): ", A("String"), Span()
+ ") -> ", A("String"), "): ", A("String"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -130,7 +135,8 @@ class SignatureTest : BaseAbstractTest() {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/simple-fun.html").firstSignature().match(
"fun <", A("T"), "> ", A("simpleFun"), "(): ",
- A("T"), Span()
+ A("T"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -149,7 +155,8 @@ class SignatureTest : BaseAbstractTest() {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/simple-fun.html").firstSignature().match(
"fun <", A("T"), " : ", A("String"), "> ", A("simpleFun"),
- "(): ", A("T"), Span()
+ "(): ", A("T"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -168,7 +175,8 @@ class SignatureTest : BaseAbstractTest() {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/simple-fun.html").firstSignature().match(
"inline suspend fun <", A("T"), " : ", A("String"), "> ", A("simpleFun"),
- "(a: ", A("Int"), ", b: ", A("String"), "): ", A("T"), Span()
+ "(a: ", A("Int"), ", b: ", A("String"), "): ", A("T"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -186,7 +194,8 @@ class SignatureTest : BaseAbstractTest() {
) {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/simple-fun.html").firstSignature().match(
- "fun ", A("simpleFun"), "(vararg params: ", A("Int"), ")", Span()
+ "fun ", A("simpleFun"), "(vararg params: ", A("Int"), ")", Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -204,7 +213,8 @@ class SignatureTest : BaseAbstractTest() {
) {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/-simple-class/index.html").firstSignature().match(
- "class ", A("SimpleClass"), Span()
+ "class ", A("SimpleClass"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -223,7 +233,8 @@ class SignatureTest : BaseAbstractTest() {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/-inheriting-class-from-generic-type/index.html").firstSignature().match(
"class ", A("InheritingClassFromGenericType"), " <", A("T"), " : ", A("Number"), ", ", A("R"), " : ", A("CharSequence"),
- "> : ", A("Comparable"), "<", A("T"), "> , ", A("Collection"), "<", A("R"), ">", Span()
+ "> : ", A("Comparable"), "<", A("T"), "> , ", A("Collection"), "<", A("R"), ">", Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -241,7 +252,8 @@ class SignatureTest : BaseAbstractTest() {
) {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/-k-runnable/index.html").firstSignature().match(
- "fun interface ", A("KRunnable"), Span()
+ "fun interface ", A("KRunnable"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -273,7 +285,8 @@ class SignatureTest : BaseAbstractTest() {
Div("@", A("Marking"))
),
"fun ", A("simpleFun"),
- "(): ", A("String"), Span()
+ "(): ", A("String"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -307,7 +320,8 @@ class SignatureTest : BaseAbstractTest() {
Div("@set:", A("Marking"))
),
"var ", A("str"),
- ": ", A("String"), Span()
+ ": ", A("String"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -347,7 +361,8 @@ class SignatureTest : BaseAbstractTest() {
Div("@", A("Marking2"), "(", Span("int = ", Span("1")), Wbr, ")")
),
"fun ", A("simpleFun"),
- "(): ", A("String"), Span()
+ "(): ", A("String"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -387,7 +402,8 @@ class SignatureTest : BaseAbstractTest() {
)
),
"fun ", A("simpleFun"),
- "(): ", A("String"), Span()
+ "(): ", A("String"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -436,7 +452,8 @@ class SignatureTest : BaseAbstractTest() {
) {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("test/example/-foo/index.html").signature().toList()[1].match(
- "typealias ", A("Foo"), " = ", A("Bar"), Span()
+ "typealias ", A("Foo"), " = ", A("Bar"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -460,7 +477,8 @@ class SignatureTest : BaseAbstractTest() {
) {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example.html").signature().first().match(
- "typealias ", A("PlainTypealias"), " = ", A("Int"), Span()
+ "typealias ", A("PlainTypealias"), " = ", A("Int"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -494,7 +512,8 @@ class SignatureTest : BaseAbstractTest() {
"@", A("SomeAnnotation")
)
),
- "typealias ", A("PlainTypealias"), " = ", A("Int"), Span()
+ "typealias ", A("PlainTypealias"), " = ", A("Int"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -519,7 +538,8 @@ class SignatureTest : BaseAbstractTest() {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example.html").signature().first().match(
"typealias ", A("PlainTypealias"), " = ", A("Comparable"),
- "<", A("Int"), ">", Span()
+ "<", A("Int"), ">", Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -545,7 +565,8 @@ class SignatureTest : BaseAbstractTest() {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example.html").signature().first().match(
"typealias ", A("GenericTypealias"), "<", A("T"), "> = ", A("Comparable"),
- "<", A("T"), ">", Span()
+ "<", A("T"), ">", Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -573,7 +594,8 @@ class SignatureTest : BaseAbstractTest() {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/kotlinAsJavaPlugin/-a-b-c/some-fun.html").signature().first().match(
"fun ", A("someFun"), "(xd: ", A("XD"), "<", A("Int"),
- ", ", A("String"), ">):", A("Int"), Span()
+ ", ", A("String"), ">):", A("Int"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -618,7 +640,7 @@ class SignatureTest : BaseAbstractTest() {
arrayOf("fun ", A("GenericClass"), "(x: ", A("Int"), ")", Span()),
)
).forEach {
- it.first.match(*it.second)
+ it.first.match(*it.second, ignoreSpanWithTokenStyle = true)
}
}
}
@@ -637,7 +659,8 @@ class SignatureTest : BaseAbstractTest() {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/simple-fun.html").firstSignature().match(
"fun", A("simpleFun"), "(int: ", A("Int"), " = 1, string: ", A("String"),
- " = \"string\"): ", A("String"), Span()
+ " = \"string\"): ", A("String"), Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -655,7 +678,8 @@ class SignatureTest : BaseAbstractTest() {
) {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/index.html").firstSignature().match(
- "const val ", A("simpleVal"), ": ", A("Int"), " = 1", Span()
+ "const val ", A("simpleVal"), ": ", A("Int"), " = 1", Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
diff --git a/plugins/base/src/test/kotlin/signatures/VarianceSignatureTest.kt b/plugins/base/src/test/kotlin/signatures/VarianceSignatureTest.kt
index d988bafe..c5d49cec 100644
--- a/plugins/base/src/test/kotlin/signatures/VarianceSignatureTest.kt
+++ b/plugins/base/src/test/kotlin/signatures/VarianceSignatureTest.kt
@@ -38,7 +38,8 @@ class VarianceSignatureTest : BaseAbstractTest() {
) {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/-generic/index.html").firstSignature().match(
- "class ", A("Generic"), "<in ", A("T"), ">", Span()
+ "class ", A("Generic"), "<in ", A("T"), ">", Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -56,7 +57,8 @@ class VarianceSignatureTest : BaseAbstractTest() {
) {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/-generic/index.html").firstSignature().match(
- "class ", A("Generic"), "<out ", A("T"), ">", Span()
+ "class ", A("Generic"), "<out ", A("T"), ">", Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -74,7 +76,8 @@ class VarianceSignatureTest : BaseAbstractTest() {
) {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/-generic/index.html").firstSignature().match(
- "class ", A("Generic"), "<", A("T"), ">", Span()
+ "class ", A("Generic"), "<", A("T"), ">", Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}
@@ -92,7 +95,8 @@ class VarianceSignatureTest : BaseAbstractTest() {
) {
renderingStage = { _, _ ->
writerPlugin.writer.renderedContent("root/example/-generic/index.html").firstSignature().match(
- "class ", A("Generic"), "<out ", A("T"), ":", A("List"), "<", A("CharSequence"), ">>", Span()
+ "class ", A("Generic"), "<out ", A("T"), ":", A("List"), "<", A("CharSequence"), ">>", Span(),
+ ignoreSpanWithTokenStyle = true
)
}
}