aboutsummaryrefslogtreecommitdiff
path: root/plugins/base/src/main/kotlin
diff options
context:
space:
mode:
authorKamil Doległo <kamilok1965@interia.pl>2020-06-25 19:27:21 +0200
committerPaweł Marks <Kordyjan@users.noreply.github.com>2020-06-25 23:39:24 +0200
commit370bf45d2dca5fcd71f53c71386be8667157c446 (patch)
treee720a2277e042ecfa6753882f6cd7939f009dfc0 /plugins/base/src/main/kotlin
parente5daeb9fe276887de95af4995ec53db2b4f407d4 (diff)
downloaddokka-370bf45d2dca5fcd71f53c71386be8667157c446.tar.gz
dokka-370bf45d2dca5fcd71f53c71386be8667157c446.tar.bz2
dokka-370bf45d2dca5fcd71f53c71386be8667157c446.zip
Make samples runnable
Diffstat (limited to 'plugins/base/src/main/kotlin')
-rw-r--r--plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt8
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt39
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/NavigationPage.kt4
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt29
-rw-r--r--plugins/base/src/main/kotlin/transformers/pages/samples/SamplesTransformer.kt57
-rw-r--r--plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt20
6 files changed, 87 insertions, 70 deletions
diff --git a/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt b/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt
index a946aa6f..09d6cad1 100644
--- a/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt
+++ b/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt
@@ -74,8 +74,8 @@ abstract class DefaultRenderer<T>(
nodes.forEach { it.build(this, pageContext, sourceSetRestriction) }
}
- open fun T.buildCode(code: List<ContentNode>, language: String, pageContext: ContentPage) {
- code.forEach { it.build(this, pageContext) }
+ open fun T.buildCode(code: ContentCode, pageContext: ContentPage) {
+ code.children.forEach { it.build(this, pageContext) }
}
open fun T.buildHeader(
@@ -102,7 +102,7 @@ abstract class DefaultRenderer<T>(
when (node) {
is ContentText -> buildText(node)
is ContentHeader -> buildHeader(node, pageContext, sourceSetRestriction)
- is ContentCode -> buildCode(node.children, node.language, pageContext)
+ is ContentCode -> buildCode(node, pageContext)
is ContentDRILink ->
buildLink(locationProvider.resolve(node.address, node.sourceSets.toList(), pageContext)) {
buildLinkText(node.children, pageContext, sourceSetRestriction)
@@ -172,4 +172,4 @@ abstract class DefaultRenderer<T>(
}
}
-fun ContentPage.platforms() = this.content.sourceSets.toList() \ No newline at end of file
+fun ContentPage.sourceSets() = this.content.sourceSets \ No newline at end of file
diff --git a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt
index ee6f1e1f..d56ab50c 100644
--- a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt
+++ b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt
@@ -540,23 +540,11 @@ open class HtmlRenderer(
a(href = address, block = content)
override fun FlowContent.buildCode(
- code: List<ContentNode>,
- language: String,
+ code: ContentCode,
pageContext: ContentPage
) {
- span(classes = "code") {
- val iterator = code.iterator()
- while (iterator.hasNext()) {
- val element = iterator.next()
- +(when (element) {
- is ContentText -> element.text
- is ContentBreakLine -> "\n"
- else -> run { context.logger.error("Cannot cast $element as ContentText!"); "" }
- })
- if (iterator.hasNext()) {
- buildNewLine()
- }
- }
+ code(code.style.joinToString(" ") { it.toString().toLowerCase() }) {
+ code.children.forEach { buildContentNode(it, pageContext) }
}
}
@@ -658,15 +646,20 @@ open class HtmlRenderer(
head {
meta(name = "viewport", content = "width=device-width, initial-scale=1", charset = "UTF-8")
title(page.name)
- with(resources) {
- filter { it.substringBefore('?').substringAfterLast('.') == "css" }
- .forEach { link(rel = LinkRel.stylesheet, href = resolveLink(it, page)) }
- filter { it.substringBefore('?').substringAfterLast('.') == "js" }
- .forEach {
- script(type = ScriptType.textJavaScript, src = resolveLink(it, page)) {
- async = true
- }
+ resources.forEach {
+ when {
+ it.substringBefore('?').substringAfterLast('.') == "css" -> link(
+ rel = LinkRel.stylesheet,
+ href = resolveLink(it, page)
+ )
+ it.substringBefore('?').substringAfterLast('.') == "js" -> script(
+ type = ScriptType.textJavaScript,
+ src = resolveLink(it, page)
+ ) {
+ async = true
}
+ else -> unsafe { +it }
+ }
}
script { unsafe { +"""var pathToRoot = "${locationProvider.resolveRoot(page)}";""" } }
}
diff --git a/plugins/base/src/main/kotlin/renderers/html/NavigationPage.kt b/plugins/base/src/main/kotlin/renderers/html/NavigationPage.kt
index eb563dbd..8fe2a6c8 100644
--- a/plugins/base/src/main/kotlin/renderers/html/NavigationPage.kt
+++ b/plugins/base/src/main/kotlin/renderers/html/NavigationPage.kt
@@ -25,7 +25,7 @@ class NavigationPage(val root: NavigationNode) : RendererSpecificPage {
id = navId
attributes["pageId"] = node.dri.toString()
div("overview") {
- buildLink(node.dri, node.sourceSets) { +node.name }
+ buildLink(node.dri, node.sourceSets.toList()) { +node.name }
if (node.children.isNotEmpty()) {
span("navButton") {
onClick = """document.getElementById("$navId").classList.toggle("hidden");"""
@@ -41,7 +41,7 @@ class NavigationPage(val root: NavigationNode) : RendererSpecificPage {
class NavigationNode(
val name: String,
val dri: DRI,
- val sourceSets: List<DokkaSourceSet>,
+ val sourceSets: Set<DokkaSourceSet>,
val children: List<NavigationNode>
)
diff --git a/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt b/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt
index af0525d7..2f7c8ee1 100644
--- a/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt
+++ b/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt
@@ -4,7 +4,7 @@ import kotlinx.html.h1
import kotlinx.html.id
import kotlinx.html.table
import kotlinx.html.tbody
-import org.jetbrains.dokka.base.renderers.platforms
+import org.jetbrains.dokka.base.renderers.sourceSets
import org.jetbrains.dokka.model.DEnum
import org.jetbrains.dokka.model.DEnumEntry
import org.jetbrains.dokka.pages.*
@@ -45,16 +45,17 @@ object NavigationPageInstaller : PageTransformer {
NavigationNode(
page.name,
page.dri.first(),
- page.platforms(),
+ page.sourceSets(),
page.navigableChildren()
)
private fun ContentPage.navigableChildren(): List<NavigationNode> {
- if(this !is ClasslikePageNode){
+ if (this !is ClasslikePageNode) {
return children.filterIsInstance<ContentPage>()
.map { visit(it) }
- } else if(documentable is DEnum) {
- return children.filter { it is ContentPage && it.documentable is DEnumEntry }.map { visit(it as ContentPage) }
+ } else if (documentable is DEnum) {
+ return children.filter { it is ContentPage && it.documentable is DEnumEntry }
+ .map { visit(it as ContentPage) }
}
return emptyList()
@@ -84,18 +85,20 @@ object StyleAndScriptsAppender : PageTransformer {
}
}
-class SourcesetDependencyAppender(val context: DokkaContext) : PageTransformer{
+class SourcesetDependencyAppender(val context: DokkaContext) : PageTransformer {
override fun invoke(input: RootPageNode): RootPageNode {
val dependenciesMap = context.configuration.sourceSets.map {
it.sourceSetID to it.dependentSourceSets
}.toMap()
- fun createDependenciesJson() : String = "sourceset_dependencies = '{${
- dependenciesMap.entries.joinToString(", ") {
- "\"${it.key}\": [${it.value.joinToString(","){
- "\"$it\""
- }}]"
- }
+
+ fun createDependenciesJson(): String = "sourceset_dependencies = '{${
+ dependenciesMap.entries.joinToString(", ") {
+ "\"${it.key}\": [${it.value.joinToString(",") {
+ "\"$it\""
+ }}]"
+ }
}}'"
+
val deps = RendererSpecificResourcePage(
name = "scripts/sourceset_dependencies.js",
children = emptyList(),
@@ -106,4 +109,4 @@ class SourcesetDependencyAppender(val context: DokkaContext) : PageTransformer{
children = input.children + deps
)
}
-} \ No newline at end of file
+}
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 a40f2f53..b39715a7 100644
--- a/plugins/base/src/main/kotlin/transformers/pages/samples/SamplesTransformer.kt
+++ b/plugins/base/src/main/kotlin/transformers/pages/samples/SamplesTransformer.kt
@@ -1,24 +1,24 @@
package org.jetbrains.dokka.base.transformers.pages.samples
import com.intellij.psi.PsiElement
+import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet
import org.jetbrains.dokka.Platform
import org.jetbrains.dokka.analysis.AnalysisEnvironment
import org.jetbrains.dokka.analysis.DokkaMessageCollector
import org.jetbrains.dokka.analysis.DokkaResolutionFacade
import org.jetbrains.dokka.analysis.EnvironmentAndFacade
-import org.jetbrains.dokka.base.renderers.platforms
+import org.jetbrains.dokka.base.renderers.sourceSets
import org.jetbrains.dokka.links.DRI
-import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet
import org.jetbrains.dokka.model.doc.Sample
import org.jetbrains.dokka.model.properties.PropertyContainer
import org.jetbrains.dokka.pages.*
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.transformers.pages.PageTransformer
-import org.jetbrains.kotlin.name.FqName
-import org.jetbrains.kotlin.utils.PathUtil
import org.jetbrains.kotlin.idea.kdoc.resolveKDocSampleLink
+import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
+import org.jetbrains.kotlin.utils.PathUtil
import java.io.File
abstract class SamplesTransformer(val context: DokkaContext) : PageTransformer {
@@ -27,13 +27,17 @@ abstract class SamplesTransformer(val context: DokkaContext) : PageTransformer {
abstract fun processImports(psiElement: PsiElement): String
final override fun invoke(input: RootPageNode): RootPageNode {
-
val analysis = setUpAnalysis(context)
+ val kotlinPlaygroundScript =
+ "<script src=\"https://unpkg.com/kotlin-playground@1\" data-selector=\"code.runnablesample\"></script>"
return input.transformContentPagesTree { page ->
page.documentable?.documentation?.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))
+ acc.modified(
+ content = acc.content.addSample(page, entry.key, sample.name, analysis),
+ embeddedResources = acc.embeddedResources + kotlinPlaygroundScript
+ )
}
} ?: page
}
@@ -66,22 +70,32 @@ abstract class SamplesTransformer(val context: DokkaContext) : PageTransformer {
?: return this.also { context.logger.warn("Cannot resolve facade for platform ${platform.moduleName}") }
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 imports =
+ processImports(psiElement)
val body = processBody(psiElement)
- val node = contentCode(contentPage.platforms(), contentPage.dri, body, "kotlin")
+ val node = contentCode(contentPage.sourceSets(), contentPage.dri, createSampleBody(imports, body), "kotlin")
return dfs(fqName, node)
}
+ protected open fun createSampleBody(imports: String, body: String) =
+ """ |$imports
+ |fun main() {
+ | //sampleStart
+ | $body
+ | //sampleEnd
+ |}""".trimMargin()
+
private fun ContentNode.dfs(fqName: String, node: ContentCode): ContentNode {
return when (this) {
is ContentHeader -> copy(children.map { it.dfs(fqName, node) })
- is ContentDivergentGroup -> copy(children.map { it.dfs(fqName, node) } as List<ContentDivergentInstance>)
+ is ContentDivergentGroup -> @Suppress("UNCHECKED_CAST") copy(children.map {
+ it.dfs(fqName, node)
+ } as List<ContentDivergentInstance>)
is ContentDivergentInstance -> copy(
before.let { it?.dfs(fqName, node) },
divergent.dfs(fqName, node),
- after.let { it?.dfs(fqName, node) }
- )
+ after.let { it?.dfs(fqName, node) })
is ContentCode -> copy(children.map { it.dfs(fqName, node) })
is ContentDRILink -> copy(children.map { it.dfs(fqName, node) })
is ContentResolvedLink -> copy(children.map { it.dfs(fqName, node) })
@@ -109,21 +123,28 @@ abstract class SamplesTransformer(val context: DokkaContext) : PageTransformer {
return DescriptorToSourceUtils.descriptorToDeclaration(symbol)
}
- private fun contentCode(sourceSets: List<DokkaSourceSet>, dri: Set<DRI>, content: String, language: String) =
+ private fun contentCode(
+ sourceSets: Set<DokkaSourceSet>,
+ dri: Set<DRI>,
+ content: String,
+ language: String,
+ styles: Set<Style> = emptySet(),
+ extra: PropertyContainer<ContentNode> = PropertyContainer.empty()
+ ) =
ContentCode(
children = listOf(
ContentText(
text = content,
- dci = DCI(dri, ContentKind.BriefComment),
- sourceSets = sourceSets.toSet(),
+ dci = DCI(dri, ContentKind.Sample),
+ sourceSets = sourceSets,
style = emptySet(),
extra = PropertyContainer.empty()
)
),
language = language,
- extra = PropertyContainer.empty(),
- dci = DCI(dri, ContentKind.Source),
- sourceSets = sourceSets.toSet(),
- style = emptySet()
+ dci = DCI(dri, ContentKind.Sample),
+ sourceSets = sourceSets,
+ style = styles + ContentStyle.RunnableSample + TextStyle.Monospace,
+ extra = extra
)
} \ No newline at end of file
diff --git a/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt b/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt
index fec986a9..eb2989db 100644
--- a/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt
+++ b/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt
@@ -75,7 +75,7 @@ open class DefaultPageCreator(
sourceSetDependentHint(
m.dri,
m.sourceSets.toSet(),
- kind = ContentKind.SourceSetDependantHint,
+ kind = ContentKind.SourceSetDependentHint,
styles = setOf(TextStyle.UnderCoverText)
) {
+contentForDescription(m)
@@ -97,7 +97,7 @@ open class DefaultPageCreator(
sourceSetDependentHint(
p.dri,
p.sourceSets.toSet(),
- kind = ContentKind.SourceSetDependantHint,
+ kind = ContentKind.SourceSetDependentHint,
styles = setOf(TextStyle.UnderCoverText)
) {
+contentForDescription(p)
@@ -135,7 +135,7 @@ open class DefaultPageCreator(
extra = mainExtra + SimpleAttr.header("Properties")
) {
link(it.name, it.dri, kind = ContentKind.Main)
- sourceSetDependentHint(it.dri, it.sourceSets.toSet(), kind = ContentKind.SourceSetDependantHint) {
+ sourceSetDependentHint(it.dri, it.sourceSets.toSet(), kind = ContentKind.SourceSetDependentHint) {
contentForBrief(it)
+buildSignature(it)
}
@@ -204,7 +204,7 @@ open class DefaultPageCreator(
sourceSetDependentHint(
it.dri,
it.sourceSets.toSet(),
- kind = ContentKind.SourceSetDependantHint,
+ kind = ContentKind.SourceSetDependentHint,
styles = emptySet()
) {
contentForBrief(it)
@@ -224,7 +224,7 @@ open class DefaultPageCreator(
styles = emptySet()
) {
link(it.name, it.dri)
- sourceSetDependentHint(it.dri, it.sourceSets.toSet(), kind = ContentKind.SourceSetDependantHint) {
+ sourceSetDependentHint(it.dri, it.sourceSets.toSet(), kind = ContentKind.SourceSetDependentHint) {
contentForBrief(it)
+buildSignature(it)
}
@@ -319,7 +319,7 @@ open class DefaultPageCreator(
extra = mainExtra + SimpleAttr.header("Parameters"),
styles = setOf(ContentStyle.WithExtraAttributes)
) {
- sourceSetDependentHint(sourceSets = platforms.toSet(), kind = ContentKind.SourceSetDependantHint) {
+ sourceSetDependentHint(sourceSets = platforms.toSet(), kind = ContentKind.SourceSetDependentHint) {
val receiver = tags.withTypeUnnamed<Receiver>()
val params = tags.withTypeNamed<Param>()
table(kind = ContentKind.Parameters) {
@@ -360,7 +360,7 @@ open class DefaultPageCreator(
extra = mainExtra + SimpleAttr.header("See also"),
styles = setOf(ContentStyle.WithExtraAttributes)
) {
- sourceSetDependentHint(sourceSets = platforms.toSet(), kind = ContentKind.SourceSetDependantHint) {
+ sourceSetDependentHint(sourceSets = platforms.toSet(), kind = ContentKind.SourceSetDependentHint) {
val seeAlsoTags = tags.withTypeNamed<See>()
table(kind = ContentKind.Sample) {
platforms.flatMap { platform ->
@@ -395,15 +395,15 @@ open class DefaultPageCreator(
header(2, "Samples")
group(
extra = mainExtra + SimpleAttr.header("Samples"),
- styles = setOf(ContentStyle.WithExtraAttributes)
+ styles = emptySet()
) {
- sourceSetDependentHint(sourceSets = platforms.toSet(), kind = ContentKind.SourceSetDependantHint) {
+ sourceSetDependentHint(sourceSets = platforms.toSet(), kind = ContentKind.SourceSetDependentHint) {
platforms.map { platformData ->
val content = samples.filter { it.value.isEmpty() || platformData in it.value }
group(
sourceSets = setOf(platformData),
kind = ContentKind.Sample,
- styles = setOf(TextStyle.Monospace)
+ styles = setOf(TextStyle.Monospace, ContentStyle.RunnableSample)
) {
content.forEach {
text(it.key)