Load enum/array annotation arguments for not found classes
It's necessary to load type qualifier related annotations without JSR305 annotations being in the classpath #KT-19419 In Progress
This commit is contained in:
+3
@@ -72,6 +72,9 @@ class JavaEnumValueAnnotationArgumentImpl(
|
||||
else -> throw IllegalStateException("Reference argument should be an enum value, but was $element: ${element.text}")
|
||||
}
|
||||
}
|
||||
|
||||
override val entryName: Name?
|
||||
get() = psiReference.referenceName?.let(Name::identifier)
|
||||
}
|
||||
|
||||
class JavaClassObjectAnnotationArgumentImpl(
|
||||
|
||||
+4
-2
@@ -184,12 +184,14 @@ class PlainJavaAnnotationAsAnnotationArgument(
|
||||
class PlainJavaEnumValueAnnotationArgument(
|
||||
name: String?,
|
||||
private val desc: String,
|
||||
private val entryName: String,
|
||||
entryName: String,
|
||||
private val context: ClassifierResolutionContext
|
||||
) : 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.asString() == entryName }
|
||||
return javaClass.fields.singleOrNull { it.name == entryName }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -61,6 +61,8 @@ class SymbolBasedReferenceAnnotationArgument(
|
||||
val element: VariableElement,
|
||||
javac: JavacWrapper
|
||||
) : SymbolBasedAnnotationArgument(Name.identifier(element.simpleName.toString()), javac), JavaEnumValueAnnotationArgument {
|
||||
override val entryName: Name?
|
||||
get() = Name.identifier(element.simpleName.toString())
|
||||
|
||||
override fun resolve() = SymbolBasedField(element, javac)
|
||||
|
||||
@@ -90,4 +92,4 @@ class SymbolBasedLiteralAnnotationArgument(
|
||||
override val value : Any,
|
||||
name : Name,
|
||||
javac: JavacWrapper
|
||||
) : SymbolBasedAnnotationArgument(name, javac), JavaLiteralAnnotationArgument
|
||||
) : SymbolBasedAnnotationArgument(name, javac), JavaLiteralAnnotationArgument
|
||||
|
||||
+15
-5
@@ -69,7 +69,7 @@ class LazyJavaAnnotationDescriptor(
|
||||
private fun resolveAnnotationArgument(argument: JavaAnnotationArgument?): ConstantValue<*>? {
|
||||
return when (argument) {
|
||||
is JavaLiteralAnnotationArgument -> factory.createConstantValue(argument.value)
|
||||
is JavaEnumValueAnnotationArgument -> resolveFromEnumValue(argument.resolve())
|
||||
is JavaEnumValueAnnotationArgument -> resolveFromEnumValue(argument.resolve(), argument.entryName)
|
||||
is JavaArrayAnnotationArgument -> resolveFromArray(argument.name ?: DEFAULT_ANNOTATION_MEMBER_NAME, argument.getElements())
|
||||
is JavaAnnotationAsAnnotationArgument -> resolveFromAnnotation(argument.getAnnotation())
|
||||
is JavaClassObjectAnnotationArgument -> resolveFromJavaClassObjectType(argument.getReferencedType())
|
||||
@@ -84,16 +84,26 @@ class LazyJavaAnnotationDescriptor(
|
||||
private fun resolveFromArray(argumentName: Name, elements: List<JavaAnnotationArgument>): ConstantValue<*>? {
|
||||
if (type.isError) return null
|
||||
|
||||
val valueParameter = DescriptorResolverUtils.getAnnotationParameterByName(argumentName, annotationClass!!) ?: return null
|
||||
val arrayType =
|
||||
DescriptorResolverUtils.getAnnotationParameterByName(argumentName, annotationClass!!)?.type
|
||||
// Try to load annotation arguments even if the annotation class is not found
|
||||
?: c.components.module.builtIns.getArrayType(
|
||||
Variance.INVARIANT,
|
||||
ErrorUtils.createErrorType("Unknown array element type")
|
||||
)
|
||||
|
||||
val values = elements.map {
|
||||
argument -> resolveAnnotationArgument(argument) ?: factory.createNullValue()
|
||||
}
|
||||
return factory.createArrayValue(values, valueParameter.type)
|
||||
|
||||
return factory.createArrayValue(values, arrayType)
|
||||
}
|
||||
|
||||
private fun resolveFromEnumValue(element: JavaField?): ConstantValue<*>? {
|
||||
if (element == null || !element.isEnumEntry) return null
|
||||
private fun resolveFromEnumValue(element: JavaField?, entryName: Name?): ConstantValue<*>? {
|
||||
if (element == null || !element.isEnumEntry) {
|
||||
if (entryName == null) return null
|
||||
return factory.createEnumValue(ErrorUtils.createErrorClassWithExactName(entryName))
|
||||
}
|
||||
|
||||
val containingJavaClass = element.containingClass
|
||||
|
||||
|
||||
+1
@@ -31,6 +31,7 @@ interface JavaArrayAnnotationArgument : JavaAnnotationArgument {
|
||||
}
|
||||
|
||||
interface JavaEnumValueAnnotationArgument : JavaAnnotationArgument {
|
||||
val entryName: Name?
|
||||
fun resolve(): JavaField?
|
||||
}
|
||||
|
||||
|
||||
+3
@@ -56,6 +56,9 @@ class ReflectJavaEnumValueAnnotationArgument(
|
||||
val enumClass = if (clazz.isEnum) clazz else clazz.enclosingClass
|
||||
return ReflectJavaField(enumClass.getDeclaredField(value.name))
|
||||
}
|
||||
|
||||
override val entryName: Name?
|
||||
get() = Name.identifier(value.name)
|
||||
}
|
||||
|
||||
class ReflectJavaClassObjectAnnotationArgument(
|
||||
|
||||
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classValueType
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.sure
|
||||
|
||||
abstract class ConstantValue<out T>(open val value: T) {
|
||||
abstract val type: KotlinType
|
||||
@@ -139,7 +138,7 @@ class EnumValue(
|
||||
) : ConstantValue<ClassDescriptor>(value) {
|
||||
|
||||
override val type: KotlinType
|
||||
get() = value.classValueType.sure { "Enum entry must have a class object type: " + value }
|
||||
get() = value.classValueType ?: ErrorUtils.createErrorType("Containing class for error-class based enum entry $value")
|
||||
|
||||
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D) = visitor.visitEnumValue(this, data)
|
||||
|
||||
@@ -270,4 +269,4 @@ class StringValue(
|
||||
}
|
||||
|
||||
override fun hashCode() = value.hashCode()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,11 +290,11 @@ public class ErrorUtils {
|
||||
}
|
||||
}
|
||||
|
||||
private static final ErrorClassDescriptor ERROR_CLASS = new ErrorClassDescriptor(null);
|
||||
private static final ErrorClassDescriptor ERROR_CLASS = new ErrorClassDescriptor(Name.special("<ERROR CLASS>"));
|
||||
|
||||
private static class ErrorClassDescriptor extends ClassDescriptorImpl {
|
||||
public ErrorClassDescriptor(@Nullable String name) {
|
||||
super(getErrorModule(), Name.special(name == null ? "<ERROR CLASS>" : "<ERROR CLASS: " + name + ">"),
|
||||
public ErrorClassDescriptor(@NotNull Name name) {
|
||||
super(getErrorModule(), name,
|
||||
Modality.OPEN, ClassKind.CLASS, Collections.<KotlinType>emptyList(), SourceElement.NO_SOURCE,
|
||||
/* isExternal = */ false
|
||||
);
|
||||
@@ -340,7 +340,12 @@ public class ErrorUtils {
|
||||
|
||||
@NotNull
|
||||
public static ClassDescriptor createErrorClass(@NotNull String debugMessage) {
|
||||
return new ErrorClassDescriptor(debugMessage);
|
||||
return new ErrorClassDescriptor(Name.special("<ERROR CLASS: " + debugMessage + ">"));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ClassDescriptor createErrorClassWithExactName(@NotNull Name name) {
|
||||
return new ErrorClassDescriptor(name);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
Reference in New Issue
Block a user