aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Aman <maman@virtuslab.com>2020-05-25 14:40:59 +0200
committerPaweł Marks <Kordyjan@users.noreply.github.com>2020-06-03 11:45:54 +0200
commitf0742fb7f8a937ef7c2e5a92d6f4a0fd079baa62 (patch)
treef7c7b8c7844b862b784a1651db5a4cb235207e41
parent02ddcd61dea19efd60c0da972ac0b5bd1d6ebf89 (diff)
downloaddokka-f0742fb7f8a937ef7c2e5a92d6f4a0fd079baa62.tar.gz
dokka-f0742fb7f8a937ef7c2e5a92d6f4a0fd079baa62.tar.bz2
dokka-f0742fb7f8a937ef7c2e5a92d6f4a0fd079baa62.zip
Enum constructor values
-rw-r--r--core/src/main/kotlin/model/aditionalExtras.kt11
-rw-r--r--plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt14
-rw-r--r--plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt26
-rw-r--r--plugins/base/src/main/resources/dokka/styles/style.css1
-rw-r--r--plugins/base/src/test/kotlin/enums/EnumsTest.kt146
-rw-r--r--plugins/base/src/test/kotlin/utils/contentUtils.kt2
6 files changed, 189 insertions, 11 deletions
diff --git a/core/src/main/kotlin/model/aditionalExtras.kt b/core/src/main/kotlin/model/aditionalExtras.kt
index f71852c4..055fc5a6 100644
--- a/core/src/main/kotlin/model/aditionalExtras.kt
+++ b/core/src/main/kotlin/model/aditionalExtras.kt
@@ -59,4 +59,15 @@ data class ActualTypealias(val underlyingType: SourceSetDependent<Bound>) : Extr
}
override val key: ExtraProperty.Key<DClasslike, ActualTypealias> = ActualTypealias
+}
+
+data class ConstructorValues(val values: List<String>) : ExtraProperty<DEnumEntry>{
+ companion object : ExtraProperty.Key<DEnumEntry, ConstructorValues> {
+ override fun mergeStrategyFor(left: ConstructorValues, right: ConstructorValues) =
+ MergeStrategy.Fail{
+ throw IllegalArgumentException("Merging constructor parameters not applicable")
+ }
+ }
+
+ override val key: ExtraProperty.Key<DEnumEntry, ConstructorValues> = ConstructorValues
} \ No newline at end of file
diff --git a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt
index 33c82458..367a7a95 100644
--- a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt
+++ b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt
@@ -33,8 +33,16 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog
}
private fun signature(e: DEnumEntry) =
- contentBuilder.contentFor(e, ContentKind.Symbol, setOf(TextStyle.Monospace)) {
- link(e.name, e.dri)
+ contentBuilder.contentFor(e, ContentKind.Symbol, setOf(TextStyle.Monospace), sourceSets = e.sourceSets.toSet()) {
+ group(styles = setOf(TextStyle.Block)){
+ annotationsBlock(e)
+ link(e.name, e.dri, styles = emptySet())
+ e.extra[ConstructorValues]?.let {
+ list(it.values, prefix = "(", suffix = ")"){
+ text(it)
+ }
+ }
+ }
}
private fun actualTypealiasedSignature(dri: DRI, name: String, aliasedTypes: SourceSetDependent<Bound>) =
@@ -87,7 +95,7 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog
+buildSignature(it)
}
}
- if (c is DClass) {
+ if (c is WithConstructors) {
val pConstructor = c.constructors.singleOrNull { it.extra[PrimaryConstructorExtra] != null }
if (pConstructor?.annotations()?.isNotEmpty() == true) {
text(nbsp.toString())
diff --git a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt
index 60182ba9..a56eb454 100644
--- a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt
+++ b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt
@@ -24,8 +24,9 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies
import org.jetbrains.kotlin.idea.kdoc.findKDoc
import org.jetbrains.kotlin.load.kotlin.toSourceElement
-import org.jetbrains.kotlin.psi.KtExpression
+import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.DescriptorUtils
+import org.jetbrains.kotlin.resolve.calls.callUtil.getValueArgumentsInParentheses
import org.jetbrains.kotlin.resolve.calls.components.isVararg
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.constants.AnnotationValue as ConstantsAnnotationValue
@@ -41,9 +42,12 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperInterfaces
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
+import org.jetbrains.kotlin.resolve.source.PsiSourceElement
import org.jetbrains.kotlin.types.DynamicType
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeProjection
+import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
+import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import java.nio.file.Paths
import kotlin.IllegalArgumentException
@@ -212,7 +216,11 @@ private class DokkaDescriptorVisitor(
properties = scope.properties(driWithPlatform),
sourceSets = listOf(sourceSet),
expectPresentInSet = sourceSet.takeIf { isExpect },
- extra = PropertyContainer.withAll(descriptor.additionalExtras(), descriptor.getAnnotations())
+ extra = PropertyContainer.withAll(
+ descriptor.additionalExtras(),
+ descriptor.getAnnotations(),
+ ConstructorValues(descriptor.getAppliedConstructorParameters())
+ )
)
}
@@ -499,7 +507,6 @@ private class DokkaDescriptorVisitor(
getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS, packageLevel)
.filter { it is ClassDescriptor && it.kind != ClassKind.ENUM_ENTRY }
.map { visitClassDescriptor(it as ClassDescriptor, parent) }
- .mapNotNull { it as? DClasslike }
private fun MemberScope.packages(parent: DRIWithPlatformInfo): List<DPackage> =
getContributedDescriptors(DescriptorKindFilter.PACKAGES) { true }
@@ -681,6 +688,19 @@ private class DokkaDescriptorVisitor(
private fun ValueParameterDescriptor.getDefaultValue(): String? =
(source as? KotlinSourceElement)?.psi?.children?.find { it is KtExpression }?.text
+ private fun ClassDescriptor.getAppliedConstructorParameters() =
+ (source as PsiSourceElement).psi?.children?.flatMap {
+ it.safeAs<KtInitializerList>()?.initializersAsText().orEmpty()
+ }.orEmpty()
+
+ private fun KtInitializerList.initializersAsText() =
+ initializers.firstIsInstanceOrNull<KtCallElement>()
+ ?.getValueArgumentsInParentheses()
+ ?.flatMap { it.childrenAsText() }
+ .orEmpty()
+
+ private fun ValueArgument.childrenAsText() = this.safeAs<KtValueArgument>()?.children?.map {it.text }.orEmpty()
+
private data class ClassInfo(val supertypes: List<DRI>, val docs: SourceSetDependent<DocumentationNode>)
private fun Visibility.toDokkaVisibility(): org.jetbrains.dokka.model.Visibility = when (this) {
diff --git a/plugins/base/src/main/resources/dokka/styles/style.css b/plugins/base/src/main/resources/dokka/styles/style.css
index d9927046..d573b76c 100644
--- a/plugins/base/src/main/resources/dokka/styles/style.css
+++ b/plugins/base/src/main/resources/dokka/styles/style.css
@@ -172,7 +172,6 @@
padding: 8px 16px;
box-sizing: border-box;
font-weight: bold;
- white-space: pre;
flex-wrap: wrap;
}
diff --git a/plugins/base/src/test/kotlin/enums/EnumsTest.kt b/plugins/base/src/test/kotlin/enums/EnumsTest.kt
index 5f8bf8c8..6c44dc35 100644
--- a/plugins/base/src/test/kotlin/enums/EnumsTest.kt
+++ b/plugins/base/src/test/kotlin/enums/EnumsTest.kt
@@ -1,11 +1,16 @@
package enums
+import matchers.content.assertNode
+import matchers.content.group
+import matchers.content.header
+import matchers.content.link
+import org.jetbrains.dokka.model.ConstructorValues
import org.jetbrains.dokka.model.DEnum
-import org.jetbrains.dokka.pages.ClasslikePageNode
-import org.jetbrains.dokka.pages.ModulePageNode
-import org.junit.jupiter.api.Test
+import org.jetbrains.dokka.pages.*
import org.jetbrains.dokka.testApi.testRunner.AbstractCoreTest
import org.junit.jupiter.api.Assertions.*
+import org.junit.jupiter.api.Test
+import utils.unwrapAnnotation
class EnumsTest : AbstractCoreTest() {
@@ -85,7 +90,142 @@ class EnumsTest : AbstractCoreTest() {
}
}
+ @Test
+ fun enumWithConstructor() {
+ val configuration = dokkaConfiguration {
+ passes {
+ pass {
+ sourceRoots = listOf("src/")
+ }
+ }
+ }
+
+ testInline(
+ """
+ |/src/main/kotlin/basic/Test.kt
+ |package enums
+ |
+ |
+ |enum class Test(name: String, index: Int, excluded: Boolean) {
+ | E1("e1", 1, true),
+ | E2("e2", 2, false);
+ |}
+ """.trimMargin(),
+ configuration
+ ) {
+ documentablesTransformationStage = { m ->
+ m.packages.let { p ->
+ p.first().classlikes.let { c ->
+ val enum = c.first() as DEnum
+ val (first, second) = enum.entries
+
+ assertEquals(1, first.extra.allOfType<ConstructorValues>().size)
+ assertEquals(1, second.extra.allOfType<ConstructorValues>().size)
+ assertEquals(listOf("\"e1\"", "1", "true"), first.extra.allOfType<ConstructorValues>().first().values)
+ assertEquals(listOf("\"e2\"", "2", "false"), second.extra.allOfType<ConstructorValues>().first().values)
+ }
+ }
+ }
+ pagesGenerationStage = { module ->
+ val entryPage = module.dfs { it.name == "E1" } as ClasslikePageNode
+ val signaturePart = (entryPage.content.dfs {
+ it is ContentGroup && it.dci.toString() == "[enums/Test.E1///PointingToDeclaration/][Symbol]"
+ } as ContentGroup).children.first() as ContentGroup
+ assertEquals("(\"e1\", 1, true)", signaturePart.constructorSignature())
+ }
+ }
+ }
+
+ @Test
+ fun enumWithMethods() {
+ val configuration = dokkaConfiguration {
+ passes {
+ pass {
+ sourceRoots = listOf("src/")
+ }
+ }
+ }
+
+ testInline(
+ """
+ |/src/main/kotlin/basic/Test.kt
+ |package enums
+ |
+ |
+ |interface Sample {
+ | fun toBeImplemented(): String
+ |}
+ |
+ |enum class Test: Sample {
+ | E1 {
+ | override fun toBeImplemented(): String = "e1"
+ | }
+ |}
+ """.trimMargin(),
+ configuration
+ ) {
+ documentablesTransformationStage = { m ->
+ m.packages.let { p ->
+ p.first().classlikes.let { c ->
+ val enum = c.first { it is DEnum } as DEnum
+ val first = enum.entries.first()
+
+ assertEquals(1, first.extra.allOfType<ConstructorValues>().size)
+ assertEquals(emptyList<String>(), first.extra.allOfType<ConstructorValues>().first().values)
+ assertNotNull(first.functions.find { it.name == "toBeImplemented" })
+ }
+ }
+ }
+ }
+ }
+
+ @Test
+ fun enumWithAnnotationsOnEntries(){
+ val configuration = dokkaConfiguration {
+ passes {
+ pass {
+ sourceRoots = listOf("src/")
+ }
+ }
+ }
+
+ testInline(
+ """
+ |/src/main/kotlin/basic/Test.kt
+ |package enums
+ |
+ |enum class Test {
+ | @SinceKotlin("1.3")
+ | E1
+ |}
+ """.trimMargin(),
+ configuration
+ ) {
+ pagesTransformationStage = { m ->
+ val entryNode = m.children.first { it.name == "enums" }.children.first { it.name == "Test" }.children.first() as ClasslikePageNode
+ val signature = (entryNode.content as ContentGroup).dfs { it is ContentGroup && it.dci.toString() == "[enums/Test.E1///PointingToDeclaration/][Cover]" } as ContentGroup
+
+ signature.assertNode {
+ header(1) { +"E1" }
+ group {
+ mapOf("SinceKotlin" to setOf("version")).entries.forEach {
+ group {
+ group {
+ unwrapAnnotation(it)
+ }
+ link { +"E1" }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
fun ModulePageNode.getClasslikeToMemberMap() =
this.parentMap.filterValues { it is ClasslikePageNode }.entries.groupBy({ it.value }) { it.key }
+
+ private fun ContentGroup.constructorSignature(): String =
+ children.drop(1).joinToString(separator = "") { (it as ContentText).text }
} \ No newline at end of file
diff --git a/plugins/base/src/test/kotlin/utils/contentUtils.kt b/plugins/base/src/test/kotlin/utils/contentUtils.kt
index 4aba3e9d..7e1b8bf4 100644
--- a/plugins/base/src/test/kotlin/utils/contentUtils.kt
+++ b/plugins/base/src/test/kotlin/utils/contentUtils.kt
@@ -184,7 +184,7 @@ fun ContentMatcherBuilder<*>.unnamedTag(tag: String, content: ContentMatcherBuil
group { content() }
}
-private fun ContentMatcherBuilder<*>.unwrapAnnotation(elem: Map.Entry<String, Set<String>>) {
+fun ContentMatcherBuilder<*>.unwrapAnnotation(elem: Map.Entry<String, Set<String>>) {
+"@"
link { +elem.key }
+"("