From c01e49eec9558736959d12820361624a3c3e41e5 Mon Sep 17 00:00:00 2001 From: Marcin Aman Date: Mon, 1 Mar 2021 11:57:30 +0100 Subject: Suppress tag support (#1742) * Suppress tag support * Support Hide tag in javadoc * Extract hide tag to be in separate plugin --- .../ModuleAndPackageDocumentationReader.kt | 2 +- .../documentables/SuppressTagDocumentableFilter.kt | 12 +++ ...ByConfigurationDocumentableFilterTransformer.kt | 51 ++++++++++ ...SuppressedByTagDocumentableFilterTransformer.kt | 110 +++++++++++++++++++++ .../SuppressedDocumentableFilterTransformer.kt | 51 ---------- 5 files changed, 174 insertions(+), 52 deletions(-) create mode 100644 plugins/base/src/main/kotlin/transformers/documentables/SuppressTagDocumentableFilter.kt create mode 100644 plugins/base/src/main/kotlin/transformers/documentables/SuppressedByConfigurationDocumentableFilterTransformer.kt create mode 100644 plugins/base/src/main/kotlin/transformers/documentables/SuppressedByTagDocumentableFilterTransformer.kt delete mode 100644 plugins/base/src/main/kotlin/transformers/documentables/SuppressedDocumentableFilterTransformer.kt (limited to 'plugins/base/src/main/kotlin/transformers') diff --git a/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationReader.kt b/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationReader.kt index b74242c3..37903988 100644 --- a/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationReader.kt +++ b/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationReader.kt @@ -45,7 +45,7 @@ private class ContextModuleAndPackageDocumentationReader( ): SourceSetDependent { return sourceSets.associateWithNotNull { sourceSet -> val fragments = documentationFragments[sourceSet].orEmpty().filter(predicate) - val resolutionFacade = kotlinAnalysis?.get(sourceSet)?.facade + val resolutionFacade = kotlinAnalysis[sourceSet].facade val documentations = fragments.map { fragment -> parseModuleAndPackageDocumentation( context = ModuleAndPackageDocumentationParsingContext(context.logger, resolutionFacade), diff --git a/plugins/base/src/main/kotlin/transformers/documentables/SuppressTagDocumentableFilter.kt b/plugins/base/src/main/kotlin/transformers/documentables/SuppressTagDocumentableFilter.kt new file mode 100644 index 00000000..7efb23ab --- /dev/null +++ b/plugins/base/src/main/kotlin/transformers/documentables/SuppressTagDocumentableFilter.kt @@ -0,0 +1,12 @@ +package org.jetbrains.dokka.base.transformers.documentables + +import org.jetbrains.dokka.model.Documentable +import org.jetbrains.dokka.model.dfs +import org.jetbrains.dokka.plugability.DokkaContext +import org.jetbrains.dokka.model.doc.Suppress + +class SuppressTagDocumentableFilter(val dokkaContext: DokkaContext) : + SuppressedByTagDocumentableFilterTransformer(dokkaContext) { + override fun shouldBeSuppressed(d: Documentable): Boolean = + d.documentation.any { (_, docs) -> docs.dfs { it is Suppress } != null } +} \ No newline at end of file diff --git a/plugins/base/src/main/kotlin/transformers/documentables/SuppressedByConfigurationDocumentableFilterTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/SuppressedByConfigurationDocumentableFilterTransformer.kt new file mode 100644 index 00000000..a013bfee --- /dev/null +++ b/plugins/base/src/main/kotlin/transformers/documentables/SuppressedByConfigurationDocumentableFilterTransformer.kt @@ -0,0 +1,51 @@ +package org.jetbrains.dokka.base.transformers.documentables + +import org.jetbrains.dokka.model.* +import org.jetbrains.dokka.plugability.DokkaContext +import org.jetbrains.dokka.transformers.documentation.PreMergeDocumentableTransformer +import org.jetbrains.dokka.transformers.documentation.perPackageOptions +import org.jetbrains.dokka.transformers.documentation.source +import org.jetbrains.dokka.transformers.documentation.sourceSet +import java.io.File + +class SuppressedByConfigurationDocumentableFilterTransformer(val context: DokkaContext) : PreMergeDocumentableTransformer { + override fun invoke(modules: List): List { + return modules.mapNotNull(::filterModule) + } + + 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 = perPackageOptions(pkg) + if (options?.suppress == true) { + return null + } + + val filteredChildren = pkg.children.filterNot(::isSuppressed) + return when { + filteredChildren == pkg.children -> pkg + filteredChildren.isEmpty() -> null + else -> pkg.copy( + functions = filteredChildren.filterIsInstance(), + classlikes = filteredChildren.filterIsInstance(), + typealiases = filteredChildren.filterIsInstance(), + properties = filteredChildren.filterIsInstance() + ) + } + } + + private fun isSuppressed(documentable: Documentable): Boolean { + if (documentable !is WithSources) return false + val sourceFile = File(source(documentable).path).absoluteFile + return sourceSet(documentable).suppressedFiles.any { suppressedFile -> + sourceFile.startsWith(suppressedFile.absoluteFile) + } + } +} diff --git a/plugins/base/src/main/kotlin/transformers/documentables/SuppressedByTagDocumentableFilterTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/SuppressedByTagDocumentableFilterTransformer.kt new file mode 100644 index 00000000..f40abe70 --- /dev/null +++ b/plugins/base/src/main/kotlin/transformers/documentables/SuppressedByTagDocumentableFilterTransformer.kt @@ -0,0 +1,110 @@ +package org.jetbrains.dokka.base.transformers.documentables + +import org.jetbrains.dokka.model.* +import org.jetbrains.dokka.plugability.DokkaContext +import org.jetbrains.dokka.transformers.documentation.PreMergeDocumentableTransformer + +abstract class SuppressedByTagDocumentableFilterTransformer(val context: DokkaContext) : PreMergeDocumentableTransformer { + override fun invoke(modules: List): List = + modules.map { module -> + val (documentable, wasChanged) = processModule(module) + documentable.takeIf { wasChanged } ?: module + } + + abstract fun shouldBeSuppressed(d: Documentable): Boolean + + private fun processModule(module: DModule): DocumentableWithChanges { + val afterProcessing = module.packages.map { processPackage(it) } + val processedModule = module.takeIf { afterProcessing.none { it.changed } } + ?: module.copy(packages = afterProcessing.mapNotNull { it.documentable }) + return DocumentableWithChanges(processedModule, afterProcessing.any { it.changed }) + } + + private fun processPackage(dPackage: DPackage): DocumentableWithChanges { + val classlikes = dPackage.classlikes.map { processClassLike(it) } + val typeAliases = dPackage.typealiases.map { processMember(it) } + val functions = dPackage.functions.map { processMember(it) } + val properies = dPackage.properties.map { processMember(it) } + + val wasChanged = (classlikes + typeAliases + functions + properies).any { it.changed } + return (dPackage.takeIf { !wasChanged } ?: dPackage.copy( + classlikes = classlikes.mapNotNull { it.documentable }, + typealiases = typeAliases.mapNotNull { it.documentable }, + functions = functions.mapNotNull { it.documentable }, + properties = properies.mapNotNull { it.documentable } + )).let { processedPackage -> DocumentableWithChanges(processedPackage, wasChanged) } + } + + private fun processClassLike(classlike: DClasslike): DocumentableWithChanges { + if (shouldBeSuppressed(classlike)) return DocumentableWithChanges.filteredDocumentable() + + val functions = classlike.functions.map { processMember(it) } + val classlikes = classlike.classlikes.map { processClassLike(it) } + val properties = classlike.properties.map { processMember(it) } + val companion = (classlike as? WithCompanion)?.companion?.let { processClassLike(it) } + + val wasClasslikeChanged = (functions + classlikes + properties).any { it.changed } || companion?.changed == true + return when (classlike) { + is DClass -> { + val constructors = classlike.constructors.map { processMember(it) } + val wasClassChange = + wasClasslikeChanged || constructors.any { it.changed } + (classlike.takeIf { !wasClassChange } ?: classlike.copy( + functions = functions.mapNotNull { it.documentable }, + classlikes = classlikes.mapNotNull { it.documentable }, + properties = properties.mapNotNull { it.documentable }, + constructors = constructors.mapNotNull { it.documentable }, + companion = companion?.documentable as? DObject + )).let { DocumentableWithChanges(it, wasClassChange) } + } + is DInterface -> (classlike.takeIf { !wasClasslikeChanged } ?: classlike.copy( + functions = functions.mapNotNull { it.documentable }, + classlikes = classlikes.mapNotNull { it.documentable }, + properties = properties.mapNotNull { it.documentable }, + companion = companion?.documentable as? DObject + )).let { DocumentableWithChanges(it, wasClasslikeChanged) } + is DObject -> (classlike.takeIf { !wasClasslikeChanged } ?: classlike.copy( + functions = functions.mapNotNull { it.documentable }, + classlikes = classlikes.mapNotNull { it.documentable }, + properties = properties.mapNotNull { it.documentable }, + )).let { DocumentableWithChanges(it, wasClasslikeChanged) } + is DAnnotation -> { + val constructors = classlike.constructors.map { processMember(it) } + val wasClassChange = + wasClasslikeChanged || constructors.any { it.changed } + (classlike.takeIf { !wasClassChange } ?: classlike.copy( + functions = functions.mapNotNull { it.documentable }, + classlikes = classlikes.mapNotNull { it.documentable }, + properties = properties.mapNotNull { it.documentable }, + constructors = constructors.mapNotNull { it.documentable }, + companion = companion?.documentable as? DObject + )).let { DocumentableWithChanges(it, wasClassChange) } + } + is DEnum -> { + val constructors = classlike.constructors.map { processMember(it) } + val entries = classlike.entries.map { processMember(it) } + val wasClassChange = + wasClasslikeChanged || (constructors + entries).any { it.changed } + (classlike.takeIf { !wasClassChange } ?: classlike.copy( + functions = functions.mapNotNull { it.documentable }, + classlikes = classlikes.mapNotNull { it.documentable }, + properties = properties.mapNotNull { it.documentable }, + constructors = constructors.mapNotNull { it.documentable }, + companion = companion?.documentable as? DObject, + entries = entries.mapNotNull { it.documentable } + )).let { DocumentableWithChanges(it, wasClassChange) } + } + } + } + + private fun processMember(member: T): DocumentableWithChanges = + if (shouldBeSuppressed(member)) DocumentableWithChanges.filteredDocumentable() + else DocumentableWithChanges(member, false) + + private data class DocumentableWithChanges(val documentable: T?, val changed: Boolean = false) { + companion object { + fun filteredDocumentable(): DocumentableWithChanges = + DocumentableWithChanges(null, true) + } + } +} \ No newline at end of file diff --git a/plugins/base/src/main/kotlin/transformers/documentables/SuppressedDocumentableFilterTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/SuppressedDocumentableFilterTransformer.kt deleted file mode 100644 index b066e69b..00000000 --- a/plugins/base/src/main/kotlin/transformers/documentables/SuppressedDocumentableFilterTransformer.kt +++ /dev/null @@ -1,51 +0,0 @@ -package org.jetbrains.dokka.base.transformers.documentables - -import org.jetbrains.dokka.model.* -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.transformers.documentation.PreMergeDocumentableTransformer -import org.jetbrains.dokka.transformers.documentation.perPackageOptions -import org.jetbrains.dokka.transformers.documentation.source -import org.jetbrains.dokka.transformers.documentation.sourceSet -import java.io.File - -class SuppressedDocumentableFilterTransformer(val context: DokkaContext) : PreMergeDocumentableTransformer { - override fun invoke(modules: List): List { - return modules.mapNotNull(::filterModule) - } - - 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 = perPackageOptions(pkg) - if (options?.suppress == true) { - return null - } - - val filteredChildren = pkg.children.filterNot(::isSuppressed) - return when { - filteredChildren == pkg.children -> pkg - filteredChildren.isEmpty() -> null - else -> pkg.copy( - functions = filteredChildren.filterIsInstance(), - classlikes = filteredChildren.filterIsInstance(), - typealiases = filteredChildren.filterIsInstance(), - properties = filteredChildren.filterIsInstance() - ) - } - } - - private fun isSuppressed(documentable: Documentable): Boolean { - if (documentable !is WithSources) return false - val sourceFile = File(source(documentable).path).absoluteFile - return sourceSet(documentable).suppressedFiles.any { suppressedFile -> - sourceFile.startsWith(suppressedFile.absoluteFile) - } - } -} -- cgit