aboutsummaryrefslogtreecommitdiff
path: root/plugins/base/src/main/kotlin/transformers/pages
diff options
context:
space:
mode:
authorVadim Mishenev <vad-mishenev@yandex.ru>2022-12-16 01:27:30 +0200
committerGitHub <noreply@github.com>2022-12-16 01:27:30 +0200
commitb7a5eac3fc848501735b3520fc12f6f5d21b9bd4 (patch)
tree42c066549023a3d3ecb953b3c2ba71f07ae22e90 /plugins/base/src/main/kotlin/transformers/pages
parentf6ea66cf10f399208ba5c8b01ad5bf323350f651 (diff)
downloaddokka-b7a5eac3fc848501735b3520fc12f6f5d21b9bd4.tar.gz
dokka-b7a5eac3fc848501735b3520fc12f6f5d21b9bd4.tar.bz2
dokka-b7a5eac3fc848501735b3520fc12f6f5d21b9bd4.zip
Display `SinceKotlin` everywhere (#2708)
* Introduce `extraOptions` * Make 'SinceKotlin' option * Display 'SinceKotlin' everywhere * Dump API * Fix CLI bug * Show custom tags in property brief * Show custom tags in extension brief * Show `SinceKotlin` for TypeAlias * Fix `stdlib.diff` * Add a test * Display doc for actual typealias * Propagate SinceKotlin * Refactor * Refactor in `SinceKotlinTransformer` * Revert "Introduce `extraOptions`" This reverts commit b83fdf5da31a97e2ae037f46a735d34a2f84d2ec. * Revert "Make 'SinceKotlin' option" This reverts commit 69f4641d1776f3a4bcd361919212c2de7fa2364e. * Introduce `dokka.SinceKotlin` system property instead of extra arg * Fix API * Fix tests * Rename * Spread on extensions * Put doc and rename prop
Diffstat (limited to 'plugins/base/src/main/kotlin/transformers/pages')
-rw-r--r--plugins/base/src/main/kotlin/transformers/pages/annotations/SinceKotlinTransformer.kt173
1 files changed, 130 insertions, 43 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 f437ebe3..d81cca89 100644
--- a/plugins/base/src/main/kotlin/transformers/pages/annotations/SinceKotlinTransformer.kt
+++ b/plugins/base/src/main/kotlin/transformers/pages/annotations/SinceKotlinTransformer.kt
@@ -1,93 +1,180 @@
package org.jetbrains.dokka.base.transformers.pages.annotations
+import com.intellij.util.containers.ComparatorUtil.max
import org.intellij.markdown.MarkdownElementTypes
-import org.jetbrains.dokka.links.DRI
+import org.jetbrains.dokka.DokkaConfiguration
+import org.jetbrains.dokka.Platform
+import org.jetbrains.dokka.base.signatures.KotlinSignatureUtils.annotations
import org.jetbrains.dokka.model.*
import org.jetbrains.dokka.model.doc.CustomDocTag
import org.jetbrains.dokka.model.doc.CustomTagWrapper
+import org.jetbrains.dokka.model.doc.DocumentationNode
import org.jetbrains.dokka.model.doc.Text
-import org.jetbrains.dokka.model.properties.WithExtraProperties
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() }
+
+ /**
+ * Corner case: 1.0 == 1.0.0
+ */
+ override fun compareTo(other: SinceKotlinVersion): Int {
+ val i1 = parts.listIterator()
+ val i2 = other.parts.listIterator()
+
+ while (i1.hasNext() || i2.hasNext()) {
+ val diff = (if (i1.hasNext()) i1.next() else 0) - (if (i2.hasNext()) i2.next() else 0)
+ if (diff != 0) return diff
+ }
+
+ return 0
+ }
+
+ override fun toString(): String = parts.joinToString(".")
+}
+
class SinceKotlinTransformer(val context: DokkaContext) : DocumentableTransformer {
+ private val minSinceKotlinVersionOfPlatform = mapOf(
+ Platform.common to SinceKotlinVersion("1.2"),
+ Platform.jvm to SinceKotlinVersion("1.0"),
+ Platform.js to SinceKotlinVersion("1.1"),
+ Platform.native to SinceKotlinVersion("1.3")
+ )
+
override fun invoke(original: DModule, context: DokkaContext) = original.transform() as DModule
- private fun <T : Documentable> T.transform(): Documentable =
- when (this) {
+ private fun <T : Documentable> T.transform(parent: SourceSetDependent<SinceKotlinVersion>? = null): Documentable {
+ val versions = calculateVersions(parent)
+ return when (this) {
is DModule -> copy(
packages = packages.map { it.transform() as DPackage }
)
+
is DPackage -> copy(
classlikes = classlikes.map { it.transform() as DClasslike },
functions = functions.map { it.transform() as DFunction },
- properties = properties.map { it.transform() as DProperty }
+ properties = properties.map { it.transform() as DProperty },
+ typealiases = typealiases.map { it.transform() as DTypeAlias }
)
+
is DClass -> copy(
- documentation = appendSinceKotlin(),
- classlikes = classlikes.map { it.transform() as DClasslike },
- functions = functions.map { it.transform() as DFunction },
- properties = properties.map { it.transform() as DProperty }
+ documentation = appendSinceKotlin(versions),
+ classlikes = classlikes.map { it.transform(versions) as DClasslike },
+ functions = functions.map { it.transform(versions) as DFunction },
+ properties = properties.map { it.transform(versions) as DProperty }
)
+
is DEnum -> copy(
- documentation = appendSinceKotlin(),
- classlikes = classlikes.map { it.transform() as DClasslike },
- functions = functions.map { it.transform() as DFunction },
- properties = properties.map { it.transform() as DProperty }
+ documentation = appendSinceKotlin(versions),
+ classlikes = classlikes.map { it.transform(versions) as DClasslike },
+ functions = functions.map { it.transform(versions) as DFunction },
+ properties = properties.map { it.transform(versions) as DProperty }
)
+
is DInterface -> copy(
- documentation = appendSinceKotlin(),
- classlikes = classlikes.map { it.transform() as DClasslike },
- functions = functions.map { it.transform() as DFunction },
- properties = properties.map { it.transform() as DProperty }
+ documentation = appendSinceKotlin(versions),
+ classlikes = classlikes.map { it.transform(versions) as DClasslike },
+ functions = functions.map { it.transform(versions) as DFunction },
+ properties = properties.map { it.transform(versions) as DProperty }
)
+
is DObject -> copy(
- documentation = appendSinceKotlin(),
- classlikes = classlikes.map { it.transform() as DClasslike },
- functions = functions.map { it.transform() as DFunction },
- properties = properties.map { it.transform() as DProperty }
+ documentation = appendSinceKotlin(versions),
+ classlikes = classlikes.map { it.transform(versions) as DClasslike },
+ functions = functions.map { it.transform(versions) as DFunction },
+ properties = properties.map { it.transform(versions) as DProperty }
)
+
+ is DTypeAlias -> copy(
+ documentation = appendSinceKotlin(versions)
+ )
+
is DAnnotation -> copy(
- documentation = appendSinceKotlin(),
- classlikes = classlikes.map { it.transform() as DClasslike },
- functions = functions.map { it.transform() as DFunction },
- properties = properties.map { it.transform() as DProperty }
+ documentation = appendSinceKotlin(versions),
+ classlikes = classlikes.map { it.transform(versions) as DClasslike },
+ functions = functions.map { it.transform(versions) as DFunction },
+ properties = properties.map { it.transform(versions) as DProperty }
)
+
is DFunction -> copy(
- documentation = appendSinceKotlin()
+ documentation = appendSinceKotlin(versions)
)
+
is DProperty -> copy(
- documentation = appendSinceKotlin()
+ documentation = appendSinceKotlin(versions)
)
+
is DParameter -> copy(
- documentation = appendSinceKotlin()
+ documentation = appendSinceKotlin(versions)
)
+
else -> this.also { context.logger.warn("Unrecognized documentable $this while SinceKotlin transformation") }
}
+ }
+
+ private fun List<Annotations.Annotation>.findSinceKotlinAnnotation(): Annotations.Annotation? =
+ this.find { it.dri.packageName == "kotlin" && it.dri.classNames == "SinceKotlin" }
+
+ private fun Documentable.getVersion(sourceSet: DokkaConfiguration.DokkaSourceSet): SinceKotlinVersion {
+ val annotatedVersion =
+ annotations()[sourceSet]
+ ?.findSinceKotlinAnnotation()
+ ?.params?.get("version").safeAs<StringValue>()?.value
+ ?.let { SinceKotlinVersion(it) }
- private fun Documentable.appendSinceKotlin() =
+ val minSinceKotlin = minSinceKotlinVersionOfPlatform[sourceSet.analysisPlatform]
+ ?: throw IllegalStateException("No value for platform: ${sourceSet.analysisPlatform}")
+
+ return annotatedVersion?.takeIf { version -> version >= minSinceKotlin } ?: minSinceKotlin
+ }
+
+
+ private fun Documentable.calculateVersions(parent: SourceSetDependent<SinceKotlinVersion>?): SourceSetDependent<SinceKotlinVersion> {
+ return sourceSets.associateWithNotNull { sourceSet ->
+ val version = getVersion(sourceSet)
+ val parentVersion = parent?.get(sourceSet)
+ if (parentVersion != null)
+ max(version, parentVersion)
+ else
+ version
+ }
+ }
+
+ private fun Documentable.appendSinceKotlin(versions: SourceSetDependent<SinceKotlinVersion>) =
sourceSets.fold(documentation) { acc, sourceSet ->
- safeAs<WithExtraProperties<Documentable>>()?.extra?.get(Annotations)?.directAnnotations?.get(sourceSet)?.find {
- it.dri == DRI("kotlin", "SinceKotlin")
- }?.params?.get("version").safeAs<StringValue>()?.value?.let { version ->
+
+ val version = versions[sourceSet]
+
+ val sinceKotlinCustomTag = CustomTagWrapper(
+ CustomDocTag(
+ listOf(
+ Text(
+ version.toString()
+ )
+ ),
+ name = MarkdownElementTypes.MARKDOWN_FILE.name
+ ),
+ "Since Kotlin"
+ )
+ if (acc[sourceSet] == null)
+ acc + (sourceSet to DocumentationNode(listOf(sinceKotlinCustomTag)))
+ else
acc.mapValues {
if (it.key == sourceSet) it.value.copy(
it.value.children + listOf(
- CustomTagWrapper(
- CustomDocTag(
- listOf(
- Text(version.dropWhile { it == '"' }.dropLastWhile { it == '"' }
- )
- ),
- name = MarkdownElementTypes.MARKDOWN_FILE.name
- ),
- "Since Kotlin"
- )
+ sinceKotlinCustomTag
)
) else it.value
}
- } ?: acc
}
+
+ internal companion object {
+ internal const val SHOULD_DISPLAY_SINCE_KOTLIN_SYS_PROP = "dokka.shouldDisplaySinceKotlin"
+ internal fun shouldDisplaySinceKotlin() =
+ System.getProperty(SHOULD_DISPLAY_SINCE_KOTLIN_SYS_PROP) in listOf("true", "1")
+ }
}