aboutsummaryrefslogtreecommitdiff
path: root/plugins/base/src
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/base/src')
-rw-r--r--plugins/base/src/main/kotlin/DokkaBase.kt6
-rw-r--r--plugins/base/src/main/kotlin/transformers/documentables/SuppressedDocumentableFilterTransformer.kt68
-rw-r--r--plugins/base/src/test/kotlin/transformers/SuppressedDocumentableFilterTransformerTest.kt188
3 files changed, 261 insertions, 1 deletions
diff --git a/plugins/base/src/main/kotlin/DokkaBase.kt b/plugins/base/src/main/kotlin/DokkaBase.kt
index 6586f2dc..20769d07 100644
--- a/plugins/base/src/main/kotlin/DokkaBase.kt
+++ b/plugins/base/src/main/kotlin/DokkaBase.kt
@@ -64,13 +64,17 @@ class DokkaBase : DokkaPlugin() {
CoreExtensions.preMergeDocumentableTransformer providing ::DeprecatedDocumentableFilterTransformer
}
+ val suppressedDocumentableFilter by extending {
+ CoreExtensions.preMergeDocumentableTransformer providing ::SuppressedDocumentableFilterTransformer
+ }
+
val documentableVisbilityFilter by extending {
CoreExtensions.preMergeDocumentableTransformer providing ::DocumentableVisibilityFilterTransformer
}
val emptyPackagesFilter by extending {
CoreExtensions.preMergeDocumentableTransformer providing ::EmptyPackagesFilterTransformer order {
- after(deprecatedDocumentableFilter, documentableVisbilityFilter)
+ after(deprecatedDocumentableFilter, suppressedDocumentableFilter, documentableVisbilityFilter)
}
}
diff --git a/plugins/base/src/main/kotlin/transformers/documentables/SuppressedDocumentableFilterTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/SuppressedDocumentableFilterTransformer.kt
new file mode 100644
index 00000000..e7a2bf25
--- /dev/null
+++ b/plugins/base/src/main/kotlin/transformers/documentables/SuppressedDocumentableFilterTransformer.kt
@@ -0,0 +1,68 @@
+package org.jetbrains.dokka.base.transformers.documentables
+
+import org.jetbrains.dokka.DokkaConfiguration
+import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet
+import org.jetbrains.dokka.model.*
+import org.jetbrains.dokka.plugability.DokkaContext
+import org.jetbrains.dokka.transformers.documentation.PreMergeDocumentableTransformer
+import java.io.File
+
+class SuppressedDocumentableFilterTransformer(val context: DokkaContext) : PreMergeDocumentableTransformer {
+ override fun invoke(modules: List<DModule>): List<DModule> {
+ return modules.mapNotNull { module -> filterModule(module) }
+ }
+
+ private fun filterModule(module: DModule): DModule? {
+ val packages = module.packages.mapNotNull { pkg -> filterPackage(pkg) }
+ return when {
+ packages == module.packages -> module
+ packages.isEmpty() -> null
+ else -> module.copy(packages = packages)
+ }
+ }
+
+ private fun filterPackage(pkg: DPackage): DPackage? {
+ val options = pkg.perPackageOptions
+ if (options?.suppress == true) {
+ return null
+ }
+
+ val filteredChildren = pkg.children.filter { child -> !isSuppressed(child) }
+ return when {
+ filteredChildren == pkg.children -> pkg
+ filteredChildren.isEmpty() -> null
+ else -> pkg.copy(
+ functions = filteredChildren.filterIsInstance<DFunction>(),
+ classlikes = filteredChildren.filterIsInstance<DClasslike>(),
+ typealiases = filteredChildren.filterIsInstance<DTypeAlias>(),
+ properties = filteredChildren.filterIsInstance<DProperty>()
+ )
+ }
+ }
+
+ private fun isSuppressed(documentable: Documentable): Boolean {
+ if (documentable !is WithExpectActual) return false
+ val sourceFile = File(documentable.source.path).absoluteFile
+ return documentable.sourceSet.suppressedFiles.any { suppressedFile ->
+ sourceFile.startsWith(File(suppressedFile).absoluteFile)
+ }
+ }
+
+ /**
+ * A [PreMergeDocumentableTransformer] can safely assume that documentables are not merged and therefore
+ * only belong to a single source set
+ */
+ private val Documentable.sourceSet: DokkaSourceSet get() = sourceSets.single()
+
+ private val Documentable.perPackageOptions: DokkaConfiguration.PackageOptions?
+ get() {
+ val packageName = dri.packageName ?: return null
+ return sourceSet.perPackageOptions
+ .sortedByDescending { packageOptions -> packageOptions.prefix.length }
+ .firstOrNull { packageOptions -> packageName.startsWith(packageOptions.prefix) }
+ }
+
+ private val <T> T.source: DocumentableSource where T : Documentable, T : WithExpectActual
+ get() = checkNotNull(sources[sourceSet])
+
+}
diff --git a/plugins/base/src/test/kotlin/transformers/SuppressedDocumentableFilterTransformerTest.kt b/plugins/base/src/test/kotlin/transformers/SuppressedDocumentableFilterTransformerTest.kt
new file mode 100644
index 00000000..93b36d2e
--- /dev/null
+++ b/plugins/base/src/test/kotlin/transformers/SuppressedDocumentableFilterTransformerTest.kt
@@ -0,0 +1,188 @@
+package transformers
+
+import org.jetbrains.dokka.PackageOptionsImpl
+import org.jetbrains.dokka.links.DRI
+import org.jetbrains.dokka.testApi.testRunner.AbstractCoreTest
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Assertions.assertIterableEquals
+import org.junit.jupiter.api.Test
+
+class SuppressedDocumentableFilterTransformerTest : AbstractCoreTest() {
+
+ @Test
+ fun `class filtered by package options`() {
+ val configuration = dokkaConfiguration {
+ sourceSets {
+ sourceSet {
+ sourceRoots = listOf("src")
+ perPackageOptions = listOf(
+ packageOptions(prefix = "suppressed", suppress = true),
+ packageOptions(prefix = "default", suppress = false)
+ )
+ }
+ }
+ }
+
+ testInline(
+ """
+ /src/suppressed/Suppressed.kt
+ package suppressed
+ class Suppressed
+
+ /src/default/Default.kt
+ package default
+ class Default.kt
+ """.trimIndent(),
+ configuration
+ ) {
+ documentablesMergingStage = { module ->
+ assertEquals(1, module.children.size, "Expected just a single package in module")
+ assertEquals(1, module.packages.size, "Expected just a single package in module")
+
+ val pkg = module.packages.single()
+ assertEquals("default", pkg.dri.packageName, "Expected 'default' package in module")
+ assertEquals(1, pkg.children.size, "Expected just a single child in 'default' package")
+ assertEquals(1, pkg.classlikes.size, "Expected just a single child in 'default' package")
+
+ val classlike = pkg.classlikes.single()
+ assertEquals(DRI("default", "Default"), classlike.dri, "Expected 'Default' class in 'default' package")
+ }
+ }
+ }
+
+ @Test
+ fun `class filtered by more specific package options`() {
+ val configuration = dokkaConfiguration {
+ sourceSets {
+ sourceSet {
+ sourceRoots = listOf("src")
+ perPackageOptions = listOf(
+ packageOptions(prefix = "parent.some", suppress = false),
+ packageOptions(prefix = "parent.some.suppressed", suppress = true),
+
+ packageOptions(prefix = "parent.other", suppress = true),
+ packageOptions(prefix = "parent.other.default", suppress = false)
+ )
+ }
+ }
+ }
+
+ testInline(
+ """
+ /src/parent/some/Some.kt
+ package parent.some
+ class Some
+
+ /src/parent/some/suppressed/Suppressed.kt
+ package parent.some.suppressed
+ class Suppressed
+
+ /src/parent/other/Other.kt
+ package parent.other
+ class Other
+
+ /src/parent/other/default/Default.kt
+ package parent.other.default
+ class Default
+ """.trimIndent(),
+ configuration
+ ) {
+ documentablesMergingStage = { module ->
+ assertEquals(2, module.packages.size, "Expected two packages in module")
+ assertIterableEquals(
+ listOf(DRI("parent.some"), DRI("parent.other.default")).sortedBy { it.packageName },
+ module.packages.map { it.dri }.sortedBy { it.packageName },
+ "Expected 'parent.some' and 'parent.other.default' packages to be not suppressed"
+ )
+ }
+ }
+ }
+
+ @Test
+ fun `class filtered by parent file path`() {
+ val configuration = dokkaConfiguration {
+ sourceSets {
+ sourceSet {
+ sourceRoots = listOf("src")
+ suppressedFiles = listOf("src/suppressed")
+ }
+ }
+ }
+
+ testInline(
+ """
+ /src/suppressed/Suppressed.kt
+ package suppressed
+ class Suppressed
+
+ /src/default/Default.kt
+ package default
+ class Default.kt
+ """.trimIndent(),
+ configuration
+ ) {
+ documentablesMergingStage = { module ->
+ assertEquals(1, module.children.size, "Expected just a single package in module")
+ assertEquals(1, module.packages.size, "Expected just a single package in module")
+
+ val pkg = module.packages.single()
+ assertEquals("default", pkg.dri.packageName, "Expected 'default' package in module")
+ assertEquals(1, pkg.children.size, "Expected just a single child in 'default' package")
+ assertEquals(1, pkg.classlikes.size, "Expected just a single child in 'default' package")
+
+ val classlike = pkg.classlikes.single()
+ assertEquals(DRI("default", "Default"), classlike.dri, "Expected 'Default' class in 'default' package")
+ }
+ }
+ }
+
+ @Test
+ fun `class filtered by exact file path`() {
+ val configuration = dokkaConfiguration {
+ sourceSets {
+ sourceSet {
+ sourceRoots = listOf("src")
+ suppressedFiles = listOf("src/suppressed/Suppressed.kt")
+ }
+ }
+ }
+
+ testInline(
+ """
+ /src/suppressed/Suppressed.kt
+ package suppressed
+ class Suppressed
+
+ /src/default/Default.kt
+ package default
+ class Default.kt
+ """.trimIndent(),
+ configuration
+ ) {
+ documentablesMergingStage = { module ->
+ assertEquals(1, module.children.size, "Expected just a single package in module")
+ assertEquals(1, module.packages.size, "Expected just a single package in module")
+
+ val pkg = module.packages.single()
+ assertEquals("default", pkg.dri.packageName, "Expected 'default' package in module")
+ assertEquals(1, pkg.children.size, "Expected just a single child in 'default' package")
+ assertEquals(1, pkg.classlikes.size, "Expected just a single child in 'default' package")
+
+ val classlike = pkg.classlikes.single()
+ assertEquals(DRI("default", "Default"), classlike.dri, "Expected 'Default' class in 'default' package")
+ }
+ }
+ }
+
+ private fun packageOptions(
+ prefix: String,
+ suppress: Boolean
+ ) = PackageOptionsImpl(
+ prefix = prefix,
+ suppress = suppress,
+ includeNonPublic = true,
+ reportUndocumented = false,
+ skipDeprecated = false
+ )
+
+}