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:
Alexander Udalov
2017-12-29 16:21:58 +01:00
parent 907f53e539
commit 899002b681
12 changed files with 76 additions and 77 deletions
@@ -162,7 +162,7 @@ object JavaAnnotationTargetMapper {
internal fun mapJavaTargetArguments(arguments: List<JavaAnnotationArgument>, builtIns: KotlinBuiltIns): ConstantValue<*> {
// Map arguments: java.lang.annotation.Target -> kotlin.annotation.Target
val kotlinTargets = arguments.filterIsInstance<JavaEnumValueAnnotationArgument>()
.flatMap { mapJavaTargetArgumentByName(it.resolve()?.name?.asString()) }
.flatMap { mapJavaTargetArgumentByName(it.entryName?.asString()) }
.mapNotNull { builtIns.getAnnotationTargetEnumEntry(it) }
.map(::EnumValue)
val parameterDescriptor = DescriptorResolverUtils.getAnnotationParameterByName(
@@ -181,7 +181,7 @@ object JavaAnnotationTargetMapper {
internal fun mapJavaRetentionArgument(element: JavaAnnotationArgument?, builtIns: KotlinBuiltIns): ConstantValue<*>? {
// Map argument: java.lang.annotation.Retention -> kotlin.annotation.annotation
return (element as? JavaEnumValueAnnotationArgument)?.let {
retentionNameList[it.resolve()?.name?.asString()]?.let {
retentionNameList[it.entryName?.asString()]?.let {
builtIns.getAnnotationRetentionEnumEntry(it)?.let(::EnumValue)
}
}
@@ -67,7 +67,7 @@ class LazyJavaAnnotationDescriptor(
private fun resolveAnnotationArgument(argument: JavaAnnotationArgument?): ConstantValue<*>? {
return when (argument) {
is JavaLiteralAnnotationArgument -> ConstantValueFactory.createConstantValue(argument.value)
is JavaEnumValueAnnotationArgument -> resolveFromEnumValue(argument.resolve(), argument.entryName)
is JavaEnumValueAnnotationArgument -> resolveFromEnumValue(argument.enumClassId, argument.entryName)
is JavaArrayAnnotationArgument -> resolveFromArray(argument.name ?: DEFAULT_ANNOTATION_MEMBER_NAME, argument.getElements())
is JavaAnnotationAsAnnotationArgument -> resolveFromAnnotation(argument.getAnnotation())
is JavaClassObjectAnnotationArgument -> resolveFromJavaClassObjectType(argument.getReferencedType())
@@ -97,17 +97,19 @@ class LazyJavaAnnotationDescriptor(
return ConstantValueFactory.createArrayValue(values, arrayType)
}
private fun resolveFromEnumValue(element: JavaField?, entryName: Name?): ConstantValue<*>? {
if (element == null || !element.isEnumEntry) {
if (entryName == null) return null
private fun resolveFromEnumValue(enumClassId: ClassId?, entryName: Name?): ConstantValue<*>? {
if (entryName == null) return null
if (enumClassId == null) {
return ConstantValueFactory.createEnumValue(ErrorUtils.createErrorClassWithExactName(entryName))
}
val containingJavaClass = element.containingClass
val enumClass = c.module.findNonGenericClassAcrossDependencies(
enumClassId,
c.components.deserializedDescriptorResolver.components.notFoundClasses
)
val enumClass = c.components.moduleClassResolver.resolveClass(containingJavaClass) ?: return null
val classifier = enumClass.unsubstitutedInnerClassesScope.getContributedClassifier(element.name, NoLookupLocation.FROM_JAVA_LOADER)
val classifier = enumClass.unsubstitutedInnerClassesScope.getContributedClassifier(entryName, NoLookupLocation.FROM_JAVA_LOADER)
as? ClassDescriptor ?: return null
return ConstantValueFactory.createEnumValue(classifier)
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.load.java.structure
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
interface JavaAnnotationArgument {
@@ -31,8 +32,8 @@ interface JavaArrayAnnotationArgument : JavaAnnotationArgument {
}
interface JavaEnumValueAnnotationArgument : JavaAnnotationArgument {
val enumClassId: ClassId?
val entryName: Name?
fun resolve(): JavaField?
}
interface JavaClassObjectAnnotationArgument : JavaAnnotationArgument {
@@ -90,6 +90,9 @@ interface JavaClass : JavaClassifier, JavaTypeParameterListOwner, JavaModifierLi
val constructors: Collection<JavaConstructor>
}
val JavaClass.classId: ClassId?
get() = outerClass?.classId?.createNestedClassId(name) ?: fqName?.let(ClassId::topLevel)
enum class LightClassOriginKind {
SOURCE, BINARY
}
@@ -17,6 +17,7 @@
package kotlin.reflect.jvm.internal.structure
import org.jetbrains.kotlin.load.java.structure.*
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
abstract class ReflectJavaAnnotationArgument(
@@ -51,11 +52,12 @@ class ReflectJavaEnumValueAnnotationArgument(
name: Name?,
private val value: Enum<*>
) : ReflectJavaAnnotationArgument(name), JavaEnumValueAnnotationArgument {
override fun resolve(): ReflectJavaField {
val clazz = value::class.java
val enumClass = if (clazz.isEnum) clazz else clazz.enclosingClass
return ReflectJavaField(enumClass.getDeclaredField(value.name))
}
override val enumClassId: ClassId?
get() {
val clazz = value::class.java
val enumClass = if (clazz.isEnum) clazz else clazz.enclosingClass
return enumClass.classId
}
override val entryName: Name?
get() = Name.identifier(value.name)