diff options
author | Vadim Mishenev <vad-mishenev@yandex.ru> | 2022-12-16 01:27:30 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-16 01:27:30 +0200 |
commit | b7a5eac3fc848501735b3520fc12f6f5d21b9bd4 (patch) | |
tree | 42c066549023a3d3ecb953b3c2ba71f07ae22e90 /plugins/base/src/main/kotlin/transformers/pages | |
parent | f6ea66cf10f399208ba5c8b01ad5bf323350f651 (diff) | |
download | dokka-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.kt | 173 |
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") + } } |