aboutsummaryrefslogtreecommitdiff
path: root/plugins/base
diff options
context:
space:
mode:
authorIgnat Beresnev <ignat.beresnev@jetbrains.com>2022-05-06 15:35:27 +0300
committerGitHub <noreply@github.com>2022-05-06 15:35:27 +0300
commit12bf21bc0814b0b85655e957ce9f3a99ef389785 (patch)
tree32d80c870acafdca19f3fa8ab58ce8506ab304d3 /plugins/base
parent88d36234b710f2ef50db9d874e25fd2378f430ac (diff)
downloaddokka-12bf21bc0814b0b85655e957ce9f3a99ef389785.tar.gz
dokka-12bf21bc0814b0b85655e957ce9f3a99ef389785.tar.bz2
dokka-12bf21bc0814b0b85655e957ce9f3a99ef389785.zip
Skip `@Deprecated` documentables with HIDDEN level (#2486)
Diffstat (limited to 'plugins/base')
-rw-r--r--plugins/base/api/base.api5
-rw-r--r--plugins/base/src/main/kotlin/transformers/documentables/DeprecatedDocumentableFilterTransformer.kt225
-rw-r--r--plugins/base/src/test/kotlin/filter/DeprecationFilterTest.kt80
3 files changed, 126 insertions, 184 deletions
diff --git a/plugins/base/api/base.api b/plugins/base/api/base.api
index 4b68b3d7..083c9973 100644
--- a/plugins/base/api/base.api
+++ b/plugins/base/api/base.api
@@ -1124,10 +1124,9 @@ public final class org/jetbrains/dokka/base/transformers/documentables/ClashingD
public fun mergeStrategyFor (Lorg/jetbrains/dokka/base/transformers/documentables/ClashingDriIdentifier;Lorg/jetbrains/dokka/base/transformers/documentables/ClashingDriIdentifier;)Lorg/jetbrains/dokka/model/properties/MergeStrategy;
}
-public final class org/jetbrains/dokka/base/transformers/documentables/DeprecatedDocumentableFilterTransformer : org/jetbrains/dokka/transformers/documentation/PreMergeDocumentableTransformer {
+public final class org/jetbrains/dokka/base/transformers/documentables/DeprecatedDocumentableFilterTransformer : org/jetbrains/dokka/base/transformers/documentables/SuppressedByConditionDocumentableFilterTransformer {
public fun <init> (Lorg/jetbrains/dokka/plugability/DokkaContext;)V
- public final fun getContext ()Lorg/jetbrains/dokka/plugability/DokkaContext;
- public fun invoke (Ljava/util/List;)Ljava/util/List;
+ public fun shouldBeSuppressed (Lorg/jetbrains/dokka/model/Documentable;)Z
}
public abstract class org/jetbrains/dokka/base/transformers/documentables/DocumentableReplacerTransformer : org/jetbrains/dokka/transformers/documentation/PreMergeDocumentableTransformer {
diff --git a/plugins/base/src/main/kotlin/transformers/documentables/DeprecatedDocumentableFilterTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/DeprecatedDocumentableFilterTransformer.kt
index 0f7795e6..1112ac15 100644
--- a/plugins/base/src/main/kotlin/transformers/documentables/DeprecatedDocumentableFilterTransformer.kt
+++ b/plugins/base/src/main/kotlin/transformers/documentables/DeprecatedDocumentableFilterTransformer.kt
@@ -1,194 +1,57 @@
package org.jetbrains.dokka.base.transformers.documentables
+import org.jetbrains.dokka.DokkaConfiguration.PackageOptions
import org.jetbrains.dokka.DokkaConfiguration
-import org.jetbrains.dokka.model.*
+import org.jetbrains.dokka.model.Annotations
+import org.jetbrains.dokka.model.Documentable
+import org.jetbrains.dokka.model.EnumValue
import org.jetbrains.dokka.model.properties.WithExtraProperties
import org.jetbrains.dokka.plugability.DokkaContext
-import org.jetbrains.dokka.transformers.documentation.PreMergeDocumentableTransformer
-
-class DeprecatedDocumentableFilterTransformer(val context: DokkaContext) : PreMergeDocumentableTransformer {
- override fun invoke(modules: List<DModule>) = modules.map { original ->
- val sourceSet = original.sourceSets.single()
- val packageOptions =
- sourceSet.perPackageOptions
- original.let {
- DeprecatedDocumentableFilter(sourceSet, packageOptions).processModule(it)
- }
+import org.jetbrains.dokka.transformers.documentation.perPackageOptions
+import org.jetbrains.dokka.transformers.documentation.sourceSet
+
+/**
+ * If [PackageOptions.skipDeprecated] or [DokkaConfiguration.DokkaSourceSet.skipDeprecated] is set
+ * to `true`, suppresses documentables marked with [kotlin.Deprecated] or [java.lang.Deprecated].
+ * Package options are given preference over global options.
+ *
+ * Documentables with [kotlin.Deprecated.level] set to [DeprecationLevel.HIDDEN]
+ * are suppressed regardless of global and package options.
+ */
+class DeprecatedDocumentableFilterTransformer(context: DokkaContext) :
+ SuppressedByConditionDocumentableFilterTransformer(context) {
+
+ override fun shouldBeSuppressed(d: Documentable): Boolean {
+ val annotations = (d as? WithExtraProperties<*>)?.annotations() ?: return false
+ if (annotations.isEmpty())
+ return false
+
+ val deprecatedAnnotations = filterDeprecatedAnnotations(annotations)
+ if (deprecatedAnnotations.isEmpty())
+ return false
+
+ val kotlinDeprecated = deprecatedAnnotations.find { it.dri.packageName == "kotlin" }
+ if (kotlinDeprecated?.isHidden() == true)
+ return true
+
+ return perPackageOptions(d)?.skipDeprecated ?: sourceSet(d).skipDeprecated
}
- private class DeprecatedDocumentableFilter(
- val globalOptions: DokkaConfiguration.DokkaSourceSet,
- val packageOptions: List<DokkaConfiguration.PackageOptions>
- ) {
-
- fun <T> T.isAllowedInPackage(): Boolean where T : WithExtraProperties<T>, T : Documentable {
- val packageName = this.dri.packageName
- val condition = packageName != null && packageOptions.firstOrNull {
- Regex(it.matchingRegex).matches(packageName)
- }?.skipDeprecated
- ?: globalOptions.skipDeprecated
-
- return !(condition && this.isDeprecated())
- }
-
- fun processModule(original: DModule) =
- filterPackages(original.packages).let { (modified, packages) ->
- if (!modified) original
- else
- original.copy(
- packages = packages
- )
- }
-
-
- private fun filterPackages(packages: List<DPackage>): Pair<Boolean, List<DPackage>> {
- var packagesListChanged = false
- val filteredPackages = packages.mapNotNull { pckg ->
- var modified = false
- val functions = filterFunctions(pckg.functions).let { (listModified, list) ->
- modified = modified || listModified
- list
- }
- val properties = filterProperties(pckg.properties).let { (listModified, list) ->
- modified = modified || listModified
- list
- }
- val classlikes = filterClasslikes(pckg.classlikes).let { (listModified, list) ->
- modified = modified || listModified
- list
- }
- val typeAliases = filterTypeAliases(pckg.typealiases).let { (listModified, list) ->
- modified = modified || listModified
- list
- }
- when {
- !modified -> pckg
- else -> {
- packagesListChanged = true
- pckg.copy(
- functions = functions,
- properties = properties,
- classlikes = classlikes,
- typealiases = typeAliases
- )
- }
- }
- }
- return Pair(packagesListChanged, filteredPackages)
- }
-
- private fun filterFunctions(
- functions: List<DFunction>
- ) = functions.filter { it.isAllowedInPackage() }.let {
- Pair(it.size != functions.size, it)
+ private fun WithExtraProperties<*>.annotations(): List<Annotations.Annotation> {
+ return this.extra.allOfType<Annotations>().flatMap { annotations ->
+ annotations.directAnnotations.values.singleOrNull() ?: emptyList()
}
+ }
- private fun filterProperties(
- properties: List<DProperty>
- ): Pair<Boolean, List<DProperty>> = properties.filter {
- it.isAllowedInPackage()
- }.let {
- Pair(properties.size != it.size, it)
+ private fun filterDeprecatedAnnotations(annotations: List<Annotations.Annotation>): List<Annotations.Annotation> {
+ return annotations.filter {
+ (it.dri.packageName == "kotlin" && it.dri.classNames == "Deprecated") ||
+ (it.dri.packageName == "java.lang" && it.dri.classNames == "Deprecated")
}
+ }
- private fun filterEnumEntries(entries: List<DEnumEntry>) =
- entries.filter { it.isAllowedInPackage() }.map { entry ->
- entry.copy(
- functions = filterFunctions(entry.functions).second,
- properties = filterProperties(entry.properties).second,
- classlikes = filterClasslikes(entry.classlikes).second,
- )
- }
-
- private fun filterTypeAliases(typeAliases: List<DTypeAlias>) =
- typeAliases.filter { it.isAllowedInPackage() }.let {
- Pair(typeAliases.size != it.size, it)
- }
-
- private fun filterClasslikes(
- classlikeList: List<DClasslike>
- ): Pair<Boolean, List<DClasslike>> {
- var modified = false
- return classlikeList.filter { classlike ->
- when (classlike) {
- is DClass -> classlike.isAllowedInPackage()
- is DInterface -> classlike.isAllowedInPackage()
- is DEnum -> classlike.isAllowedInPackage()
- is DObject -> classlike.isAllowedInPackage()
- is DAnnotation -> classlike.isAllowedInPackage()
- }
- }.map { classlike ->
- fun helper(): DClasslike = when (classlike) {
- is DClass -> classlike.copy(
- constructors = filterFunctions(classlike.constructors).let {
- modified = modified || it.first; it.second
- },
- functions = filterFunctions(classlike.functions).let {
- modified = modified || it.first; it.second
- },
- properties = filterProperties(classlike.properties).let {
- modified = modified || it.first; it.second
- },
- classlikes = filterClasslikes(classlike.classlikes).let {
- modified = modified || it.first; it.second
- }
- )
- is DAnnotation -> classlike.copy(
- functions = filterFunctions(classlike.functions).let {
- modified = modified || it.first; it.second
- },
- properties = filterProperties(classlike.properties).let {
- modified = modified || it.first; it.second
- },
- classlikes = filterClasslikes(classlike.classlikes).let {
- modified = modified || it.first; it.second
- },
- constructors = filterFunctions(classlike.constructors).let {
- modified = modified || it.first; it.second
- }
- )
- is DEnum -> classlike.copy(
- entries = filterEnumEntries(classlike.entries),
- functions = filterFunctions(classlike.functions).let {
- modified = modified || it.first; it.second
- },
- properties = filterProperties(classlike.properties).let {
- modified = modified || it.first; it.second
- },
- classlikes = filterClasslikes(classlike.classlikes).let {
- modified = modified || it.first; it.second
- },
- constructors = filterFunctions(classlike.constructors).let {
- modified = modified || it.first; it.second
- },
- )
- is DInterface -> classlike.copy(
- functions = filterFunctions(classlike.functions).let {
- modified = modified || it.first; it.second
- },
- properties = filterProperties(classlike.properties).let {
- modified = modified || it.first; it.second
- },
- classlikes = filterClasslikes(classlike.classlikes).let {
- modified = modified || it.first; it.second
- }
- )
- is DObject -> classlike.copy(
- functions = filterFunctions(classlike.functions).let {
- modified = modified || it.first; it.second
- },
- properties = filterProperties(classlike.properties).let {
- modified = modified || it.first; it.second
- },
- classlikes = filterClasslikes(classlike.classlikes).let {
- modified = modified || it.first; it.second
- }
- )
- }
- helper()
- }.let {
- Pair(it.size != classlikeList.size || modified, it)
- }
- }
+ private fun Annotations.Annotation.isHidden(): Boolean {
+ val level = (this.params["level"] as? EnumValue) ?: return false
+ return level.enumName == "DeprecationLevel.HIDDEN"
}
}
diff --git a/plugins/base/src/test/kotlin/filter/DeprecationFilterTest.kt b/plugins/base/src/test/kotlin/filter/DeprecationFilterTest.kt
index 295a969b..44caecaa 100644
--- a/plugins/base/src/test/kotlin/filter/DeprecationFilterTest.kt
+++ b/plugins/base/src/test/kotlin/filter/DeprecationFilterTest.kt
@@ -7,6 +7,47 @@ import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
class DeprecationFilterTest : BaseAbstractTest() {
+
+ @Test
+ fun `should skip hidden deprecated level regardless of skipDeprecated`() {
+ val configuration = dokkaConfiguration {
+ sourceSets {
+ sourceSet {
+ sourceRoots = listOf("src/main/kotlin/basic/Test.kt")
+ skipDeprecated = false
+ perPackageOptions = mutableListOf(
+ PackageOptionsImpl(
+ "example.*",
+ true,
+ false,
+ false,
+ false,
+ DokkaDefaults.documentedVisibilities
+ )
+ )
+ }
+ }
+ }
+
+ testInline(
+ """
+ |/src/main/kotlin/basic/Test.kt
+ |package example
+ |
+ |@Deprecated("dep", level = DeprecationLevel.HIDDEN)
+ |fun testFunction() { }
+ |
+ """.trimMargin(),
+ configuration
+ ) {
+ preMergeDocumentablesTransformationStage = {
+ Assertions.assertTrue(
+ it.first().packages.first().functions.isEmpty()
+ )
+ }
+ }
+ }
+
@Test
fun `function with false global skipDeprecated`() {
val configuration = dokkaConfiguration {
@@ -37,6 +78,7 @@ class DeprecationFilterTest : BaseAbstractTest() {
}
}
}
+
@Test
fun `deprecated function with false global skipDeprecated`() {
val configuration = dokkaConfiguration {
@@ -67,6 +109,7 @@ class DeprecationFilterTest : BaseAbstractTest() {
}
}
}
+
@Test
fun `deprecated function with true global skipDeprecated`() {
val configuration = dokkaConfiguration {
@@ -97,6 +140,42 @@ class DeprecationFilterTest : BaseAbstractTest() {
}
}
}
+
+ @Test
+ fun `should skip deprecated companion object`() {
+ val configuration = dokkaConfiguration {
+ sourceSets {
+ sourceSet {
+ sourceRoots = listOf("src/main/kotlin/basic/Test.kt")
+ skipDeprecated = true
+ }
+ }
+ }
+
+ testInline(
+ """
+ |/src/main/kotlin/basic/Test.kt
+ |package example
+ |
+ |class Test {
+ | @Deprecated("dep")
+ | companion object {
+ | fun method() {}
+ | }
+ |}
+ |
+ |
+ """.trimMargin(),
+ configuration
+ ) {
+ preMergeDocumentablesTransformationStage = {
+ Assertions.assertTrue(
+ it.first().packages.first().classlikes.first().classlikes.isEmpty()
+ )
+ }
+ }
+ }
+
@Test
fun `deprecated function with false global true package skipDeprecated`() {
val configuration = dokkaConfiguration {
@@ -137,6 +216,7 @@ class DeprecationFilterTest : BaseAbstractTest() {
}
}
}
+
@Test
fun `deprecated function with true global false package skipDeprecated`() {
val configuration = dokkaConfiguration {