Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suppress tag support #1742

Merged
merged 3 commits into from
Mar 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/src/doc/docs/user_guide/android-plugin/android-plugin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Android documentationn plugin

Android documentation plugin aims to improve the documentation on android platform.

### Features:

* `@hide` support - `@hide` javadoc tag is an equivalent of `@suppress` tag in kdoc. It hides certain entry from being
displayed in the documentation.
1 change: 1 addition & 0 deletions docs/src/doc/docs/user_guide/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Currently maintained plugins are:
* `jekyll-plugin` - configures `Jekyll` output format
* `javadoc-plugin` - configures `Javadoc` output format, automatically applies `kotlin-as-java-plugin`
* `kotlin-as-java-plugin` - translates Kotlin definitions to Java
* `android-documentation-plugin` - provides android specific enhancements like `@hide` support

Please see the usage instructions for each build system on how to add plugins to Dokka.

Expand Down
1 change: 1 addition & 0 deletions docs/src/doc/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ nav:
- Maven: user_guide/maven/usage.md
- Command line: user_guide/cli/usage.md
- Html frontend: user_guide/base-specific/frontend.md
- Android plugin: user_guide/android-plugin/android-plugin.md
- Plugin development:
- Introduction: developer_guide/introduction.md
- Data model: developer_guide/data_model.md
Expand Down
11 changes: 11 additions & 0 deletions plugins/android-documentation/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import org.jetbrains.registerDokkaArtifactPublication

dependencies {
implementation(project(":plugins:base"))
testImplementation(project(":plugins:base"))
testImplementation(project(":plugins:base:base-test-utils"))
}

registerDokkaArtifactPublication("androidDocumentationPlugin") {
artifactId = "android-documentation-plugin"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.jetbrains.dokka.android

import org.jetbrains.dokka.android.transformers.HideTagDocumentableFilter
import org.jetbrains.dokka.base.DokkaBase
import org.jetbrains.dokka.plugability.DokkaPlugin

class AndroidDocumentationPlugin : DokkaPlugin() {
private val dokkaBase by lazy { plugin<DokkaBase>() }

val suppressedByHideTagDocumentableFilter by extending {
dokkaBase.preMergeDocumentableTransformer providing ::HideTagDocumentableFilter order { before(dokkaBase.emptyPackagesFilter) }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.jetbrains.dokka.android.transformers

import org.jetbrains.dokka.base.transformers.documentables.SuppressedByTagDocumentableFilterTransformer
import org.jetbrains.dokka.model.Documentable
import org.jetbrains.dokka.model.dfs
import org.jetbrains.dokka.model.doc.CustomTagWrapper
import org.jetbrains.dokka.plugability.DokkaContext

class HideTagDocumentableFilter(val dokkaContext: DokkaContext) :
SuppressedByTagDocumentableFilterTransformer(dokkaContext) {
override fun shouldBeSuppressed(d: Documentable): Boolean =
d.documentation.any { (_, docs) -> docs.dfs { it is CustomTagWrapper && it.name.trim() == "hide" } != null }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
org.jetbrains.dokka.android.AndroidDocumentationPlugin
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package transformers

import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest
import org.jetbrains.dokka.model.DClass
import kotlin.test.assertEquals
import org.junit.jupiter.api.Test

class HideTagDocumentableFilterTest : BaseAbstractTest() {
private val configuration = dokkaConfiguration {
sourceSets {
sourceSet {
sourceRoots = listOf("src")
}
}
}


@Test
fun `should work as hide in java with functions`() {
testInline(
"""
|/src/suppressed/Testing.java
|package testing;
|
|public class Testing {
| /**
| * @hide
| */
| public void shouldNotBeVisible() { }
|}
""".trimIndent(), configuration
) {
documentablesFirstTransformationStep = { modules ->
val testingClass = modules.flatMap { it.packages }.flatMap { it.classlikes }.single() as DClass
assertEquals(0, testingClass.functions.size)
}
}
}

@Test
fun `should work as hide in java with classes`() {
testInline(
"""
|/src/suppressed/Suppressed.java
|package testing;
|
|/**
| * @hide
| */
|public class Suppressed {
|}
|/src/suppressed/Visible.java
|package testing;
|
|/**
| * Another docs
| * @undeprecate
| */
|public class Visible {
|}
""".trimIndent(), configuration
) {
documentablesFirstTransformationStep = { modules ->
val classes = modules.flatMap { it.packages }.flatMap { it.classlikes }.map { it.name }
assertEquals(listOf("Visible"), classes)
}
}
}


}
13 changes: 11 additions & 2 deletions plugins/base/src/main/kotlin/DokkaBase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,11 @@ class DokkaBase : DokkaPlugin() {
}

val suppressedDocumentableFilter by extending {
preMergeDocumentableTransformer providing ::SuppressedDocumentableFilterTransformer
preMergeDocumentableTransformer providing ::SuppressedByConfigurationDocumentableFilterTransformer
}

val suppressedBySuppressTagDocumentableFilter by extending {
preMergeDocumentableTransformer providing ::SuppressTagDocumentableFilter
}

val documentableVisbilityFilter by extending {
Expand All @@ -76,7 +80,12 @@ class DokkaBase : DokkaPlugin() {

val emptyPackagesFilter by extending {
preMergeDocumentableTransformer providing ::EmptyPackagesFilterTransformer order {
after(deprecatedDocumentableFilter, suppressedDocumentableFilter, documentableVisbilityFilter)
after(
deprecatedDocumentableFilter,
suppressedDocumentableFilter,
documentableVisbilityFilter,
suppressedBySuppressTagDocumentableFilter
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ private class ContextModuleAndPackageDocumentationReader(
): SourceSetDependent<DocumentationNode> {
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),
Expand Down
Original file line number Diff line number Diff line change
@@ -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 }
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import org.jetbrains.dokka.transformers.documentation.source
import org.jetbrains.dokka.transformers.documentation.sourceSet
import java.io.File

class SuppressedDocumentableFilterTransformer(val context: DokkaContext) : PreMergeDocumentableTransformer {
class SuppressedByConfigurationDocumentableFilterTransformer(val context: DokkaContext) : PreMergeDocumentableTransformer {
override fun invoke(modules: List<DModule>): List<DModule> {
return modules.mapNotNull(::filterModule)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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<DModule>): List<DModule> =
modules.map { module ->
val (documentable, wasChanged) = processModule(module)
documentable.takeIf { wasChanged } ?: module
}

abstract fun shouldBeSuppressed(d: Documentable): Boolean

private fun processModule(module: DModule): DocumentableWithChanges<DModule> {
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<DPackage> {
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<DClasslike> {
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 <T : Documentable> processMember(member: T): DocumentableWithChanges<T> =
if (shouldBeSuppressed(member)) DocumentableWithChanges.filteredDocumentable()
else DocumentableWithChanges(member, false)

private data class DocumentableWithChanges<T : Documentable>(val documentable: T?, val changed: Boolean = false) {
companion object {
fun <T : Documentable> filteredDocumentable(): DocumentableWithChanges<T> =
DocumentableWithChanges(null, true)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull

internal data class CommentResolutionContext(
val comment: PsiDocComment,
val tag: JavadocTag,
val tag: JavadocTag?,
val name: String? = null,
val parameterIndex: Int? = null,
)
Expand All @@ -25,7 +25,7 @@ internal class InheritDocResolver(
JavadocTag.PARAM -> context.parameterIndex?.let { paramIndex -> resolveParamTag(context.comment, paramIndex) }
JavadocTag.DEPRECATED -> resolveGenericTag(context.comment, JavadocTag.DESCRIPTION)
JavadocTag.SEE -> emptyList()
else -> resolveGenericTag(context.comment, context.tag)
else -> context.tag?.let { tag -> resolveGenericTag(context.comment, tag) }
}

private fun resolveGenericTag(currentElement: PsiDocComment, tag: JavadocTag): List<PsiElement> =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import org.jetbrains.dokka.analysis.from
import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.model.doc.*
import org.jetbrains.dokka.model.doc.Deprecated
import org.jetbrains.dokka.model.doc.Suppress
import org.jetbrains.dokka.utilities.DokkaLogger
import org.jetbrains.dokka.utilities.enumValueOrNull
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
Expand Down Expand Up @@ -118,7 +119,15 @@ class JavadocParser(
else -> null
//TODO https://github.com/Kotlin/dokka/issues/1618
}
}
} ?: CustomTagWrapper(
wrapTagIfNecessary(
convertJavadocElements(
tag.contentElementsWithSiblingIfNeeded(),
context = CommentResolutionContext(docComment, null)
)
),
tag.name
)

private fun wrapTagIfNecessary(list: List<DocTag>): CustomDocTag =
if (list.size == 1 && (list.first() as? CustomDocTag)?.name == MarkdownElementTypes.MARKDOWN_FILE.name)
Expand Down Expand Up @@ -148,14 +157,14 @@ class JavadocParser(
}

private data class ParserState(
val currentJavadocTag: JavadocTag,
val currentJavadocTag: JavadocTag?,
val previousElement: PsiElement? = null,
val openPreTags: Int = 0,
val closedPreTags: Int = 0
)

private data class ParsingResult(val newState: ParserState, val parsedLine: String? = null) {
constructor(tag: JavadocTag) : this(ParserState(tag))
constructor(tag: JavadocTag?) : this(ParserState(tag))

operator fun plus(other: ParsingResult): ParsingResult =
ParsingResult(
Expand Down Expand Up @@ -267,7 +276,7 @@ class JavadocParser(

private fun convertInlineDocTag(
tag: PsiInlineDocTag,
javadocTag: JavadocTag,
javadocTag: JavadocTag?,
context: CommentResolutionContext
) =
when (tag.name) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.jetbrains.dokka.base.translators.psi.parsers

internal enum class JavadocTag {
PARAM, THROWS, RETURN, AUTHOR, SEE, DEPRECATED, EXCEPTION,
PARAM, THROWS, RETURN, AUTHOR, SEE, DEPRECATED, EXCEPTION, HIDE,

/**
* Artificial tag created to handle tag-less section
Expand Down
Loading