Refactor JavaEnumValueAnnotationArgument and implementations
Only require implementations to be able to compute the enum class name and the corresponding entry name. Only this should be necessary to correctly resolve the argument; the resolvers will find the corresponding class descriptor if necessary
This commit is contained in:
+12
-7
@@ -18,6 +18,8 @@ package org.jetbrains.kotlin.load.java.structure.impl
|
||||
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.load.java.structure.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
abstract class JavaAnnotationArgumentImpl(
|
||||
@@ -64,14 +66,17 @@ class JavaEnumValueAnnotationArgumentImpl(
|
||||
private val psiReference: PsiReferenceExpression,
|
||||
name: Name?
|
||||
) : JavaAnnotationArgumentImpl(name), JavaEnumValueAnnotationArgument {
|
||||
override fun resolve(): JavaField? {
|
||||
val element = psiReference.resolve()
|
||||
return when (element) {
|
||||
null -> null
|
||||
is PsiEnumConstant -> JavaFieldImpl(element)
|
||||
else -> throw IllegalStateException("Reference argument should be an enum value, but was $element: ${element.text}")
|
||||
override val enumClassId: ClassId?
|
||||
get() {
|
||||
val element = psiReference.resolve()
|
||||
if (element is PsiEnumConstant) {
|
||||
return JavaFieldImpl(element).containingClass.classId
|
||||
}
|
||||
|
||||
val fqName = (psiReference.qualifier as? PsiReferenceExpression)?.qualifiedName ?: return null
|
||||
// TODO: find a way to construct a correct name (with nested classes) for unresolved enums
|
||||
return ClassId.topLevel(FqName(fqName))
|
||||
}
|
||||
}
|
||||
|
||||
override val entryName: Name?
|
||||
get() = psiReference.referenceName?.let(Name::identifier)
|
||||
|
||||
+4
-19
@@ -127,7 +127,7 @@ class BinaryJavaAnnotation private constructor(
|
||||
}
|
||||
|
||||
override val classId: ClassId?
|
||||
get() = classifierResolutionResult.classifier.safeAs<JavaClass>()?.classId()
|
||||
get() = classifierResolutionResult.classifier.safeAs<JavaClass>()?.classId
|
||||
?: ClassId.topLevel(FqName(classifierResolutionResult.qualifiedName))
|
||||
|
||||
override fun resolve() = classifierResolutionResult.classifier as? JavaClass
|
||||
@@ -152,7 +152,7 @@ class BinaryJavaAnnotationVisitor(
|
||||
}
|
||||
|
||||
override fun visitEnum(name: String?, desc: String, value: String) {
|
||||
addArgument(PlainJavaEnumValueAnnotationArgument(name, desc, value, context))
|
||||
addArgument(PlainJavaEnumValueAnnotationArgument(name, context.mapDescToClassId(desc), value))
|
||||
}
|
||||
|
||||
override fun visit(name: String?, value: Any?) {
|
||||
@@ -216,23 +216,8 @@ class PlainJavaAnnotationAsAnnotationArgument(
|
||||
|
||||
class PlainJavaEnumValueAnnotationArgument(
|
||||
name: String?,
|
||||
private val desc: String,
|
||||
entryName: String,
|
||||
private val context: ClassifierResolutionContext
|
||||
override val enumClassId: ClassId,
|
||||
entryName: String
|
||||
) : PlainJavaAnnotationArgument(name), JavaEnumValueAnnotationArgument {
|
||||
override val entryName = Name.identifier(entryName)
|
||||
|
||||
override fun resolve(): JavaField? {
|
||||
val javaClass = context.resolveByInternalName(Type.getType(desc).internalName).classifier as? JavaClass ?: return null
|
||||
return javaClass.fields.singleOrNull { it.name == entryName }
|
||||
}
|
||||
}
|
||||
|
||||
private fun JavaClass.classId(): ClassId? {
|
||||
val fqName = fqName ?: return null
|
||||
if (outerClass == null) return ClassId.topLevel(fqName)
|
||||
|
||||
val outerClassId = outerClass!!.classId() ?: return null
|
||||
|
||||
return ClassId(outerClassId.packageFqName, outerClassId.relativeClassName.child(name), false)
|
||||
}
|
||||
|
||||
+3
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
typealias ClassIdToJavaClass = (ClassId) -> JavaClass?
|
||||
|
||||
@@ -117,4 +118,6 @@ class ClassifierResolutionContext private constructor(
|
||||
private fun createClassIdForTopLevel(internalName: String) = ClassId.topLevel(FqName(internalName.replace('/', '.')))
|
||||
|
||||
internal fun resolveByInternalName(c: String) = resolveClass(mapInternalNameToClassId(c))
|
||||
|
||||
internal fun mapDescToClassId(desc: String): ClassId = mapInternalNameToClassId(Type.getType(desc).internalName)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user