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 | |
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')
4 files changed, 161 insertions, 52 deletions
diff --git a/plugins/base/src/main/kotlin/DokkaBase.kt b/plugins/base/src/main/kotlin/DokkaBase.kt index 86160b4a..ddc06fe0 100644 --- a/plugins/base/src/main/kotlin/DokkaBase.kt +++ b/plugins/base/src/main/kotlin/DokkaBase.kt @@ -36,7 +36,6 @@ import org.jetbrains.dokka.base.translators.descriptors.ExternalClasslikesTransl import org.jetbrains.dokka.base.translators.descriptors.ExternalDocumentablesProvider import org.jetbrains.dokka.base.utils.NoopIntellijLoggerFactory import org.jetbrains.dokka.plugability.DokkaPlugin -import org.jetbrains.dokka.plugability.configuration import org.jetbrains.dokka.transformers.documentation.PreMergeDocumentableTransformer import org.jetbrains.dokka.transformers.pages.PageTransformer @@ -133,7 +132,9 @@ class DokkaBase : DokkaPlugin() { } val sinceKotlinTransformer by extending { - CoreExtensions.documentableTransformer providing ::SinceKotlinTransformer + CoreExtensions.documentableTransformer providing ::SinceKotlinTransformer applyIf { SinceKotlinTransformer.shouldDisplaySinceKotlin() } order { + before(extensionsExtractor) + } } val inheritorsExtractor by extending { @@ -157,7 +158,7 @@ class DokkaBase : DokkaPlugin() { } val sinceKotlinTagContentProvider by extending { - customTagContentProvider with SinceKotlinTagContentProvider + customTagContentProvider with SinceKotlinTagContentProvider applyIf { SinceKotlinTransformer.shouldDisplaySinceKotlin() } } val pageMerger by extending { diff --git a/plugins/base/src/main/kotlin/transformers/documentables/ActualTypealiasAdder.kt b/plugins/base/src/main/kotlin/transformers/documentables/ActualTypealiasAdder.kt index 58c601bc..e895db60 100644 --- a/plugins/base/src/main/kotlin/transformers/documentables/ActualTypealiasAdder.kt +++ b/plugins/base/src/main/kotlin/transformers/documentables/ActualTypealiasAdder.kt @@ -67,12 +67,32 @@ class ActualTypealiasAdder : DocumentableTransformer { if (element.expectPresentInSet != null) { typealiases[element.dri]?.let { ta -> val merged = element.withNewExtras(element.extra + ActualTypealias(ta.underlyingType)).let { - when(it) { - is DClass -> it.copy(sourceSets = element.sourceSets + ta.sourceSets) - is DEnum -> it.copy(sourceSets = element.sourceSets + ta.sourceSets) - is DInterface -> it.copy(sourceSets = element.sourceSets + ta.sourceSets) - is DObject -> it.copy(sourceSets = element.sourceSets + ta.sourceSets) - is DAnnotation -> it.copy(sourceSets = element.sourceSets + ta.sourceSets) + when (it) { + is DClass -> it.copy( + documentation = element.documentation + ta.documentation, + sourceSets = element.sourceSets + ta.sourceSets + ) + + is DEnum -> it.copy( + documentation = element.documentation + ta.documentation, + sourceSets = element.sourceSets + ta.sourceSets + ) + + is DInterface -> it.copy( + documentation = element.documentation + ta.documentation, + sourceSets = element.sourceSets + ta.sourceSets + ) + + is DObject -> it.copy( + documentation = element.documentation + ta.documentation, + sourceSets = element.sourceSets + ta.sourceSets + ) + + is DAnnotation -> it.copy( + documentation = element.documentation + ta.documentation, + sourceSets = element.sourceSets + ta.sourceSets + ) + else -> throw IllegalStateException("${it::class.qualifiedName} ${it.name} cannot have copy its sourceSets") } } 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") + } } diff --git a/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt b/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt index ff60170c..9d45f7a3 100644 --- a/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt +++ b/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt @@ -802,6 +802,7 @@ open class DefaultPageCreator( props.forEach { +buildSignature(it) contentForBrief(it) + contentForCustomTagsBrief(it) } } } |