Skip to content

Commit

Permalink
Mark synthetic methods generated for Java enums as obvious (#2554)
Browse files Browse the repository at this point in the history
Fixes #2548
  • Loading branch information
IgnatBeresnev committed Jun 30, 2022
1 parent 76334ec commit e3c76cb
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 9 deletions.
Expand Up @@ -112,9 +112,6 @@ class DefaultPsiToDocumentableTranslator(
private val PsiClassType.shouldBeIgnored: Boolean
get() = isClass("java.lang.Enum") || isClass("java.lang.Object")

private val DRI.isObvious: Boolean
get() = packageName == "java.lang" && (classNames == "Object" || classNames == "Enum")

private fun PsiClassType.isClass(qName: String): Boolean {
val shortName = qName.substringAfterLast('.')
if (className == shortName) {
Expand Down Expand Up @@ -446,14 +443,22 @@ class DefaultPsiToDocumentableTranslator(
(psi.annotations.toList()
.toListOfAnnotations() + it.toListOfAnnotations()).toSourceSetDependent()
.toAnnotations(),
ObviousMember.takeIf { inheritedFrom != null && inheritedFrom.isObvious },
ObviousMember.takeIf { psi.isObvious(inheritedFrom) },
psi.throwsList.toDriList().takeIf { it.isNotEmpty() }
?.let { CheckedExceptions(it.toSourceSetDependent()) }
)
}
)
}

private fun PsiMethod.isObvious(inheritedFrom: DRI? = null): Boolean {
return this is SyntheticElement || inheritedFrom?.isObvious() == true
}

private fun DRI.isObvious(): Boolean {
return packageName == "java.lang" && (classNames == "Object" || classNames == "Enum")
}

private fun PsiReferenceList.toDriList() = referenceElements.mapNotNull { it?.resolve()?.let { DRI.from(it) } }

private fun PsiModifierListOwner.additionalExtras() = listOfNotNull(
Expand Down
66 changes: 66 additions & 0 deletions plugins/base/src/test/kotlin/enums/JavaEnumTest.kt
@@ -0,0 +1,66 @@
package enums

import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest
import org.jetbrains.dokka.model.DEnum
import org.jetbrains.dokka.model.ObviousMember
import org.junit.jupiter.api.Test
import utils.TestOutputWriterPlugin
import kotlin.test.assertEquals
import kotlin.test.assertNotNull

class JavaEnumTest : BaseAbstractTest() {

private val configuration = dokkaConfiguration {
sourceSets {
sourceSet {
sourceRoots = listOf("src/")
}
}
}

@Test
fun `should mark synthetic functions generated for Kotlin as obvious`() {
val writerPlugin = TestOutputWriterPlugin()
testInline(
"""
|/src/main/java/basic/JavaEnum.java
|package testpackage
|
|public enum JavaEnum {
| ONE, TWO
|}
""".trimMargin(),
configuration,
pluginOverrides = listOf(writerPlugin)
) {
documentablesCreationStage = { modules ->
val pckg = modules.flatMap { it.packages }.single { it.packageName == "testpackage" }
val enum = pckg.children.single { it is DEnum } as DEnum

// there's two with the same name, one inherited from
// java.lang.Enum and one is synthetic for Kotlin interop
enum.functions.filter { it.name == "valueOf" }.let { valueOfMethods ->
assertEquals(2, valueOfMethods.size)

val valueOfFromKotlin = valueOfMethods[0]
assertEquals(
"testpackage/JavaEnum/valueOf/#java.lang.String/PointingToDeclaration/",
valueOfFromKotlin.dri.toString()
)
assertNotNull(valueOfFromKotlin.extra[ObviousMember])

val valueOfFromJava = valueOfMethods[1]
assertEquals(
"java.lang/Enum/valueOf/#java.lang.Class<T>#java.lang.String/PointingToDeclaration/",
valueOfFromJava.dri.toString()
)
assertNotNull(valueOfFromJava.extra[ObviousMember])
}

val valuesMethod = enum.functions.single { it.name == "values" }
assertEquals("testpackage/JavaEnum/values/#/PointingToDeclaration/", valuesMethod.dri.toString())
assertNotNull(valuesMethod.extra[ObviousMember])
}
}
}
}
5 changes: 0 additions & 5 deletions plugins/base/src/test/kotlin/model/JavaTest.kt
Expand Up @@ -334,11 +334,6 @@ class JavaTest : AbstractModelTest("/src/main/kotlin/java/Test.java", "java") {
with((this / "java" / "E").cast<DEnum>()) {
name equals "E"
entries counts 1
functions.sortedBy { it.name }.filter { it.name == "valueOf" || it.name == "values" }.map { it.dri } equals listOf(
DRI("java", "E", DRICallable("valueOf", null, listOf(JavaClassReference("java.lang.String"))), PointingToDeclaration),
DRI("java", "E", DRICallable("values", null, emptyList()), PointingToDeclaration),
)

with((this / "Foo").cast<DEnumEntry>()) {
name equals "Foo"
}
Expand Down

0 comments on commit e3c76cb

Please sign in to comment.