-
Notifications
You must be signed in to change notification settings - Fork 411
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix and refactor Sample Transformer (#3102)
(cherry picked from commit 2fd8e90)
- Loading branch information
1 parent
b8cf2fd
commit 9d7c372
Showing
10 changed files
with
319 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
113 changes: 113 additions & 0 deletions
113
plugins/base/src/main/kotlin/transformers/pages/DefaultSamplesTransformer.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
package org.jetbrains.dokka.base.transformers.pages | ||
|
||
import org.jetbrains.dokka.links.DRI | ||
import org.jetbrains.dokka.model.DisplaySourceSet | ||
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.plugability.plugin | ||
import org.jetbrains.dokka.plugability.querySingle | ||
import org.jetbrains.dokka.transformers.pages.PageTransformer | ||
import org.jetbrains.dokka.analysis.kotlin.internal.InternalKotlinAnalysisPlugin | ||
import org.jetbrains.dokka.analysis.kotlin.internal.SampleProvider | ||
import org.jetbrains.dokka.analysis.kotlin.internal.SampleProviderFactory | ||
|
||
internal const val KOTLIN_PLAYGROUND_SCRIPT = "https://unpkg.com/kotlin-playground@1/dist/playground.min.js" | ||
|
||
internal class DefaultSamplesTransformer(val context: DokkaContext) : PageTransformer { | ||
|
||
private val sampleProviderFactory: SampleProviderFactory = context.plugin<InternalKotlinAnalysisPlugin>().querySingle { sampleProviderFactory } | ||
|
||
override fun invoke(input: RootPageNode): RootPageNode { | ||
return sampleProviderFactory.build().use { sampleProvider -> | ||
input.transformContentPagesTree { page -> | ||
val samples = (page as? WithDocumentables)?.documentables?.flatMap { | ||
it.documentation.entries.flatMap { entry -> | ||
entry.value.children.filterIsInstance<Sample>().map { entry.key to it } | ||
} | ||
} ?: return@transformContentPagesTree page | ||
|
||
val newContent = samples.fold(page.content) { acc, (sampleSourceSet, sample) -> | ||
sampleProvider.getSample(sampleSourceSet, sample.name) | ||
?.let { | ||
acc.addSample(page, sample.name, it) | ||
} ?: acc | ||
} | ||
|
||
page.modified( | ||
content = newContent, | ||
embeddedResources = page.embeddedResources + KOTLIN_PLAYGROUND_SCRIPT | ||
) | ||
} | ||
} | ||
} | ||
|
||
|
||
private fun ContentNode.addSample( | ||
contentPage: ContentPage, | ||
fqLink: String, | ||
sample: SampleProvider.SampleSnippet, | ||
): ContentNode { | ||
val node = contentCode(contentPage.content.sourceSets, contentPage.dri, createSampleBody(sample.imports, sample.body), "kotlin") | ||
return dfs(fqLink, node) | ||
} | ||
|
||
fun createSampleBody(imports: String, body: String) = | ||
""" |$imports | ||
|fun main() { | ||
| //sampleStart | ||
| $body | ||
| //sampleEnd | ||
|}""".trimMargin() | ||
|
||
private fun ContentNode.dfs(fqName: String, node: ContentCodeBlock): ContentNode { | ||
return when (this) { | ||
is ContentHeader -> copy(children.map { it.dfs(fqName, node) }) | ||
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) }) | ||
is ContentCodeBlock -> copy(children.map { it.dfs(fqName, node) }) | ||
is ContentCodeInline -> 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) }) | ||
is ContentEmbeddedResource -> copy(children.map { it.dfs(fqName, node) }) | ||
is ContentTable -> copy(children = children.map { it.dfs(fqName, node) as ContentGroup }) | ||
is ContentList -> copy(children.map { it.dfs(fqName, node) }) | ||
is ContentGroup -> copy(children.map { it.dfs(fqName, node) }) | ||
is PlatformHintedContent -> copy(inner.dfs(fqName, node)) | ||
is ContentText -> if (text == fqName) node else this | ||
is ContentBreakLine -> this | ||
else -> this.also { context.logger.error("Could not recognize $this ContentNode in SamplesTransformer") } | ||
} | ||
} | ||
|
||
private fun contentCode( | ||
sourceSets: Set<DisplaySourceSet>, | ||
dri: Set<DRI>, | ||
content: String, | ||
language: String, | ||
styles: Set<Style> = emptySet(), | ||
extra: PropertyContainer<ContentNode> = PropertyContainer.empty() | ||
) = | ||
ContentCodeBlock( | ||
children = listOf( | ||
ContentText( | ||
text = content, | ||
dci = DCI(dri, ContentKind.Sample), | ||
sourceSets = sourceSets, | ||
style = emptySet(), | ||
extra = PropertyContainer.empty() | ||
) | ||
), | ||
language = language, | ||
dci = DCI(dri, ContentKind.Sample), | ||
sourceSets = sourceSets, | ||
style = styles + ContentStyle.RunnableSample + TextStyle.Monospace, | ||
extra = extra | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 30 additions & 0 deletions
30
...kotlin-api/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/internal/SampleProvider.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package org.jetbrains.dokka.analysis.kotlin.internal | ||
|
||
import org.jetbrains.dokka.DokkaConfiguration | ||
import org.jetbrains.dokka.InternalDokkaApi | ||
|
||
@InternalDokkaApi | ||
interface SampleProviderFactory { | ||
/** | ||
* [SampleProvider] is a short-lived closeable instance. | ||
* It assumes that [SampleProvider] scope of use is not big. | ||
* Otherwise, it can lead to high memory consumption / leaks during Dokka running. | ||
*/ | ||
fun build(): SampleProvider | ||
} | ||
|
||
/** | ||
* It is closeable. | ||
* Otherwise, there is a chance of high memory consumption / leak. | ||
* In general case, it creates a separate project to analysis samples directories. | ||
*/ | ||
@InternalDokkaApi | ||
interface SampleProvider: AutoCloseable { | ||
class SampleSnippet(val imports: String, val body:String) | ||
|
||
|
||
/** | ||
* @return [SampleSnippet] or null if it has not found by [fqLink] | ||
*/ | ||
fun getSample(sourceSet: DokkaConfiguration.DokkaSourceSet, fqLink: String): SampleSnippet? | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.