Skip to content

Commit

Permalink
Fix parsing of static imports in java annotation params (#2593)
Browse files Browse the repository at this point in the history
Fixes #2580
  • Loading branch information
IgnatBeresnev committed Aug 3, 2022
1 parent 3994c42 commit 256740a
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 3 deletions.
Expand Up @@ -3,6 +3,7 @@ package org.jetbrains.dokka.base.translators.psi
import com.intellij.lang.jvm.JvmModifier
import com.intellij.lang.jvm.annotation.JvmAnnotationAttribute
import com.intellij.lang.jvm.annotation.JvmAnnotationAttributeValue
import com.intellij.lang.jvm.annotation.JvmAnnotationConstantValue
import com.intellij.lang.jvm.annotation.JvmAnnotationEnumFieldValue
import com.intellij.lang.jvm.types.JvmReferenceType
import com.intellij.openapi.vfs.VirtualFileManager
Expand Down Expand Up @@ -682,9 +683,22 @@ class DefaultPsiToDocumentableTranslator(
* This is a workaround for static imports from JDK like RetentionPolicy
* For some reason they are not represented in the same way than using normal import
*/
private fun JvmAnnotationAttributeValue.toValue(): AnnotationParameterValue? = when (this) {
is JvmAnnotationEnumFieldValue -> (field as? PsiElement)?.let { EnumValue(fieldName ?: "", DRI.from(it)) }
else -> null
private fun JvmAnnotationAttributeValue.toValue(): AnnotationParameterValue? {
return when (this) {
is JvmAnnotationEnumFieldValue -> (field as? PsiElement)?.let { EnumValue(fieldName ?: "", DRI.from(it)) }
// static import of a constant is resolved to constant value instead of a field/link
is JvmAnnotationConstantValue -> this.constantValue?.toAnnotationLiteralValue()
else -> null
}
}

private fun Any.toAnnotationLiteralValue() = when (this) {
is Int -> IntValue(this)
is Long -> LongValue(this)
is Boolean -> BooleanValue(this)
is Float -> FloatValue(this)
is Double -> DoubleValue(this)
else -> StringValue(this.toString())
}

private fun PsiAnnotationMemberValue.toValue(): AnnotationParameterValue? = when (this) {
Expand Down
Expand Up @@ -198,6 +198,70 @@ class DefaultPsiToDocumentableTranslatorTest : BaseAbstractTest() {
}
}

@Test
fun `should resolve static imports used as annotation param values as literal values`() {
testInline(
"""
|/src/main/java/test/JavaClassUsingAnnotation.java
|package test;
|
|import static test.JavaConstants.STRING;
|import static test.JavaConstants.INTEGER;
|import static test.JavaConstants.LONG;
|import static test.JavaConstants.BOOLEAN;
|import static test.JavaConstants.DOUBLE;
|import static test.JavaConstants.FLOAT;
|
|@JavaAnnotation(
| stringValue = STRING, intValue = INTEGER, longValue = LONG,
| booleanValue = BOOLEAN, doubleValue = DOUBLE, floatValue = FLOAT
|)
|public class JavaClassUsingAnnotation {
|}
|
|/src/main/java/test/JavaAnnotation.java
|package test;
|@Documented
|public @interface JavaAnnotation {
| String stringValue();
| int intValue();
| long longValue();
| boolean booleanValue();
| double doubleValue();
| float floatValue();
|}
|
|/src/main/java/test/JavaConstants.java
|package test;
|public class JavaConstants {
| public static final String STRING = "STRING_CONSTANT_VALUE";
| public static final int INTEGER = 5;
| public static final long LONG = 6L;
| public static final boolean BOOLEAN = true;
| public static final double DOUBLE = 7.0d;
| public static final float FLOAT = 8.0f;
|}
""".trimIndent(),
configuration
) {
documentablesMergingStage = { module ->
val testedClass = module.packages.single().classlikes.single { it.name == "JavaClassUsingAnnotation" }

val annotation = (testedClass as DClass).extra[Annotations]?.directAnnotations?.values?.single()?.single()
checkNotNull(annotation)

assertEquals("JavaAnnotation", annotation.dri.classNames)
assertEquals(StringValue("STRING_CONSTANT_VALUE"), annotation.params["stringValue"])

assertEquals(IntValue(5), annotation.params["intValue"])
assertEquals(LongValue(6), annotation.params["longValue"])
assertEquals(BooleanValue(true), annotation.params["booleanValue"])
assertEquals(DoubleValue(7.0), annotation.params["doubleValue"])
assertEquals(FloatValue(8.0f), annotation.params["floatValue"])
}
}
}

class OnlyPsiPlugin : DokkaPlugin() {
private val dokkaBase by lazy { plugin<DokkaBase>() }

Expand Down

0 comments on commit 256740a

Please sign in to comment.