Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle PsiImmediateClassType as PsiClassType to resolve bounds #2647

Merged
merged 1 commit into from Aug 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -513,7 +513,7 @@ class DefaultPsiToDocumentableTranslator(
}

return when (type) {
is PsiClassReferenceType ->
is PsiClassType ->
type.resolve()?.let { resolved ->
when {
resolved.qualifiedName == "java.lang.Object" -> type.cacheBoundIfHasNoAnnotation { annotations -> JavaObject(annotations.annotations()) }
Expand Down Expand Up @@ -564,8 +564,6 @@ class DefaultPsiToDocumentableTranslator(

is PsiPrimitiveType -> if (type.name == "void") Void
else type.cacheBoundIfHasNoAnnotation { annotations -> PrimitiveJavaType(type.name, annotations.annotations()) }
is PsiImmediateClassType ->
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why it was done this way. Probably an exception was thrown and mapping PsiImmediateClassType -> JavaObject was added without researching. I found the PR where it was introduced and there was no additional context :(

PsiImmediateClassType and PsiClassReferenceType are both extending PsiClassType (resolve() is also part of the latter), so hopefully it's all good

type.cacheBoundIfHasNoAnnotation { annotations -> JavaObject(annotations.annotations()) }
else -> throw IllegalStateException("${type.presentableText} is not supported by PSI parser")
}
}
Expand Down
Expand Up @@ -4,6 +4,7 @@ import org.jetbrains.dokka.DokkaConfiguration
import org.jetbrains.dokka.base.DokkaBase
import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest
import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.links.PointingToDeclaration
import org.jetbrains.dokka.model.*
import org.jetbrains.dokka.model.doc.Text
import org.jetbrains.dokka.plugability.DokkaPlugin
Expand Down Expand Up @@ -538,4 +539,56 @@ class DefaultPsiToDocumentableTranslatorTest : BaseAbstractTest() {
}
}
}

@Test // see https://github.com/Kotlin/dokka/issues/2646
fun `should resolve PsiImmediateClassType as class reference`() {
testInline(
"""
|/src/main/java/test/JavaEnum.java
|package test;
|public enum JavaEnum {
| FOO, BAR
|}
|
|/src/main/java/test/ContainingEnumType.java
|package test;
|public class ContainingEnumType {
|
| public JavaEnum returningEnumType() {
| return null;
| }
|
| public JavaEnum[] returningEnumTypeArray() {
| return null;
| }
|
| public void acceptingEnumType(JavaEnum javaEnum) {}
|}
""".trimIndent(),
configuration
) {
documentablesMergingStage = { module ->
val expectedType = GenericTypeConstructor(
dri = DRI(packageName = "test", classNames = "JavaEnum", target = PointingToDeclaration),
projections = emptyList()
)
val expectedArrayType = GenericTypeConstructor(
dri = DRI("kotlin", "Array", target = PointingToDeclaration),
projections = listOf(expectedType)
)

val classWithEnumUsage = module.packages.single().classlikes.single { it.name == "ContainingEnumType" }

val returningEnum = classWithEnumUsage.functions.single { it.name == "returningEnumType" }
assertEquals(expectedType, returningEnum.type)

val acceptingEnum = classWithEnumUsage.functions.single { it.name == "acceptingEnumType" }
assertEquals(1, acceptingEnum.parameters.size)
assertEquals(expectedType, acceptingEnum.parameters[0].type)

val returningArray = classWithEnumUsage.functions.single { it.name == "returningEnumTypeArray" }
assertEquals(expectedArrayType, returningArray.type)
}
}
}
}