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}")
|
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(
|
class JavaClassObjectAnnotationArgumentImpl(
|
||||||
|
|||||||
+4
-2
@@ -184,12 +184,14 @@ class PlainJavaAnnotationAsAnnotationArgument(
|
|||||||
class PlainJavaEnumValueAnnotationArgument(
|
class PlainJavaEnumValueAnnotationArgument(
|
||||||
name: String?,
|
name: String?,
|
||||||
private val desc: String,
|
private val desc: String,
|
||||||
private val entryName: String,
|
entryName: String,
|
||||||
private val context: ClassifierResolutionContext
|
private val context: ClassifierResolutionContext
|
||||||
) : PlainJavaAnnotationArgument(name), JavaEnumValueAnnotationArgument {
|
) : PlainJavaAnnotationArgument(name), JavaEnumValueAnnotationArgument {
|
||||||
|
override val entryName = Name.identifier(entryName)
|
||||||
|
|
||||||
override fun resolve(): JavaField? {
|
override fun resolve(): JavaField? {
|
||||||
val javaClass = context.resolveByInternalName(Type.getType(desc).internalName).classifier as? JavaClass ?: return null
|
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 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
@@ -61,6 +61,8 @@ class SymbolBasedReferenceAnnotationArgument(
|
|||||||
val element: VariableElement,
|
val element: VariableElement,
|
||||||
javac: JavacWrapper
|
javac: JavacWrapper
|
||||||
) : SymbolBasedAnnotationArgument(Name.identifier(element.simpleName.toString()), javac), JavaEnumValueAnnotationArgument {
|
) : SymbolBasedAnnotationArgument(Name.identifier(element.simpleName.toString()), javac), JavaEnumValueAnnotationArgument {
|
||||||
|
override val entryName: Name?
|
||||||
|
get() = Name.identifier(element.simpleName.toString())
|
||||||
|
|
||||||
override fun resolve() = SymbolBasedField(element, javac)
|
override fun resolve() = SymbolBasedField(element, javac)
|
||||||
|
|
||||||
|
|||||||
+15
-5
@@ -69,7 +69,7 @@ class LazyJavaAnnotationDescriptor(
|
|||||||
private fun resolveAnnotationArgument(argument: JavaAnnotationArgument?): ConstantValue<*>? {
|
private fun resolveAnnotationArgument(argument: JavaAnnotationArgument?): ConstantValue<*>? {
|
||||||
return when (argument) {
|
return when (argument) {
|
||||||
is JavaLiteralAnnotationArgument -> factory.createConstantValue(argument.value)
|
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 JavaArrayAnnotationArgument -> resolveFromArray(argument.name ?: DEFAULT_ANNOTATION_MEMBER_NAME, argument.getElements())
|
||||||
is JavaAnnotationAsAnnotationArgument -> resolveFromAnnotation(argument.getAnnotation())
|
is JavaAnnotationAsAnnotationArgument -> resolveFromAnnotation(argument.getAnnotation())
|
||||||
is JavaClassObjectAnnotationArgument -> resolveFromJavaClassObjectType(argument.getReferencedType())
|
is JavaClassObjectAnnotationArgument -> resolveFromJavaClassObjectType(argument.getReferencedType())
|
||||||
@@ -84,16 +84,26 @@ class LazyJavaAnnotationDescriptor(
|
|||||||
private fun resolveFromArray(argumentName: Name, elements: List<JavaAnnotationArgument>): ConstantValue<*>? {
|
private fun resolveFromArray(argumentName: Name, elements: List<JavaAnnotationArgument>): ConstantValue<*>? {
|
||||||
if (type.isError) return null
|
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 {
|
val values = elements.map {
|
||||||
argument -> resolveAnnotationArgument(argument) ?: factory.createNullValue()
|
argument -> resolveAnnotationArgument(argument) ?: factory.createNullValue()
|
||||||
}
|
}
|
||||||
return factory.createArrayValue(values, valueParameter.type)
|
|
||||||
|
return factory.createArrayValue(values, arrayType)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun resolveFromEnumValue(element: JavaField?): ConstantValue<*>? {
|
private fun resolveFromEnumValue(element: JavaField?, entryName: Name?): ConstantValue<*>? {
|
||||||
if (element == null || !element.isEnumEntry) return null
|
if (element == null || !element.isEnumEntry) {
|
||||||
|
if (entryName == null) return null
|
||||||
|
return factory.createEnumValue(ErrorUtils.createErrorClassWithExactName(entryName))
|
||||||
|
}
|
||||||
|
|
||||||
val containingJavaClass = element.containingClass
|
val containingJavaClass = element.containingClass
|
||||||
|
|
||||||
|
|||||||
+1
@@ -31,6 +31,7 @@ interface JavaArrayAnnotationArgument : JavaAnnotationArgument {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface JavaEnumValueAnnotationArgument : JavaAnnotationArgument {
|
interface JavaEnumValueAnnotationArgument : JavaAnnotationArgument {
|
||||||
|
val entryName: Name?
|
||||||
fun resolve(): JavaField?
|
fun resolve(): JavaField?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
@@ -56,6 +56,9 @@ class ReflectJavaEnumValueAnnotationArgument(
|
|||||||
val enumClass = if (clazz.isEnum) clazz else clazz.enclosingClass
|
val enumClass = if (clazz.isEnum) clazz else clazz.enclosingClass
|
||||||
return ReflectJavaField(enumClass.getDeclaredField(value.name))
|
return ReflectJavaField(enumClass.getDeclaredField(value.name))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val entryName: Name?
|
||||||
|
get() = Name.identifier(value.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReflectJavaClassObjectAnnotationArgument(
|
class ReflectJavaClassObjectAnnotationArgument(
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
|||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classValueType
|
import org.jetbrains.kotlin.resolve.descriptorUtil.classValueType
|
||||||
import org.jetbrains.kotlin.types.ErrorUtils
|
import org.jetbrains.kotlin.types.ErrorUtils
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.utils.sure
|
|
||||||
|
|
||||||
abstract class ConstantValue<out T>(open val value: T) {
|
abstract class ConstantValue<out T>(open val value: T) {
|
||||||
abstract val type: KotlinType
|
abstract val type: KotlinType
|
||||||
@@ -139,7 +138,7 @@ class EnumValue(
|
|||||||
) : ConstantValue<ClassDescriptor>(value) {
|
) : ConstantValue<ClassDescriptor>(value) {
|
||||||
|
|
||||||
override val type: KotlinType
|
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)
|
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D) = visitor.visitEnumValue(this, data)
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
private static class ErrorClassDescriptor extends ClassDescriptorImpl {
|
||||||
public ErrorClassDescriptor(@Nullable String name) {
|
public ErrorClassDescriptor(@NotNull Name name) {
|
||||||
super(getErrorModule(), Name.special(name == null ? "<ERROR CLASS>" : "<ERROR CLASS: " + name + ">"),
|
super(getErrorModule(), name,
|
||||||
Modality.OPEN, ClassKind.CLASS, Collections.<KotlinType>emptyList(), SourceElement.NO_SOURCE,
|
Modality.OPEN, ClassKind.CLASS, Collections.<KotlinType>emptyList(), SourceElement.NO_SOURCE,
|
||||||
/* isExternal = */ false
|
/* isExternal = */ false
|
||||||
);
|
);
|
||||||
@@ -340,7 +340,12 @@ public class ErrorUtils {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static ClassDescriptor createErrorClass(@NotNull String debugMessage) {
|
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
|
@NotNull
|
||||||
|
|||||||
Reference in New Issue
Block a user