aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.run/it-basic_dokka.run.xml2
-rw-r--r--integration-tests/gradle/projects/it-basic/build.gradle.kts5
-rw-r--r--integration-tests/gradle/projects/it-basic/src/main/kotlin/it/internal/InternalClass.kt7
-rw-r--r--integration-tests/gradle/projects/it-basic/src/main/kotlin/it/suppressedByPackage/SuppressedByPackage.kt7
-rw-r--r--integration-tests/gradle/projects/it-basic/src/main/kotlin/it/suppressedByPath/SuppressedByPath.kt7
-rw-r--r--integration-tests/gradle/src/integrationTest/kotlin/org/jetbrains/dokka/it/gradle/BasicGradleIntegrationTest.kt1
-rw-r--r--integration-tests/src/main/kotlin/org/jetbrains/dokka/it/AbstractIntegrationTest.kt8
-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
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt1
-rw-r--r--testApi/src/main/kotlin/testApi/testRunner/TestRunner.kt13
12 files changed, 308 insertions, 5 deletions
diff --git a/.run/it-basic_dokka.run.xml b/.run/it-basic_dokka.run.xml
index 42d6ca63..7a9b42bd 100644
--- a/.run/it-basic_dokka.run.xml
+++ b/.run/it-basic_dokka.run.xml
@@ -11,7 +11,7 @@
<option name="taskNames">
<list>
<option value="clean" />
- <option value="dokka" />
+ <option value="dokkaHtml" />
</list>
</option>
<option name="vmOptions" value="" />
diff --git a/integration-tests/gradle/projects/it-basic/build.gradle.kts b/integration-tests/gradle/projects/it-basic/build.gradle.kts
index 1de92418..b3ddde18 100644
--- a/integration-tests/gradle/projects/it-basic/build.gradle.kts
+++ b/integration-tests/gradle/projects/it-basic/build.gradle.kts
@@ -15,6 +15,11 @@ tasks.withType<DokkaTask> {
dokkaSourceSets {
configureEach {
moduleDisplayName = "Basic Project"
+ suppressedFiles = listOf("src/main/kotlin/it/suppressedByPath")
+ perPackageOption {
+ prefix = "it.suppressedByPackage"
+ suppress = true
+ }
}
}
}
diff --git a/integration-tests/gradle/projects/it-basic/src/main/kotlin/it/internal/InternalClass.kt b/integration-tests/gradle/projects/it-basic/src/main/kotlin/it/internal/InternalClass.kt
new file mode 100644
index 00000000..7d42b978
--- /dev/null
+++ b/integration-tests/gradle/projects/it-basic/src/main/kotlin/it/internal/InternalClass.kt
@@ -0,0 +1,7 @@
+package it.internal
+
+/**
+ * §INTERNAL§
+ * This class is internal and should not be rendered
+ */
+internal class InternalClass
diff --git a/integration-tests/gradle/projects/it-basic/src/main/kotlin/it/suppressedByPackage/SuppressedByPackage.kt b/integration-tests/gradle/projects/it-basic/src/main/kotlin/it/suppressedByPackage/SuppressedByPackage.kt
new file mode 100644
index 00000000..d8dc9cff
--- /dev/null
+++ b/integration-tests/gradle/projects/it-basic/src/main/kotlin/it/suppressedByPackage/SuppressedByPackage.kt
@@ -0,0 +1,7 @@
+package it.suppressedByPackage
+
+/**
+ * §SUPPRESSED§
+ * This should not be rendered.
+ */
+class SuppressedByPackage
diff --git a/integration-tests/gradle/projects/it-basic/src/main/kotlin/it/suppressedByPath/SuppressedByPath.kt b/integration-tests/gradle/projects/it-basic/src/main/kotlin/it/suppressedByPath/SuppressedByPath.kt
new file mode 100644
index 00000000..4dda9da4
--- /dev/null
+++ b/integration-tests/gradle/projects/it-basic/src/main/kotlin/it/suppressedByPath/SuppressedByPath.kt
@@ -0,0 +1,7 @@
+package it.suppressedByPath
+
+/**
+ * §SUPPRESSED§
+ * This should not be rendered.
+ */
+class SuppressedByPath
diff --git a/integration-tests/gradle/src/integrationTest/kotlin/org/jetbrains/dokka/it/gradle/BasicGradleIntegrationTest.kt b/integration-tests/gradle/src/integrationTest/kotlin/org/jetbrains/dokka/it/gradle/BasicGradleIntegrationTest.kt
index 54021e81..46577e81 100644
--- a/integration-tests/gradle/src/integrationTest/kotlin/org/jetbrains/dokka/it/gradle/BasicGradleIntegrationTest.kt
+++ b/integration-tests/gradle/src/integrationTest/kotlin/org/jetbrains/dokka/it/gradle/BasicGradleIntegrationTest.kt
@@ -77,6 +77,7 @@ class BasicGradleIntegrationTest(override val versions: BuildVersions) : Abstrac
assertContainsNoErrorClass(file)
assertNoUnresolvedLinks(file)
assertNoHrefToMissingLocalFileOrDirectory(file)
+ assertNoSuppressedMarker(file)
}
assertTrue(
diff --git a/integration-tests/src/main/kotlin/org/jetbrains/dokka/it/AbstractIntegrationTest.kt b/integration-tests/src/main/kotlin/org/jetbrains/dokka/it/AbstractIntegrationTest.kt
index d2e3c980..c4914652 100644
--- a/integration-tests/src/main/kotlin/org/jetbrains/dokka/it/AbstractIntegrationTest.kt
+++ b/integration-tests/src/main/kotlin/org/jetbrains/dokka/it/AbstractIntegrationTest.kt
@@ -68,4 +68,12 @@ abstract class AbstractIntegrationTest {
}
}
}
+
+ protected fun assertNoSuppressedMarker(file: File) {
+ val fileText = file.readText()
+ assertFalse(
+ fileText.contains("§SUPPRESSED§"),
+ "Unexpected `§SUPPRESSED§` in file ${file.path}"
+ )
+ }
}
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
+ )
+
+}
diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt
index f5b66cdb..b4601acf 100644
--- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt
+++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt
@@ -265,6 +265,7 @@ open class DokkaTask : AbstractDokkaTask() {
config.samples = config.samples.map { project.file(it).absolutePath }
config.includes = config.includes.map { project.file(it).absolutePath }
config.suppressedFiles += collectSuppressedFiles(config.sourceRoots)
+ config.suppressedFiles = config.suppressedFiles.map { project.file(it).absolutePath }
return config
}
diff --git a/testApi/src/main/kotlin/testApi/testRunner/TestRunner.kt b/testApi/src/main/kotlin/testApi/testRunner/TestRunner.kt
index 2d79e7e5..25b6b6f2 100644
--- a/testApi/src/main/kotlin/testApi/testRunner/TestRunner.kt
+++ b/testApi/src/main/kotlin/testApi/testRunner/TestRunner.kt
@@ -63,9 +63,16 @@ abstract class AbstractCoreTest {
val newConfiguration =
configuration.copy(
outputDir = testDirPath.toAbsolutePath().toString(),
- sourceSets = configuration.sourceSets.map {
- it.copy(sourceRoots = it.sourceRoots.map { it.copy(path = "${testDirPath.toAbsolutePath()}/${it.path}") })
- }
+ sourceSets = configuration.sourceSets.map { sourceSet ->
+ sourceSet.copy(
+ sourceRoots = sourceSet.sourceRoots.map { sourceRoot ->
+ sourceRoot.copy(path = "${testDirPath.toAbsolutePath()}/${sourceRoot.path}")
+ },
+ suppressedFiles = sourceSet.suppressedFiles.map { suppressedFile ->
+ testDirPath.toAbsolutePath().toFile().resolve(suppressedFile).absolutePath
+ }
+ )
+ },
)
DokkaTestGenerator(
newConfiguration,