Support KClassValue in JavaActualAnnotationArgumentExtractor

#KT-22704 Fixed
This commit is contained in:
Alexander Udalov
2018-10-18 18:24:25 +02:00
parent 49d6a7a7cb
commit 3bfe138dbe
3 changed files with 44 additions and 8 deletions
@@ -7,13 +7,17 @@ package org.jetbrains.kotlin.resolve.jvm.multiplatform
import com.intellij.psi.PsiAnnotationMethod
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
import org.jetbrains.kotlin.load.java.components.JavaPropertyInitializerEvaluatorImpl
import org.jetbrains.kotlin.load.java.structure.*
import org.jetbrains.kotlin.load.java.structure.impl.JavaAnnotationArgumentImpl
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory
import org.jetbrains.kotlin.resolve.constants.EnumValue
import org.jetbrains.kotlin.resolve.constants.KClassValue
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.builtIns
@@ -47,8 +51,36 @@ class JavaActualAnnotationArgumentExtractor : ExpectedActualDeclarationChecker.A
null
}
is JavaClassObjectAnnotationArgument -> {
// TODO: support class literals as annotation arguments
null
convertTypeToKClassValue(getReferencedType())
}
else -> null
}
}
// See FileBasedKotlinClass.resolveKotlinNameByType
private fun convertTypeToKClassValue(javaType: JavaType): KClassValue? {
var type = javaType
var arrayDimensions = 0
while (type is JavaArrayType) {
type = type.componentType
arrayDimensions++
}
return when (type) {
is JavaPrimitiveType -> {
val primitiveType = type.type
// void.class is not representable in Kotlin, we approximate it by Unit::class
?: return KClassValue(ClassId.topLevel(KotlinBuiltIns.FQ_NAMES.unit.toSafe()), 0)
if (arrayDimensions > 0) {
KClassValue(ClassId.topLevel(primitiveType.arrayTypeFqName), arrayDimensions - 1)
} else {
KClassValue(ClassId.topLevel(primitiveType.typeFqName), arrayDimensions)
}
}
is JavaClassifierType -> {
val fqName = FqName(type.classifierQualifiedName)
// TODO: support nested classes somehow
val classId = JavaToKotlinClassMap.mapJavaToKotlin(fqName) ?: ClassId.topLevel(fqName)
KClassValue(classId, arrayDimensions)
}
else -> null
}