diff options
author | Filip ZybaĆa <fzybala@virtuslab.com> | 2020-05-14 10:17:25 +0200 |
---|---|---|
committer | Sebastian Sellmair <34319766+sellmair@users.noreply.github.com> | 2020-06-25 16:19:29 +0200 |
commit | fff8bb5ffe629bebd2d5e071dd12966a7d89f885 (patch) | |
tree | d56935127c53f3a01cc19e2f61b3dda412a89dd7 /plugins/base/src/main/kotlin/transformers | |
parent | f861b3738a75a5acc112d98b760bd1ada1023882 (diff) | |
download | dokka-fff8bb5ffe629bebd2d5e071dd12966a7d89f885.tar.gz dokka-fff8bb5ffe629bebd2d5e071dd12966a7d89f885.tar.bz2 dokka-fff8bb5ffe629bebd2d5e071dd12966a7d89f885.zip |
Added deprecation filter. Included some tests.
Diffstat (limited to 'plugins/base/src/main/kotlin/transformers')
-rw-r--r-- | plugins/base/src/main/kotlin/transformers/documentables/DocumentableFilter.kt (renamed from plugins/base/src/main/kotlin/transformers/documentables/DocumentableVisibilityFilter.kt) | 281 |
1 files changed, 272 insertions, 9 deletions
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 |