diff options
Diffstat (limited to 'plugins/base/src/main/kotlin/transformers/pages')
7 files changed, 21 insertions, 226 deletions
diff --git a/plugins/base/src/main/kotlin/transformers/pages/annotations/SinceKotlinTransformer.kt b/plugins/base/src/main/kotlin/transformers/pages/annotations/SinceKotlinTransformer.kt index 75f43324..23b3f625 100644 --- a/plugins/base/src/main/kotlin/transformers/pages/annotations/SinceKotlinTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/pages/annotations/SinceKotlinTransformer.kt @@ -1,9 +1,9 @@ package org.jetbrains.dokka.base.transformers.pages.annotations -import com.intellij.util.containers.ComparatorUtil.max -import org.intellij.markdown.MarkdownElementTypes + import org.jetbrains.dokka.DokkaConfiguration import org.jetbrains.dokka.Platform +import org.jetbrains.dokka.analysis.markdown.jb.MARKDOWN_ELEMENT_FILE_NAME import org.jetbrains.dokka.base.signatures.KotlinSignatureUtils.annotations import org.jetbrains.dokka.model.* import org.jetbrains.dokka.model.doc.CustomDocTag @@ -13,7 +13,6 @@ import org.jetbrains.dokka.model.doc.Text import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.transformers.documentation.DocumentableTransformer import org.jetbrains.dokka.utilities.associateWithNotNull -import org.jetbrains.kotlin.utils.addToStdlib.safeAs class SinceKotlinVersion constructor(str: String) : Comparable<SinceKotlinVersion> { private val parts: List<Int> = str.split(".").map { it.toInt() } @@ -124,7 +123,7 @@ class SinceKotlinTransformer(val context: DokkaContext) : DocumentableTransforme val annotatedVersion = annotations()[sourceSet] ?.findSinceKotlinAnnotation() - ?.params?.get("version").safeAs<StringValue>()?.value + ?.params?.let { it["version"] as? StringValue }?.value ?.let { SinceKotlinVersion(it) } val minSinceKotlin = minSinceKotlinVersionOfPlatform[sourceSet.analysisPlatform] @@ -139,7 +138,7 @@ class SinceKotlinTransformer(val context: DokkaContext) : DocumentableTransforme val version = getVersion(sourceSet) val parentVersion = parent?.get(sourceSet) if (parentVersion != null) - max(version, parentVersion) + maxOf(version, parentVersion) else version } @@ -157,7 +156,7 @@ class SinceKotlinTransformer(val context: DokkaContext) : DocumentableTransforme version.toString() ) ), - name = MarkdownElementTypes.MARKDOWN_FILE.name + name = MARKDOWN_ELEMENT_FILE_NAME ), "Since Kotlin" ) diff --git a/plugins/base/src/main/kotlin/transformers/pages/comments/CommentsToContentConverter.kt b/plugins/base/src/main/kotlin/transformers/pages/comments/CommentsToContentConverter.kt index fa9ce37e..58e22103 100644 --- a/plugins/base/src/main/kotlin/transformers/pages/comments/CommentsToContentConverter.kt +++ b/plugins/base/src/main/kotlin/transformers/pages/comments/CommentsToContentConverter.kt @@ -3,7 +3,9 @@ package org.jetbrains.dokka.base.transformers.pages.comments import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet import org.jetbrains.dokka.model.doc.DocTag import org.jetbrains.dokka.model.properties.PropertyContainer -import org.jetbrains.dokka.pages.* +import org.jetbrains.dokka.pages.ContentNode +import org.jetbrains.dokka.pages.DCI +import org.jetbrains.dokka.pages.Style interface CommentsToContentConverter { fun buildContent( 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 2193283c..083a82cc 100644 --- a/plugins/base/src/main/kotlin/transformers/pages/comments/DocTagToContentConverter.kt +++ b/plugins/base/src/main/kotlin/transformers/pages/comments/DocTagToContentConverter.kt @@ -1,13 +1,14 @@ package org.jetbrains.dokka.base.transformers.pages.comments -import org.intellij.markdown.MarkdownElementTypes + import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet +import org.jetbrains.dokka.analysis.markdown.jb.MARKDOWN_ELEMENT_FILE_NAME import org.jetbrains.dokka.model.doc.* import org.jetbrains.dokka.model.properties.PropertyContainer import org.jetbrains.dokka.model.properties.plus import org.jetbrains.dokka.model.toDisplaySourceSets import org.jetbrains.dokka.pages.* -import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull +import org.jetbrains.dokka.utilities.firstIsInstanceOrNull open class DocTagToContentConverter : CommentsToContentConverter { override fun buildContent( @@ -261,5 +262,5 @@ open class DocTagToContentConverter : CommentsToContentConverter { } } - private fun CustomDocTag.isNonemptyFile() = name == MarkdownElementTypes.MARKDOWN_FILE.name && children.size > 1 + private fun CustomDocTag.isNonemptyFile() = name == MARKDOWN_ELEMENT_FILE_NAME && children.size > 1 } diff --git a/plugins/base/src/main/kotlin/transformers/pages/merger/SourceSetMergingPageTransformer.kt b/plugins/base/src/main/kotlin/transformers/pages/merger/SourceSetMergingPageTransformer.kt index 6cb7f603..f9da616c 100644 --- a/plugins/base/src/main/kotlin/transformers/pages/merger/SourceSetMergingPageTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/pages/merger/SourceSetMergingPageTransformer.kt @@ -3,7 +3,9 @@ package org.jetbrains.dokka.base.transformers.pages.merger import org.jetbrains.dokka.Platform import org.jetbrains.dokka.model.DisplaySourceSet import org.jetbrains.dokka.model.toDisplaySourceSets -import org.jetbrains.dokka.pages.* +import org.jetbrains.dokka.pages.ContentComposite +import org.jetbrains.dokka.pages.ContentNode +import org.jetbrains.dokka.pages.RootPageNode import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.transformers.pages.PageTransformer diff --git a/plugins/base/src/main/kotlin/transformers/pages/samples/DefaultSamplesTransformer.kt b/plugins/base/src/main/kotlin/transformers/pages/samples/DefaultSamplesTransformer.kt deleted file mode 100644 index 49ddd0a5..00000000 --- a/plugins/base/src/main/kotlin/transformers/pages/samples/DefaultSamplesTransformer.kt +++ /dev/null @@ -1,36 +0,0 @@ -package org.jetbrains.dokka.base.transformers.pages.samples - -import com.intellij.psi.PsiElement -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.kotlin.psi.KtBlockExpression -import org.jetbrains.kotlin.psi.KtDeclarationWithBody -import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.utils.addToStdlib.safeAs - -class DefaultSamplesTransformer(context: DokkaContext) : SamplesTransformer(context) { - - override fun processBody(psiElement: PsiElement): String { - val text = processSampleBody(psiElement).trim { it == '\n' || it == '\r' }.trimEnd() - val lines = text.split("\n") - val indent = lines.filter(String::isNotBlank).map { it.takeWhile(Char::isWhitespace).count() }.minOrNull() ?: 0 - return lines.joinToString("\n") { it.drop(indent) } - } - - private fun processSampleBody(psiElement: PsiElement): String = when (psiElement) { - is KtDeclarationWithBody -> { - when (val bodyExpression = psiElement.bodyExpression) { - is KtBlockExpression -> bodyExpression.text.removeSurrounding("{", "}") - else -> bodyExpression!!.text - } - } - else -> psiElement.text - } - - override fun processImports(psiElement: PsiElement): String { - val psiFile = psiElement.containingFile - return when(val text = psiFile.safeAs<KtFile>()?.importList?.text) { - is String -> text - else -> "" - } - } -}
\ 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 deleted file mode 100644 index e72700e0..00000000 --- a/plugins/base/src/main/kotlin/transformers/pages/samples/SamplesTransformer.kt +++ /dev/null @@ -1,148 +0,0 @@ -package org.jetbrains.dokka.base.transformers.pages.samples - -import com.intellij.psi.PsiElement -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.runBlocking -import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet -import org.jetbrains.dokka.analysis.* -import org.jetbrains.dokka.base.DokkaBase -import org.jetbrains.dokka.base.renderers.sourceSets -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.kotlin.idea.kdoc.resolveKDocLink -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils - -internal const val KOTLIN_PLAYGROUND_SCRIPT = "<script src=\"https://unpkg.com/kotlin-playground@1\"></script>" -abstract class SamplesTransformer(val context: DokkaContext) : PageTransformer { - - abstract fun processBody(psiElement: PsiElement): String - abstract fun processImports(psiElement: PsiElement): String - - final override fun invoke(input: RootPageNode): RootPageNode = - /** - * Run from the thread of [Dispatchers.Default]. It can help to avoid a memory leaks in `ThreadLocal`s (that keep `URLCLassLoader`) - * since we shut down Dispatchers. Default at the end of each task (see [org.jetbrains.dokka.DokkaConfiguration.finalizeCoroutines]). - * Currently, all `ThreadLocal`s are in a compiler/IDE codebase. - */ - runBlocking(Dispatchers.Default) { - val analysis = SamplesKotlinAnalysis( - sourceSets = context.configuration.sourceSets, - logger = context.logger, - projectKotlinAnalysis = context.plugin<DokkaBase>().querySingle { kotlinAnalysis } - ) - analysis.use { - 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 } - } - } - - samples?.fold(page as ContentPage) { acc, (sampleSourceSet, sample) -> - acc.modified( - content = acc.content.addSample(page, sampleSourceSet, sample.name, it), - embeddedResources = acc.embeddedResources + KOTLIN_PLAYGROUND_SCRIPT - ) - } ?: page - } - } - } - - private fun ContentNode.addSample( - contentPage: ContentPage, - sourceSet: DokkaSourceSet, - fqName: String, - analysis: KotlinAnalysis - ): ContentNode { - val facade = analysis[sourceSet].facade - val psiElement = fqNameToPsiElement(facade, fqName) - ?: return this.also { context.logger.warn("Cannot find PsiElement corresponding to $fqName") } - val imports = - processImports(psiElement) - val body = processBody(psiElement) - 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: 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 fqNameToPsiElement(resolutionFacade: DokkaResolutionFacade, functionName: String): PsiElement? { - val packageName = functionName.takeWhile { it != '.' } - val descriptor = resolutionFacade.resolveSession.getPackageFragment(FqName(packageName)) - ?: return null.also { context.logger.warn("Cannot find descriptor for package $packageName") } - val symbol = resolveKDocLink( - BindingContext.EMPTY, - resolutionFacade, - descriptor, - null, - functionName.split(".") - ).firstOrNull() ?: return null.also { context.logger.warn("Unresolved function $functionName in @sample") } - return DescriptorToSourceUtils.descriptorToDeclaration(symbol) - } - - 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 - ) -} diff --git a/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt b/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt index 27428fc6..f2c3d3f0 100644 --- a/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt @@ -1,26 +1,19 @@ package org.jetbrains.dokka.base.transformers.pages.sourcelinks -import com.intellij.psi.PsiDocumentManager -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiIdentifier import org.jetbrains.dokka.DokkaConfiguration import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet -import org.jetbrains.dokka.analysis.DescriptorDocumentableSource -import org.jetbrains.dokka.analysis.PsiDocumentableSource import org.jetbrains.dokka.base.DokkaBase import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.model.* +import org.jetbrains.dokka.model.Documentable +import org.jetbrains.dokka.model.DocumentableSource +import org.jetbrains.dokka.model.WithSources +import org.jetbrains.dokka.model.sourceSetIDs 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.kotlin.descriptors.DeclarationDescriptorWithSource -import org.jetbrains.kotlin.lexer.KtTokens -import org.jetbrains.kotlin.psi.psiUtil.getChildOfType -import org.jetbrains.kotlin.resolve.source.getPsi -import org.jetbrains.kotlin.utils.addToStdlib.cast import java.io.File class SourceLinksTransformer(val context: DokkaContext) : PageTransformer { @@ -80,31 +73,13 @@ class SourceLinksTransformer(val context: DokkaContext) : PageTransformer { val sourcePath = File(this.path).invariantSeparatorsPath val sourceLinkPath = File(sourceLink.path).invariantSeparatorsPath - val lineNumber = when (this) { - is DescriptorDocumentableSource -> this.descriptor - .cast<DeclarationDescriptorWithSource>() - .source.getPsi() - ?.lineNumber() - is PsiDocumentableSource -> this.psi.lineNumber() - else -> null - } + val lineNumber = this.computeLineNumber() return sourceLink.url + sourcePath.split(sourceLinkPath)[1] + sourceLink.lineSuffix + "${lineNumber ?: 1}" } - private fun PsiElement.lineNumber(): Int? { - val ktIdentifierTextRange = this.node?.findChildByType(KtTokens.IDENTIFIER)?.textRange - val javaIdentifierTextRange = this.getChildOfType<PsiIdentifier>()?.textRange - // synthetic and some light methods might return null - val textRange = ktIdentifierTextRange ?: javaIdentifierTextRange ?: textRange ?: return null - - val doc = PsiDocumentManager.getInstance(project).getDocument(containingFile) - // IJ uses 0-based line-numbers; external source browsers use 1-based - return doc?.getLineNumber(textRange.startOffset)?.plus(1) - } - private fun ContentNode.signatureGroupOrNull() = (this as? ContentGroup)?.takeIf { it.dci.kind == ContentKind.Symbol } @@ -150,4 +125,4 @@ data class SourceLink(val path: String, val url: String, val lineSuffix: String? sourceLinkDefinition.remoteLineSuffix, sourceSetData ) -}
\ No newline at end of file +} |