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

Allow filtering of property setter #2220

Merged
merged 2 commits into from Dec 23, 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -81,8 +81,12 @@ class DocumentableVisibilityFilterTransformer(val context: DokkaContext) : PreMe
return Pair(packagesListChanged, filteredPackages)
}

@Suppress("UNUSED_PARAMETER")
private fun <T : WithVisibility> alwaysTrue(a: T, p: DokkaSourceSet) = true
@Suppress("UNUSED_PARAMETER")
private fun <T : WithVisibility> alwaysFalse(a: T, p: DokkaSourceSet) = false
@Suppress("UNUSED_PARAMETER")
private fun <T> alwaysNoModify(a: T, sourceSets: Set<DokkaSourceSet>) = false to a

private fun WithVisibility.visibilityForPlatform(data: DokkaSourceSet): Visibility? = visibility[data]

Expand All @@ -99,13 +103,18 @@ class DocumentableVisibilityFilterTransformer(val context: DokkaContext) : PreMe
private fun <T> List<T>.transform(
additionalCondition: (T, DokkaSourceSet) -> Boolean = ::alwaysTrue,
alternativeCondition: (T, DokkaSourceSet) -> Boolean = ::alwaysFalse,
recreate: (T, Set<DokkaSourceSet>) -> T
modify: (T, Set<DokkaSourceSet>) -> Pair<Boolean, T> = ::alwaysNoModify,
recreate: (T, Set<DokkaSourceSet>) -> T,
): Pair<Boolean, List<T>> where T : Documentable, T : WithVisibility {
var changed = false
val values = mapNotNull { t ->
val filteredPlatforms = t.filterPlatforms(additionalCondition, alternativeCondition)
when (filteredPlatforms.size) {
t.visibility.size -> t
t.visibility.size -> {
val (wasChanged, element) = modify(t, filteredPlatforms)
changed = changed || wasChanged
element
}
0 -> {
changed = true
null
Expand Down Expand Up @@ -142,9 +151,35 @@ class DocumentableVisibilityFilterTransformer(val context: DokkaContext) : PreMe

private fun filterProperties(
properties: List<DProperty>,
additionalCondition: (DProperty, DokkaSourceSet) -> Boolean = ::alwaysTrue
): Pair<Boolean, List<DProperty>> =
properties.transform(additionalCondition, ::hasVisibleAccessorsForPlatform) { original, filteredPlatforms ->
additionalCondition: (DProperty, DokkaSourceSet) -> Boolean = ::alwaysTrue,
additionalConditionAccessors: (DFunction, DokkaSourceSet) -> Boolean = ::alwaysTrue
): Pair<Boolean, List<DProperty>> {

val modifier: (DProperty, Set<DokkaSourceSet>) -> Pair<Boolean, DProperty> =
{ original, filteredPlatforms ->
val setter = original.setter?.let { filterFunctions(listOf(it), additionalConditionAccessors) }
val getter = original.getter?.let { filterFunctions(listOf(it), additionalConditionAccessors) }

val modified = setter?.first == true || getter?.first == true

val property =
if (modified)
original.copy(
setter = setter?.second?.firstOrNull(),
getter = getter?.second?.firstOrNull()
)
else original
modified to property
}

return properties.transform(
additionalCondition,
::hasVisibleAccessorsForPlatform,
modifier
) { original, filteredPlatforms ->
val setter = original.setter?.let { filterFunctions(listOf(it), additionalConditionAccessors) }
val getter = original.getter?.let { filterFunctions(listOf(it), additionalConditionAccessors) }

with(original) {
copy(
documentation = documentation.filtered(filteredPlatforms),
Expand All @@ -153,9 +188,12 @@ class DocumentableVisibilityFilterTransformer(val context: DokkaContext) : PreMe
visibility = visibility.filtered(filteredPlatforms),
sourceSets = filteredPlatforms,
generics = generics.mapNotNull { it.filter(filteredPlatforms) },
setter = setter?.second?.firstOrNull(),
getter = getter?.second?.firstOrNull()
)
}
}
}

private fun filterEnumEntries(entries: List<DEnumEntry>, filteredPlatforms: Set<DokkaSourceSet>): Pair<Boolean, List<DEnumEntry>> =
entries.foldRight(Pair(false, emptyList())) { entry, acc ->
Expand Down
Expand Up @@ -27,7 +27,7 @@ abstract class SuppressedByConditionDocumentableFilterTransformer(val context: D
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 properies = dPackage.properties.map { processProperty(it) }

val wasChanged = (classlikes + typeAliases + functions + properies).any { it.changed }
return (dPackage.takeIf { !wasChanged } ?: dPackage.copy(
Expand All @@ -43,7 +43,7 @@ abstract class SuppressedByConditionDocumentableFilterTransformer(val context: D

val functions = classlike.functions.map { processMember(it) }
val classlikes = classlike.classlikes.map { processClassLike(it) }
val properties = classlike.properties.map { processMember(it) }
val properties = classlike.properties.map { processProperty(it) }
val companion = (classlike as? WithCompanion)?.companion?.let { processClassLike(it) }

val wasClasslikeChanged = (functions + classlikes + properties).any { it.changed } || companion?.changed == true
Expand Down Expand Up @@ -104,7 +104,7 @@ abstract class SuppressedByConditionDocumentableFilterTransformer(val context: D
if (shouldBeSuppressed(dEnumEntry)) return DocumentableWithChanges.filteredDocumentable()

val functions = dEnumEntry.functions.map { processMember(it) }
val properties = dEnumEntry.properties.map { processMember(it) }
val properties = dEnumEntry.properties.map { processProperty(it) }
val classlikes = dEnumEntry.classlikes.map { processClassLike(it) }

val wasChanged = (functions + properties + classlikes).any { it.changed }
Expand All @@ -115,6 +115,19 @@ abstract class SuppressedByConditionDocumentableFilterTransformer(val context: D
)).let { DocumentableWithChanges(it, wasChanged) }
}

private fun processProperty(dProperty: DProperty): DocumentableWithChanges<DProperty> {
if (shouldBeSuppressed(dProperty)) return DocumentableWithChanges.filteredDocumentable()

val getter = dProperty.getter?.let { processMember(it) } ?: DocumentableWithChanges(null, false)
val setter = dProperty.setter?.let { processMember(it) } ?: DocumentableWithChanges(null, false)

val wasChanged = getter.changed || setter.changed
return (dProperty.takeIf { !wasChanged } ?: dProperty.copy(
getter = getter.documentable,
setter = setter.documentable
)).let { DocumentableWithChanges(it, wasChanged) }
}

private fun <T : Documentable> processMember(member: T): DocumentableWithChanges<T> =
if (shouldBeSuppressed(member)) DocumentableWithChanges.filteredDocumentable()
else DocumentableWithChanges(member, false)
Expand Down
31 changes: 31 additions & 0 deletions plugins/base/src/test/kotlin/filter/VisibilityFilterTest.kt
Expand Up @@ -104,6 +104,37 @@ class VisibilityFilterTest : BaseAbstractTest() {
}
}

@Test
fun `private setter with false global includeNonPublic`() {
val configuration = dokkaConfiguration {
sourceSets {
sourceSet {
includeNonPublic = false
sourceRoots = listOf("src/main/kotlin/basic/Test.kt")
}
}
}

testInline(
"""
|/src/main/kotlin/basic/Test.kt
|package example
|
|var property: Int = 0
|private set
|
|
""".trimMargin(),
configuration
) {
preMergeDocumentablesTransformationStage = {
Assertions.assertNull(
it.first().packages.first().properties.first().setter
)
}
}
}

@Test
fun `private function with false global true package includeNonPublic`() {
val configuration = dokkaConfiguration {
Expand Down
20 changes: 20 additions & 0 deletions plugins/base/src/test/kotlin/transformers/SuppressTagFilterTest.kt
Expand Up @@ -88,6 +88,26 @@ class SuppressTagFilterTest : BaseAbstractTest() {
}
}

@Test
fun `should filter setter`() {
testInline(
"""
|/src/suppressed/Suppressed.kt
|var property: Int
|/** @suppress */
|private set
""".trimIndent(), configuration
) {
preMergeDocumentablesTransformationStage = { modules ->
val prop = modules.flatMap { it.packages }.flatMap { it.properties }
.find { it.name == "property" }
assertNotNull(prop)
assertNotNull(prop.getter)
assertNull(prop.setter)
}
}
}

@Test
fun `should filter top level type aliases`() {
testInline(
Expand Down