diff options
author | Ignat Beresnev <ignat.beresnev@jetbrains.com> | 2022-06-30 16:01:31 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-30 16:01:31 +0200 |
commit | 623b0e729c805e2ec019b1f56f67c5a2cf7eb327 (patch) | |
tree | a2be21288b69977900d4ad32250855f4ea08bad8 /plugins/base | |
parent | fb589740213286cc5c2f240f248a10752187a9d7 (diff) | |
download | dokka-623b0e729c805e2ec019b1f56f67c5a2cf7eb327.tar.gz dokka-623b0e729c805e2ec019b1f56f67c5a2cf7eb327.tar.bz2 dokka-623b0e729c805e2ec019b1f56f67c5a2cf7eb327.zip |
Add enum synthetic functions to documentable model (#2553)
Diffstat (limited to 'plugins/base')
-rw-r--r-- | plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt | 33 | ||||
-rw-r--r-- | plugins/base/src/test/kotlin/enums/KotlinEnumTest.kt (renamed from plugins/base/src/test/kotlin/enums/EnumsTest.kt) | 41 |
2 files changed, 64 insertions, 10 deletions
diff --git a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt index c4a8253a..43b8c544 100644 --- a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt +++ b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt @@ -59,6 +59,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull import org.jetbrains.kotlin.resolve.descriptorUtil.parents import org.jetbrains.kotlin.resolve.scopes.MemberScope +import org.jetbrains.kotlin.resolve.scopes.StaticScopeForKotlinEnum import org.jetbrains.kotlin.resolve.source.KotlinSourceElement import org.jetbrains.kotlin.resolve.source.PsiSourceElement import org.jetbrains.kotlin.resolve.source.PsiSourceFile @@ -261,13 +262,12 @@ private class DokkaDescriptorVisitor( private suspend fun enumDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): DEnum { val driWithPlatform = parent.dri.withClass(descriptor.name.asString()).withEmptyInfo() - val scope = descriptor.unsubstitutedMemberScope val isExpect = descriptor.isExpect val isActual = descriptor.isActual val info = descriptor.resolveClassDescriptionData() return coroutineScope { - val descriptorsWithKind = scope.getDescriptorsWithKind() + val descriptorsWithKind = descriptor.getEnumDescriptorsWithKind() val functions = async { descriptorsWithKind.functions.visitFunctions(driWithPlatform) } val properties = async { descriptorsWithKind.properties.visitProperties(driWithPlatform) } @@ -301,6 +301,16 @@ private class DokkaDescriptorVisitor( } } + private fun ClassDescriptor.getEnumDescriptorsWithKind(): DescriptorsWithKind { + val descriptorsWithKind = this.unsubstitutedMemberScope.getDescriptorsWithKind() + val staticScopeForKotlinEnum = (this.staticScope as? StaticScopeForKotlinEnum) ?: return descriptorsWithKind + + // synthetic values() and valueOf() functions are not present among average class functions + val enumSyntheticFunctions = staticScopeForKotlinEnum.getContributedDescriptors { true } + + return descriptorsWithKind.copy(functions = descriptorsWithKind.functions + enumSyntheticFunctions) + } + private suspend fun visitEnumEntryDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): DEnumEntry { val driWithPlatform = parent.dri.withClass(descriptor.name.asString()).withEmptyInfo() val scope = descriptor.unsubstitutedMemberScope @@ -578,7 +588,7 @@ private class DokkaDescriptorVisitor( descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), (descriptor.getAnnotations() + descriptor.fileLevelAnnotations()).toSourceSetDependent() .toAnnotations(), - ObviousMember.takeIf { descriptor.isObvious }, + ObviousMember.takeIf { descriptor.isObvious() }, ) ) } @@ -597,6 +607,17 @@ private class DokkaDescriptorVisitor( .takeIf { parent.dri.classNames != this.classNames || parent.dri.packageName != this.packageName } } + private fun FunctionDescriptor.isObvious(): Boolean { + return kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE + || kind == CallableMemberDescriptor.Kind.SYNTHESIZED + || containingDeclaration.fqNameOrNull()?.isObvious() == true + } + + private fun FqName.isObvious(): Boolean = with(this.asString()) { + return this == "kotlin.Any" || this == "kotlin.Enum" + || this == "java.lang.Object" || this == "java.lang.Enum" + } + suspend fun visitConstructorDescriptor(descriptor: ConstructorDescriptor, parent: DRIWithPlatformInfo): DFunction { val name = descriptor.constructedClass.name.toString() val dri = parent.dri.copy(callable = Callable.from(descriptor, name)) @@ -1204,12 +1225,6 @@ private class DokkaDescriptorVisitor( ?.parallelMap { it.toAnnotation(scope = Annotations.AnnotationScope.FILE) } .orEmpty() - private val FunctionDescriptor.isObvious: Boolean - get() = kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE || - kind == CallableMemberDescriptor.Kind.SYNTHESIZED || - containingDeclaration.fqNameOrNull()?.asString() - ?.let { it == "kotlin.Any" || it == "kotlin.Enum" || it == "java.lang.Enum" || it == "java.lang.Object" } == true - private fun AncestryNode.exceptionInSupertypesOrNull(): ExceptionInSupertypes? = typeConstructorsBeingExceptions().takeIf { it.isNotEmpty() }?.let { ExceptionInSupertypes(it.toSourceSetDependent()) } } diff --git a/plugins/base/src/test/kotlin/enums/EnumsTest.kt b/plugins/base/src/test/kotlin/enums/KotlinEnumTest.kt index 8cb9f654..83430869 100644 --- a/plugins/base/src/test/kotlin/enums/EnumsTest.kt +++ b/plugins/base/src/test/kotlin/enums/KotlinEnumTest.kt @@ -13,7 +13,7 @@ import signatures.renderedContent import utils.TestOutputWriter import utils.TestOutputWriterPlugin -class EnumsTest : BaseAbstractTest() { +class KotlinEnumTest : BaseAbstractTest() { @Test fun `should preserve enum source ordering for documentables`() { @@ -276,6 +276,45 @@ class EnumsTest : BaseAbstractTest() { } } + + @Test + fun `should contain synthetic values and valueOf functions`() { + val configuration = dokkaConfiguration { + sourceSets { + sourceSet { + sourceRoots = listOf("src/") + } + } + } + + testInline( + """ + |/src/main/kotlin/basic/Test.kt + |package testpackage + | + |enum class TestEnum { + | E1, + | E2; + |} + """.trimMargin(), + configuration + ) { + // stage is important because they will get filtered out later on + documentablesCreationStage = { modules -> + val pckg = modules.flatMap { it.packages }.single { it.packageName == "testpackage" } + val enum = pckg.children.single { it is DEnum } as DEnum + + val valueOf = enum.functions.single { it.name == "valueOf" } + assertEquals("testpackage/TestEnum/valueOf/#kotlin.String/PointingToDeclaration/", valueOf.dri.toString()) + assertNotNull(valueOf.extra[ObviousMember]) + + val values = enum.functions.single { it.name == "values" } + assertEquals("testpackage/TestEnum/values/#/PointingToDeclaration/", values.dri.toString()) + assertNotNull(values.extra[ObviousMember]) + } + } + } + @Test fun enumWithMethods() { val configuration = dokkaConfiguration { |