aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/base/src/test/kotlin/enums/KotlinEnumsTest.kt44
-rw-r--r--plugins/base/src/test/kotlin/transformers/InheritedEntriesDocumentableFilterTransfromerTest.kt5
-rw-r--r--plugins/base/src/test/kotlin/transformers/MergeImplicitExpectActualDeclarationsTest.kt15
-rw-r--r--plugins/base/src/test/kotlin/utils/contentUtils.kt25
-rw-r--r--subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/DefaultSymbolToDocumentableTranslator.kt52
5 files changed, 103 insertions, 38 deletions
diff --git a/plugins/base/src/test/kotlin/enums/KotlinEnumsTest.kt b/plugins/base/src/test/kotlin/enums/KotlinEnumsTest.kt
index 94a6b932..c32a5cc2 100644
--- a/plugins/base/src/test/kotlin/enums/KotlinEnumsTest.kt
+++ b/plugins/base/src/test/kotlin/enums/KotlinEnumsTest.kt
@@ -15,8 +15,7 @@ import org.jetbrains.dokka.pages.ContentGroup
import org.jsoup.Jsoup
import org.jsoup.nodes.Element
import signatures.renderedContent
-import utils.TestOutputWriter
-import utils.TestOutputWriterPlugin
+import utils.*
import java.net.URL
import kotlin.test.Test
import kotlin.test.assertEquals
@@ -329,6 +328,47 @@ class KotlinEnumsTest : BaseAbstractTest() {
}
@Test
+ @OnlyDescriptors("K2 has `compareTo`, that should be suppressed, due to #3196")
+ fun `enum should have functions on page`() {
+ val configuration = dokkaConfiguration {
+ sourceSets {
+ sourceSet {
+ sourceRoots = listOf("src/")
+ }
+ }
+ }
+
+ testInline(
+ """
+ |/src/main/kotlin/basic/TestEnum.kt
+ |package testpackage
+ |
+ |
+ |interface Sample {
+ | fun toBeImplemented(): String
+ |}
+ |
+ |enum class TestEnum: Sample {
+ | E1 {
+ | override fun toBeImplemented(): String = "e1"
+ | }
+ |}
+ """.trimMargin(),
+ configuration
+ ) {
+ pagesTransformationStage = { root ->
+ root.contentPage<ClasslikePageNode>("E1") {
+ assertHasFunctions("toBeImplemented")
+ }
+
+ root.contentPage<ClasslikePageNode>("TestEnum") {
+ assertHasFunctions("toBeImplemented", "valueOf", "values")
+ }
+ }
+ }
+ }
+
+ @Test
fun enumWithAnnotationsOnEntries() {
val configuration = dokkaConfiguration {
sourceSets {
diff --git a/plugins/base/src/test/kotlin/transformers/InheritedEntriesDocumentableFilterTransfromerTest.kt b/plugins/base/src/test/kotlin/transformers/InheritedEntriesDocumentableFilterTransfromerTest.kt
index 831d2680..c07dd5b8 100644
--- a/plugins/base/src/test/kotlin/transformers/InheritedEntriesDocumentableFilterTransfromerTest.kt
+++ b/plugins/base/src/test/kotlin/transformers/InheritedEntriesDocumentableFilterTransfromerTest.kt
@@ -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 {
@@ -138,7 +137,6 @@ class InheritedEntriesDocumentableFilterTransformerTest : BaseAbstractTest() {
}
}
- @OnlyDescriptors("Entry does not have `name` and `ordinal`") // TODO
@Test
fun `should work with enum entries when not suppressing`(){
testInline(
@@ -146,7 +144,8 @@ class InheritedEntriesDocumentableFilterTransformerTest : BaseAbstractTest() {
/src/suppressed/Suppressed.kt
package suppressed
enum class Suppressed {
- ENTRY_SUPPRESSED
+ ENTRY_SUPPRESSED;
+ class A
}
""".trimIndent(),
nonSuppressingInheritedConfiguration
diff --git a/plugins/base/src/test/kotlin/transformers/MergeImplicitExpectActualDeclarationsTest.kt b/plugins/base/src/test/kotlin/transformers/MergeImplicitExpectActualDeclarationsTest.kt
index f7118f33..18e42e47 100644
--- a/plugins/base/src/test/kotlin/transformers/MergeImplicitExpectActualDeclarationsTest.kt
+++ b/plugins/base/src/test/kotlin/transformers/MergeImplicitExpectActualDeclarationsTest.kt
@@ -13,10 +13,10 @@ import org.jetbrains.dokka.model.dfs
import org.jetbrains.dokka.model.firstChildOfType
import org.jetbrains.dokka.pages.*
import utils.assertNotNull
+import utils.findSectionWithName
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
-import utils.OnlyDescriptors
class MergeImplicitExpectActualDeclarationsTest : BaseAbstractTest() {
@@ -52,15 +52,6 @@ class MergeImplicitExpectActualDeclarationsTest : BaseAbstractTest() {
)
}
- private fun ClasslikePageNode.findSectionWithName(name: String) : ContentNode? {
- var sectionHeader: ContentHeader? = null
- return content.dfs { node ->
- node.children.filterIsInstance<ContentHeader>().any { header ->
- header.children.firstOrNull { it is ContentText && it.text == name }?.also { sectionHeader = header } != null
- }
- }?.children?.dropWhile { child -> child != sectionHeader }?.drop(1)?.firstOrNull()
- }
-
private fun ContentNode.findTabWithType(type: TabbedContentType): ContentNode? = dfs { node ->
node.children.filterIsInstance<ContentGroup>().any { gr ->
gr.extra[TabbedContentTypeExtra]?.value == type
@@ -274,7 +265,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(
@@ -304,7 +294,8 @@ class MergeImplicitExpectActualDeclarationsTest : BaseAbstractTest() {
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,
diff --git a/plugins/base/src/test/kotlin/utils/contentUtils.kt b/plugins/base/src/test/kotlin/utils/contentUtils.kt
index b83d8697..3ca0bd2d 100644
--- a/plugins/base/src/test/kotlin/utils/contentUtils.kt
+++ b/plugins/base/src/test/kotlin/utils/contentUtils.kt
@@ -5,10 +5,9 @@
package utils
import matchers.content.*
-import org.jetbrains.dokka.pages.BasicTabbedContentType
-import org.jetbrains.dokka.pages.ContentGroup
-import org.jetbrains.dokka.pages.ContentPage
-import org.jetbrains.dokka.pages.RootPageNode
+import org.jetbrains.dokka.model.dfs
+import org.jetbrains.dokka.pages.*
+import kotlin.test.assertEquals
//TODO: Try to unify those functions after update to 1.4
fun ContentMatcherBuilder<*>.functionSignature(
@@ -327,6 +326,24 @@ fun ContentMatcherBuilder<*>.unwrapAnnotation(elem: Map.Entry<String, Set<String
}
}
}
+inline fun<reified T> PageNode.contentPage(name: String, block: T.() -> Unit) {
+ (dfs { it.name == name } as? T).assertNotNull("The page `$name` is not found").block()
+}
+
+fun ClasslikePageNode.assertHasFunctions(vararg expectedFunctionName: String) {
+ val functions = this.findSectionWithName("Functions").assertNotNull("Functions")
+ val functionsName = functions.children.map { (it.dfs { it is ContentText } as ContentText).text }
+ assertEquals(expectedFunctionName.toList(), functionsName)
+}
+
+fun ClasslikePageNode.findSectionWithName(name: String) : ContentNode? {
+ var sectionHeader: ContentHeader? = null
+ return content.dfs { node ->
+ node.children.filterIsInstance<ContentHeader>().any { header ->
+ header.children.firstOrNull { it is ContentText && it.text == name }?.also { sectionHeader = header } != null
+ }
+ }?.children?.dropWhile { child -> child != sectionHeader }?.drop(1)?.firstOrNull()
+}
data class ParamAttributes(
val annotations: Map<String, Set<String>>,
diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/DefaultSymbolToDocumentableTranslator.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/DefaultSymbolToDocumentableTranslator.kt
index 4e741d09..f217c88f 100644
--- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/DefaultSymbolToDocumentableTranslator.kt
+++ b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/DefaultSymbolToDocumentableTranslator.kt
@@ -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,
@@ -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()
@@ -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(