Skip to content

Commit

Permalink
[K2] Display enum entry members
Browse files Browse the repository at this point in the history
  • Loading branch information
vmishenev committed Sep 18, 2023
1 parent 38e09dd commit d57a6d1
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import org.jetbrains.dokka.model.DEnum
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue
import utils.OnlyDescriptors

class InheritedEntriesDocumentableFilterTransformerTest : BaseAbstractTest() {
val suppressingInheritedConfiguration = dokkaConfiguration {
Expand Down Expand Up @@ -138,15 +137,15 @@ class InheritedEntriesDocumentableFilterTransformerTest : BaseAbstractTest() {
}
}

@OnlyDescriptors("Entry does not have `name` and `ordinal`") // TODO
@Test
fun `should work with enum entries when not suppressing`(){
testInline(
"""
/src/suppressed/Suppressed.kt
package suppressed
enum class Suppressed {
ENTRY_SUPPRESSED
ENTRY_SUPPRESSED;
class A
}
""".trimIndent(),
nonSuppressingInheritedConfiguration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import utils.assertNotNull
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import utils.OnlyDescriptors

class MergeImplicitExpectActualDeclarationsTest : BaseAbstractTest() {

Expand Down Expand Up @@ -274,7 +273,6 @@ class MergeImplicitExpectActualDeclarationsTest : BaseAbstractTest() {

fun PageNode.childrenRec(): List<PageNode> = listOf(this) + children.flatMap { it.childrenRec() }

@OnlyDescriptors("Enum entry [SMTH] does not have functions") // TODO
@Test
fun `should merge enum entries`() {
testInline(
Expand All @@ -299,12 +297,16 @@ class MergeImplicitExpectActualDeclarationsTest : BaseAbstractTest() {
configuration(true),
cleanupOutput = true
) {
documentablesCreationStage = {
print(it)
}
pagesTransformationStage = { root ->
val classPage = root.dfs { it.name == "SMTH" } as? ClasslikePageNode
assertNotNull(classPage, "Tested class not found!")

val functions = classPage.findSectionWithName("Functions").assertNotNull("Functions")
val method1 = functions.children.singleOrNull().assertNotNull("method1")
val method1 = functions.children.single { it.sourceSets.size == 2 && it.dci.dri.singleOrNull()?.callable?.name == "method1" }
.assertNotNull("method1")

assertEquals(
2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,30 @@ internal class DokkaSymbolVisitor(

KtClassKind.ANONYMOUS_OBJECT -> throw NotImplementedError("ANONYMOUS_OBJECT does not support")
KtClassKind.ENUM_CLASS -> {
val entries = namedClassOrObjectSymbol.getEnumEntries().map { visitEnumEntrySymbol(it) }
/**
* See https://github.com/Kotlin/dokka/issues/3129
*
* e.g. the `A` enum entry in the `enum E` is
* ```
* static val A: E = object : E() {
* val x: Int = 5
* }
* ```
* it needs to exclude all static members like `values` and `valueOf` from the enum class's scope
*/
val enumEntryScope = lazy {
getDokkaScopeFrom(namedClassOrObjectSymbol, dri, includeStaticScope = false).let {
it.copy(
functions = it.functions.map { it.withNewExtras( it.extra + InheritedMember(dri.copy(callable = null).toSourceSetDependent())) },
properties = it.properties.map { it.withNewExtras( it.extra + InheritedMember(dri.copy(callable = null).toSourceSetDependent())) }
)
}
}

val entries =
namedClassOrObjectSymbol.getEnumEntries().map {
visitEnumEntrySymbol(it, enumEntryScope.value)
}

DEnum(
dri = dri,
Expand Down Expand Up @@ -383,12 +406,17 @@ internal class DokkaSymbolVisitor(
val properties: List<DProperty>,
val classlikes: List<DClasslike>
)

/**
* @param includeStaticScope flag to add static members, e.g. `valueOf`, `values` and `entries` members for Enum
*/
private fun KtAnalysisSession.getDokkaScopeFrom(
namedClassOrObjectSymbol: KtNamedClassOrObjectSymbol,
dri: DRI
dri: DRI,
includeStaticScope: Boolean = true
): DokkaScope {
// e.g. getStaticMemberScope contains `valueOf`, `values` and `entries` members for Enum
val scope = listOf(namedClassOrObjectSymbol.getMemberScope(), namedClassOrObjectSymbol.getStaticMemberScope()).asCompositeScope()
val scope = if(includeStaticScope) listOf(namedClassOrObjectSymbol.getMemberScope(), namedClassOrObjectSymbol.getStaticMemberScope()).asCompositeScope() else namedClassOrObjectSymbol.getMemberScope()
val constructors = scope.getConstructors().map { visitConstructorSymbol(it) }.toList()

val callables = scope.getCallableSymbols().toList()
Expand Down Expand Up @@ -453,28 +481,18 @@ internal class DokkaSymbolVisitor(
}

private fun KtAnalysisSession.visitEnumEntrySymbol(
enumEntrySymbol: KtEnumEntrySymbol
enumEntrySymbol: KtEnumEntrySymbol, scope: DokkaScope
): DEnumEntry = withExceptionCatcher(enumEntrySymbol) {
val dri = getDRIFromEnumEntry(enumEntrySymbol)
val isExpect = false

val scope = enumEntrySymbol.getMemberScope()
val callables = scope.getCallableSymbols().toList()
val classifiers = scope.getClassifierSymbols().toList()

val functions = callables.filterIsInstance<KtFunctionSymbol>().map { visitFunctionSymbol(it, dri) }
val properties = callables.filterIsInstance<KtPropertySymbol>().map { visitPropertySymbol(it, dri) }
val classlikes =
classifiers.filterIsInstance<KtNamedClassOrObjectSymbol>()
.map { visitNamedClassOrObjectSymbol(it, dri) }

return DEnumEntry(
dri = dri,
name = enumEntrySymbol.name.asString(),
documentation = getDocumentation(enumEntrySymbol)?.toSourceSetDependent() ?: emptyMap(),
functions = functions,
properties = properties,
classlikes = classlikes,
functions = scope.functions,
properties = scope.properties,
classlikes = emptyList(), // always empty, see https://github.com/Kotlin/dokka/issues/3129
sourceSets = setOf(sourceSet),
expectPresentInSet = sourceSet.takeIf { isExpect },
extra = PropertyContainer.withAll(
Expand Down

0 comments on commit d57a6d1

Please sign in to comment.