aboutsummaryrefslogtreecommitdiff
path: root/plugins/base/src/main
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
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')
-rw-r--r--plugins/base/src/main/kotlin/DokkaBase.kt7
-rw-r--r--plugins/base/src/main/kotlin/transformers/documentables/ActualTypealiasAdder.kt32
-rw-r--r--plugins/base/src/main/kotlin/transformers/pages/annotations/SinceKotlinTransformer.kt173
-rw-r--r--plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt1
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)
}
}
}