diff options
-rw-r--r-- | plugins/base/src/main/kotlin/DokkaBase.kt | 12 | ||||
-rw-r--r-- | plugins/base/src/main/kotlin/transformers/documentables/DocumentableFilter.kt (renamed from plugins/base/src/main/kotlin/transformers/documentables/DocumentableVisibilityFilter.kt) | 281 | ||||
-rw-r--r-- | plugins/base/src/test/kotlin/content/signatures/ContentForSignaturesTest.kt | 1 | ||||
-rw-r--r-- | plugins/base/src/test/kotlin/filter/DeprecationFilterTest.kt | 173 | ||||
-rw-r--r-- | plugins/base/src/test/kotlin/filter/EmptyPackagesFilterTest.kt | 64 | ||||
-rw-r--r-- | plugins/base/src/test/kotlin/filter/VisibilityFilterTest.kt (renamed from plugins/base/src/test/kotlin/visibility/VisibilityFilterTest.kt) | 6 | ||||
-rw-r--r-- | testApi/src/main/kotlin/testApi/testRunner/TestRunner.kt | 2 |
7 files changed, 521 insertions, 18 deletions
diff --git a/plugins/base/src/main/kotlin/DokkaBase.kt b/plugins/base/src/main/kotlin/DokkaBase.kt index 18402863..1d2097ef 100644 --- a/plugins/base/src/main/kotlin/DokkaBase.kt +++ b/plugins/base/src/main/kotlin/DokkaBase.kt @@ -11,10 +11,10 @@ import org.jetbrains.dokka.base.resolvers.local.DefaultLocationProviderFactory import org.jetbrains.dokka.base.resolvers.local.LocationProviderFactory import org.jetbrains.dokka.base.transformers.documentables.* import org.jetbrains.dokka.base.transformers.documentables.DefaultDocumentableMerger -import org.jetbrains.dokka.base.transformers.documentables.DocumentableVisibilityFilter import org.jetbrains.dokka.base.transformers.documentables.ModuleAndPackageDocumentationTransformer import org.jetbrains.dokka.base.transformers.documentables.ReportUndocumentedTransformer import org.jetbrains.dokka.base.transformers.pages.annotations.SinceKotlinTransformer +import org.jetbrains.dokka.base.transformers.documentables.DocumentableFilter import org.jetbrains.dokka.base.transformers.pages.comments.CommentsToContentConverter import org.jetbrains.dokka.base.transformers.pages.comments.DocTagToContentConverter import org.jetbrains.dokka.base.transformers.pages.merger.FallbackPageMergerStrategy @@ -52,7 +52,11 @@ class DokkaBase : DokkaPlugin() { } val preMergeDocumentableTransformer by extending(isFallback = true) { - CoreExtensions.preMergeDocumentableTransformer providing ::DocumentableVisibilityFilter + CoreExtensions.preMergeDocumentableTransformer providing ::DocumentableFilter + } + + val actualTypealiasAdder by extending { + CoreExtensions.documentableTransformer with ActualTypealiasAdder() } val modulesAndPackagesDocumentation by extending(isFallback = true) { @@ -73,14 +77,12 @@ class DokkaBase : DokkaPlugin() { CoreExtensions.documentableTransformer with InheritorsExtractorTransformer() } - val actualTypealiasAdder by extending { - CoreExtensions.documentableTransformer with ActualTypealiasAdder() - } val undocumentedCodeReporter by extending { CoreExtensions.documentableTransformer with ReportUndocumentedTransformer() } + val documentableToPageTranslator by extending(isFallback = true) { CoreExtensions.documentableToPageTranslator providing { ctx -> DefaultDocumentableToPageTranslator( diff --git a/plugins/base/src/main/kotlin/transformers/documentables/DocumentableVisibilityFilter.kt b/plugins/base/src/main/kotlin/transformers/documentables/DocumentableFilter.kt index 66c917c5..fcead846 100644 --- a/plugins/base/src/main/kotlin/transformers/documentables/DocumentableVisibilityFilter.kt +++ b/plugins/base/src/main/kotlin/transformers/documentables/DocumentableFilter.kt @@ -5,23 +5,30 @@ import org.jetbrains.dokka.model.* import org.jetbrains.dokka.model.DAnnotation import org.jetbrains.dokka.model.DEnum import org.jetbrains.dokka.model.DFunction +import org.jetbrains.dokka.model.properties.WithExtraProperties import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.transformers.documentation.PreMergeDocumentableTransformer +import org.jetbrains.kotlin.utils.addToStdlib.safeAs -internal class DocumentableVisibilityFilter(val context: DokkaContext) : PreMergeDocumentableTransformer { +internal class DocumentableFilter(val context: DokkaContext) : PreMergeDocumentableTransformer { override fun invoke(modules: List<DModule>): List<DModule> = modules.map { original -> val packageOptions = context.configuration.passesConfigurations.first { original.sourceSets.contains(context.sourceSet(it)) } .perPackageOptions val passOptions = context.configuration.passesConfigurations.first { - original.platformData.contains(it.platformData) + original.sourceSets.contains(context.sourceSet(it)) + } + original.let { + DeprecationFilter(passOptions,packageOptions).processModule(it) + }.let { + VisibilityFilter(packageOptions, passOptions).processModule(it) + }.let { + EmptyPackagesFilter(passOptions).processModule(it) } - - DocumentableFilter(packageOptions, passOptions).processModule(original) } - private class DocumentableFilter( + private class VisibilityFilter( val packageOptions: List<DokkaConfiguration.PackageOptions>, val globalOptions: DokkaConfiguration.PassConfiguration ) { @@ -48,6 +55,8 @@ internal class DocumentableVisibilityFilter(val context: DokkaContext) : PreMerg ) } + + private fun filterPackages(packages: List<DPackage>): Pair<Boolean, List<DPackage>> { var packagesListChanged = false val filteredPackages = packages.mapNotNull { @@ -66,10 +75,6 @@ internal class DocumentableVisibilityFilter(val context: DokkaContext) : PreMerg } when { !modified -> it - functions.isEmpty() && properties.isEmpty() && classlikes.isEmpty() -> { - packagesListChanged = true - null - } else -> { packagesListChanged = true DPackage( @@ -334,5 +339,263 @@ internal class DocumentableVisibilityFilter(val context: DokkaContext) : PreMerg } return Pair(classlikesListChanged, filteredClasslikes) } + + + } + + private class DeprecationFilter( + val globalOptions: DokkaConfiguration.PassConfiguration, + 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 { + packageName.startsWith(it.prefix) + }?.skipDeprecated + ?: globalOptions.skipDeprecated + + fun T.isDeprecated() = extra[Annotations]?.let { annotations -> + annotations.content.values.flatten().any { + it.dri.toString() == "kotlin/Deprecated///PointingToDeclaration/" + } + } ?: false + + return !(condition && this.isDeprecated()) + } + + fun processModule(original: DModule) = + filterPackages(original.packages).let { (modified, packages) -> + if (!modified) original + else + DModule( + original.name, + packages = packages, + documentation = original.documentation, + sourceSets = original.sourceSets, + extra = original.extra + ) + } + + + private fun filterPackages(packages: List<DPackage>): Pair<Boolean, List<DPackage>> { + var packagesListChanged = false + val filteredPackages = packages.mapNotNull { + var modified = false + val functions = filterFunctions(it.functions).let { (listModified, list) -> + modified = modified || listModified + list + } + val properties = filterProperties(it.properties).let { (listModified, list) -> + modified = modified || listModified + list + } + val classlikes = filterClasslikes(it.classlikes).let { (listModified, list) -> + modified = modified || listModified + list + } + when { + !modified -> it + else -> { + packagesListChanged = true + DPackage( + it.dri, + functions, + properties, + classlikes, + it.typealiases, + it.documentation, + it.expectPresentInSet, + it.sourceSets, + it.extra + ) + } + } + } + return Pair(packagesListChanged, filteredPackages) + } + + private fun filterFunctions( + functions: List<DFunction> + ) = functions.filter { it.isAllowedInPackage() }.let { + Pair(it.size != functions.size, it) + } + + private fun filterProperties( + properties: List<DProperty> + ): Pair<Boolean, List<DProperty>> = properties.filter { + it.isAllowedInPackage() + }.let { + Pair(properties.size != it.size, it) + } + + private fun filterEnumEntries(entries: List<DEnumEntry>) = + entries.filter { it.isAllowedInPackage() }.map { entry -> + DEnumEntry( + entry.dri, + entry.name, + entry.documentation, + entry.expectPresentInSet, + filterFunctions(entry.functions).second, + filterProperties(entry.properties).second, + filterClasslikes(entry.classlikes).second, + entry.sourceSets, + entry.extra + ) + } + + private fun filterClasslikes( + classlikeList: List<DClasslike> + ): Pair<Boolean, List<DClasslike>> { + var modified = false + return classlikeList.filter { + when (it) { + is DClass -> it.isAllowedInPackage() + is DInterface -> it.isAllowedInPackage() + is DEnum -> it.isAllowedInPackage() + is DObject -> it.isAllowedInPackage() + is DAnnotation -> it.isAllowedInPackage() + } + }.map { + fun helper(): DClasslike = when (it) { + is DClass -> DClass( + it.dri, + it.name, + filterFunctions(it.constructors).let { + modified = modified || it.first; it.second + }, + filterFunctions(it.functions).let { + modified = modified || it.first; it.second + }, + filterProperties(it.properties).let { + modified = modified || it.first; it.second + }, + filterClasslikes(it.classlikes).let { + modified = modified || it.first; it.second + }, + it.sources, + it.visibility, + it.companion, + it.generics, + it.supertypes, + it.documentation, + it.expectPresentInSet, + it.modifier, + it.sourceSets, + it.extra + ) + is DAnnotation -> DAnnotation( + it.name, + it.dri, + it.documentation, + it.expectPresentInSet, + it.sources, + filterFunctions(it.functions).let { + modified = modified || it.first; it.second + }, + filterProperties(it.properties).let { + modified = modified || it.first; it.second + }, + filterClasslikes(it.classlikes).let { + modified = modified || it.first; it.second + }, + it.visibility, + it.companion, + filterFunctions(it.constructors).let { + modified = modified || it.first; it.second + }, + it.generics, + it.sourceSets, + it.extra + ) + is DEnum -> DEnum( + it.dri, + it.name, + filterEnumEntries(it.entries), + it.documentation, + it.expectPresentInSet, + it.sources, + filterFunctions(it.functions).let { + modified = modified || it.first; it.second + }, + filterProperties(it.properties).let { + modified = modified || it.first; it.second + }, + filterClasslikes(it.classlikes).let { + modified = modified || it.first; it.second + }, + it.visibility, + it.companion, + filterFunctions(it.constructors).let { + modified = modified || it.first; it.second + }, + it.supertypes, + it.sourceSets, + it.extra + ) + is DInterface -> DInterface( + it.dri, + it.name, + it.documentation, + it.expectPresentInSet, + it.sources, + filterFunctions(it.functions).let { + modified = modified || it.first; it.second + }, + filterProperties(it.properties).let { + modified = modified || it.first; it.second + }, + filterClasslikes(it.classlikes).let { + modified = modified || it.first; it.second + }, + it.visibility, + it.companion, + it.generics, + it.supertypes, + it.sourceSets, + it.extra + ) + is DObject -> DObject( + it.name, + it.dri, + it.documentation, + it.expectPresentInSet, + it.sources, + filterFunctions(it.functions).let { + modified = modified || it.first; it.second + }, + filterProperties(it.properties).let { + modified = modified || it.first; it.second + }, + filterClasslikes(it.classlikes).let { + modified = modified || it.first; it.second + }, + it.visibility, + it.supertypes, + it.sourceSets, + it.extra + ) + } + helper() + }.let { + Pair(it.size != classlikeList.size || modified, it) + } + } + } + + private class EmptyPackagesFilter( + val passOptions: DokkaConfiguration.PassConfiguration + ) { + fun DPackage.shouldBeSkipped() = passOptions.skipEmptyPackages && + functions.isEmpty() && + properties.isEmpty() && + classlikes.isEmpty() + + fun processModule(module: DModule) = module.copy( + packages = module.packages.mapNotNull { pckg -> + if (pckg.shouldBeSkipped()) null + else pckg + } + ) } }
\ No newline at end of file diff --git a/plugins/base/src/test/kotlin/content/signatures/ContentForSignaturesTest.kt b/plugins/base/src/test/kotlin/content/signatures/ContentForSignaturesTest.kt index dc0488c8..20aba2e8 100644 --- a/plugins/base/src/test/kotlin/content/signatures/ContentForSignaturesTest.kt +++ b/plugins/base/src/test/kotlin/content/signatures/ContentForSignaturesTest.kt @@ -16,6 +16,7 @@ class ContentForSignaturesTest : AbstractCoreTest() { pass { sourceRoots = listOf("src/") analysisPlatform = "jvm" + includeNonPublic = true } } } diff --git a/plugins/base/src/test/kotlin/filter/DeprecationFilterTest.kt b/plugins/base/src/test/kotlin/filter/DeprecationFilterTest.kt new file mode 100644 index 00000000..c15e53e8 --- /dev/null +++ b/plugins/base/src/test/kotlin/filter/DeprecationFilterTest.kt @@ -0,0 +1,173 @@ +package filter + +import org.jetbrains.dokka.PackageOptionsImpl +import org.jetbrains.dokka.testApi.testRunner.AbstractCoreTest +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test + +class DeprecationFilterTest : AbstractCoreTest() { + @Test + fun `function with false global skipDeprecated`() { + val configuration = dokkaConfiguration { + passes { + pass { + skipDeprecated = false + sourceRoots = listOf("src/main/kotlin/basic/Test.kt") + } + } + } + + testInline( + """ + |/src/main/kotlin/basic/Test.kt + |package example + | + |fun testFunction() { } + | + | + | + """.trimMargin(), + configuration + ) { + documentablesFirstTransformationStep = { + Assertions.assertTrue( + it.component2().packages.first().functions.size == 1 + ) + } + } + } + @Test + fun `deprecated function with false global skipDeprecated`() { + val configuration = dokkaConfiguration { + passes { + pass { + skipDeprecated = false + sourceRoots = listOf("src/main/kotlin/basic/Test.kt") + } + } + } + + testInline( + """ + |/src/main/kotlin/basic/Test.kt + |package example + | + |@Deprecated("dep") + |fun testFunction() { } + | + | + """.trimMargin(), + configuration + ) { + documentablesFirstTransformationStep = { + Assertions.assertTrue( + it.component2().packages.first().functions.size == 1 + ) + } + } + } + @Test + fun `deprecated function with true global skipDeprecated`() { + val configuration = dokkaConfiguration { + passes { + pass { + sourceRoots = listOf("src/main/kotlin/basic/Test.kt") + skipDeprecated = true + } + } + } + + testInline( + """ + |/src/main/kotlin/basic/Test.kt + |package example + | + |@Deprecated("dep") + |fun testFunction() { } + | + | + """.trimMargin(), + configuration + ) { + documentablesFirstTransformationStep = { + Assertions.assertTrue( + it.component2().packages.first().functions.size == 0 + ) + } + } + } + @Test + fun `deprecated function with false global true package skipDeprecated`() { + val configuration = dokkaConfiguration { + passes { + pass { + sourceRoots = listOf("src/main/kotlin/basic/Test.kt") + skipDeprecated = false + perPackageOptions = mutableListOf( + PackageOptionsImpl("example", + true, + false, + true, + false) + ) + } + } + } + + testInline( + """ + |/src/main/kotlin/basic/Test.kt + |package example + | + |@Deprecated("dep") + |fun testFunction() { } + | + | + """.trimMargin(), + configuration + ) { + documentablesFirstTransformationStep = { + Assertions.assertTrue( + it.component2().packages.first().functions.size == 0 + ) + } + } + } + @Test + fun `deprecated function with true global false package skipDeprecated`() { + val configuration = dokkaConfiguration { + passes { + pass { + sourceRoots = listOf("src/main/kotlin/basic/Test.kt") + skipDeprecated = true + perPackageOptions = mutableListOf( + PackageOptionsImpl("example", + false, + false, + false, + false) + ) + } + } + } + + testInline( + """ + |/src/main/kotlin/basic/Test.kt + |package example + | + |@Deprecated("dep") + |fun testFunction() { } + | + | + """.trimMargin(), + configuration + ) { + documentablesFirstTransformationStep = { + Assertions.assertTrue( + it.component2().packages.first().functions.size == 1 + ) + } + } + } +}
\ No newline at end of file diff --git a/plugins/base/src/test/kotlin/filter/EmptyPackagesFilterTest.kt b/plugins/base/src/test/kotlin/filter/EmptyPackagesFilterTest.kt new file mode 100644 index 00000000..7d96541b --- /dev/null +++ b/plugins/base/src/test/kotlin/filter/EmptyPackagesFilterTest.kt @@ -0,0 +1,64 @@ +package filter + +import org.jetbrains.dokka.PackageOptionsImpl +import org.jetbrains.dokka.testApi.testRunner.AbstractCoreTest +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test + +class EmptyPackagesFilterTest : AbstractCoreTest() { + @Test + fun `empty package with false skipEmptyPackages`() { + val configuration = dokkaConfiguration { + passes { + pass { + skipEmptyPackages = false + sourceRoots = listOf("src/main/kotlin/basic/Test.kt") + } + } + } + + testInline( + """ + |/src/main/kotlin/basic/Test.kt + |package example + | + | + | + """.trimMargin(), + configuration + ) { + documentablesFirstTransformationStep = { + Assertions.assertTrue( + it.component2().packages.isNotEmpty() + ) + } + } + } + @Test + fun `empty package with true skipEmptyPackages`() { + val configuration = dokkaConfiguration { + passes { + pass { + skipEmptyPackages = true + sourceRoots = listOf("src/main/kotlin/basic/Test.kt") + } + } + } + + testInline( + """ + |/src/main/kotlin/basic/Test.kt + |package example + | + | + """.trimMargin(), + configuration + ) { + documentablesFirstTransformationStep = { + Assertions.assertTrue( + it.component2().packages.isEmpty() + ) + } + } + } +}
\ No newline at end of file diff --git a/plugins/base/src/test/kotlin/visibility/VisibilityFilterTest.kt b/plugins/base/src/test/kotlin/filter/VisibilityFilterTest.kt index 1ce567c6..5e8e33dc 100644 --- a/plugins/base/src/test/kotlin/visibility/VisibilityFilterTest.kt +++ b/plugins/base/src/test/kotlin/filter/VisibilityFilterTest.kt @@ -1,4 +1,4 @@ -package visibility +package filter import org.jetbrains.dokka.PackageOptionsImpl import org.jetbrains.dokka.testApi.testRunner.AbstractCoreTest @@ -61,7 +61,7 @@ class VisibilityFilterTest : AbstractCoreTest() { ) { documentablesFirstTransformationStep = { Assertions.assertTrue( - it.component2().packages.isEmpty() + it.component2().packages.first().functions.size == 0 ) } } @@ -165,7 +165,7 @@ class VisibilityFilterTest : AbstractCoreTest() { ) { documentablesFirstTransformationStep = { Assertions.assertTrue( - it.component2().packages.isEmpty() + it.component2().packages.first().functions.size == 0 ) } } diff --git a/testApi/src/main/kotlin/testApi/testRunner/TestRunner.kt b/testApi/src/main/kotlin/testApi/testRunner/TestRunner.kt index ee62d8c7..9df20138 100644 --- a/testApi/src/main/kotlin/testApi/testRunner/TestRunner.kt +++ b/testApi/src/main/kotlin/testApi/testRunner/TestRunner.kt @@ -179,7 +179,7 @@ abstract class AbstractCoreTest { var dependentSourceSets: List<String> = emptyList(), var samples: List<String> = emptyList(), var includes: List<String> = emptyList(), - var includeNonPublic: Boolean = true, + var includeNonPublic: Boolean = false, var includeRootPackage: Boolean = true, var reportUndocumented: Boolean = false, var skipEmptyPackages: Boolean = false, |