Add SourceElement to AnnotationDescriptor
Use KotlinSourceElement in the compiler for annotations resolved from PSI, introduce ReflectAnnotationSource for reflection
This commit is contained in:
+14
-16
@@ -18,29 +18,22 @@ package org.jetbrains.kotlin.load.java.components
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention
|
||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
|
||||
import org.jetbrains.kotlin.load.java.lazy.descriptors.resolveAnnotation
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaAnnotationArgument
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaArrayAnnotationArgument
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaEnumValueAnnotationArgument
|
||||
import org.jetbrains.kotlin.resolve.constants.ArrayValue
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
||||
import org.jetbrains.kotlin.resolve.constants.EnumValue
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||
import org.jetbrains.kotlin.load.java.structure.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention
|
||||
import org.jetbrains.kotlin.load.java.structure.*
|
||||
import org.jetbrains.kotlin.resolve.constants.*
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import java.lang.annotation.Retention
|
||||
import java.lang.annotation.Target
|
||||
import java.util.*
|
||||
import java.util.EnumSet
|
||||
|
||||
public object JavaAnnotationMapper {
|
||||
|
||||
@@ -93,11 +86,16 @@ public object JavaAnnotationMapper {
|
||||
}
|
||||
|
||||
abstract class AbstractJavaAnnotationDescriptor(
|
||||
c: LazyJavaResolverContext,
|
||||
annotation: JavaAnnotation?,
|
||||
private val kotlinAnnotationClassDescriptor: ClassDescriptor
|
||||
): AnnotationDescriptor {
|
||||
private val source = annotation?.let { c.sourceElementFactory.source(it) } ?: SourceElement.NO_SOURCE
|
||||
|
||||
override fun getType() = kotlinAnnotationClassDescriptor.defaultType
|
||||
|
||||
override fun getSource() = source
|
||||
|
||||
protected val valueParameters: List<ValueParameterDescriptor>
|
||||
get() = kotlinAnnotationClassDescriptor.constructors.single().valueParameters
|
||||
|
||||
@@ -107,7 +105,7 @@ abstract class AbstractJavaAnnotationDescriptor(
|
||||
class JavaDeprecatedAnnotationDescriptor(
|
||||
annotation: JavaAnnotation,
|
||||
c: LazyJavaResolverContext
|
||||
): AbstractJavaAnnotationDescriptor(annotation, c.module.builtIns.deprecatedAnnotation) {
|
||||
): AbstractJavaAnnotationDescriptor(c, annotation, c.module.builtIns.deprecatedAnnotation) {
|
||||
|
||||
private val valueArguments = c.storageManager.createLazyValue {
|
||||
val parameterDescriptor = valueParameters.firstOrNull {
|
||||
@@ -123,7 +121,7 @@ class JavaRetentionRepeatableAnnotationDescriptor(
|
||||
retentionAnnotation: JavaAnnotation?,
|
||||
repeatable: Boolean,
|
||||
c: LazyJavaResolverContext
|
||||
): AbstractJavaAnnotationDescriptor(retentionAnnotation, c.module.builtIns.annotationAnnotation) {
|
||||
): AbstractJavaAnnotationDescriptor(c, retentionAnnotation, c.module.builtIns.annotationAnnotation) {
|
||||
|
||||
private val valueArguments = c.storageManager.createLazyValue {
|
||||
val retentionArgument = when (firstArgument) {
|
||||
@@ -147,7 +145,7 @@ class JavaRetentionRepeatableAnnotationDescriptor(
|
||||
class JavaTargetAnnotationDescriptor(
|
||||
annotation: JavaAnnotation,
|
||||
c: LazyJavaResolverContext
|
||||
): AbstractJavaAnnotationDescriptor(annotation, c.module.builtIns.targetAnnotation) {
|
||||
): AbstractJavaAnnotationDescriptor(c, annotation, c.module.builtIns.targetAnnotation) {
|
||||
|
||||
private val valueArguments = c.storageManager.createLazyValue {
|
||||
val targetArgument = when (firstArgument) {
|
||||
|
||||
+4
@@ -60,6 +60,8 @@ class LazyJavaAnnotationDescriptor(
|
||||
annotationClass?.getDefaultType() ?: ErrorUtils.createErrorType(fqName.asString())
|
||||
}
|
||||
|
||||
private val source = c.sourceElementFactory.source(javaAnnotation)
|
||||
|
||||
private val factory = ConstantValueFactory(c.module.builtIns)
|
||||
|
||||
override fun getType(): JetType = type()
|
||||
@@ -70,6 +72,8 @@ class LazyJavaAnnotationDescriptor(
|
||||
|
||||
override fun getAllValueArguments() = allValueArguments()
|
||||
|
||||
override fun getSource() = source
|
||||
|
||||
private fun computeValueArguments(): Map<ValueParameterDescriptor, ConstantValue<*>> {
|
||||
val constructors = getAnnotationClass().getConstructors()
|
||||
if (constructors.isEmpty()) return mapOf()
|
||||
|
||||
+2
-4
@@ -18,19 +18,16 @@ package org.jetbrains.kotlin.load.java.typeEnhacement
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.load.java.typeEnhacement.JavaTypeQualifiers
|
||||
import org.jetbrains.kotlin.load.java.typeEnhacement.MutabilityQualifier.MUTABLE
|
||||
import org.jetbrains.kotlin.load.java.typeEnhacement.MutabilityQualifier.READ_ONLY
|
||||
import org.jetbrains.kotlin.load.java.typeEnhacement.NullabilityQualifier.NOT_NULL
|
||||
import org.jetbrains.kotlin.load.java.typeEnhacement.NullabilityQualifier.NULLABLE
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
|
||||
import org.jetbrains.kotlin.types.*
|
||||
|
||||
// The index in the lambda is the position of the type component:
|
||||
@@ -177,8 +174,9 @@ private class EnhancedTypeAnnotations(private val fqNameToMatch: FqName) : Annot
|
||||
}
|
||||
|
||||
private object EnhancedTypeAnnotationDescriptor : AnnotationDescriptor {
|
||||
private fun throwError() = error("No methods should be called on this descriptor. Only it's presence matters")
|
||||
private fun throwError() = error("No methods should be called on this descriptor. Only its presence matters")
|
||||
override fun getType() = throwError()
|
||||
override fun getAllValueArguments() = throwError()
|
||||
override fun getSource() = throwError()
|
||||
override fun toString() = "[EnhancedType]"
|
||||
}
|
||||
|
||||
+12
-7
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.load.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -47,6 +48,7 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
|
||||
|
||||
protected abstract fun loadAnnotation(
|
||||
annotationClassId: ClassId,
|
||||
source: SourceElement,
|
||||
result: MutableList<A>
|
||||
): KotlinJvmBinaryClass.AnnotationArgumentVisitor?
|
||||
|
||||
@@ -54,11 +56,12 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
|
||||
|
||||
private fun loadAnnotationIfNotSpecial(
|
||||
annotationClassId: ClassId,
|
||||
source: SourceElement,
|
||||
result: MutableList<A>
|
||||
): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||
if (JvmAnnotationNames.isSpecialAnnotation(annotationClassId, true)) return null
|
||||
|
||||
return loadAnnotation(annotationClassId, result)
|
||||
return loadAnnotation(annotationClassId, source, result)
|
||||
}
|
||||
|
||||
override fun loadClassAnnotations(classProto: ProtoBuf.Class, nameResolver: NameResolver): List<A> {
|
||||
@@ -74,8 +77,8 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
|
||||
val result = ArrayList<A>(1)
|
||||
|
||||
kotlinClass.loadClassAnnotations(object : KotlinJvmBinaryClass.AnnotationVisitor {
|
||||
override fun visitAnnotation(classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||
return loadAnnotationIfNotSpecial(classId, result)
|
||||
override fun visitAnnotation(classId: ClassId, source: SourceElement): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||
return loadAnnotationIfNotSpecial(classId, source, result)
|
||||
}
|
||||
|
||||
override fun visitEnd() {
|
||||
@@ -220,22 +223,24 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
|
||||
|
||||
inner class AnnotationVisitorForMethod(signature: MemberSignature) : MemberAnnotationVisitor(signature), KotlinJvmBinaryClass.MethodAnnotationVisitor {
|
||||
|
||||
override fun visitParameterAnnotation(index: Int, classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||
override fun visitParameterAnnotation(
|
||||
index: Int, classId: ClassId, source: SourceElement
|
||||
): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||
val paramSignature = MemberSignature.fromMethodSignatureAndParameterIndex(signature, index)
|
||||
var result = memberAnnotations[paramSignature]
|
||||
if (result == null) {
|
||||
result = ArrayList<A>()
|
||||
memberAnnotations[paramSignature] = result
|
||||
}
|
||||
return loadAnnotationIfNotSpecial(classId, result)
|
||||
return loadAnnotationIfNotSpecial(classId, source, result)
|
||||
}
|
||||
}
|
||||
|
||||
open inner class MemberAnnotationVisitor(protected val signature: MemberSignature) : KotlinJvmBinaryClass.AnnotationVisitor {
|
||||
private val result = ArrayList<A>()
|
||||
|
||||
override fun visitAnnotation(classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||
return loadAnnotationIfNotSpecial(classId, result)
|
||||
override fun visitAnnotation(classId: ClassId, source: SourceElement): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||
return loadAnnotationIfNotSpecial(classId, source, result)
|
||||
}
|
||||
|
||||
override fun visitEnd() {
|
||||
|
||||
+4
-6
@@ -16,10 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.load.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl
|
||||
import org.jetbrains.kotlin.load.java.components.DescriptorResolverUtils
|
||||
@@ -86,6 +83,7 @@ public class BinaryClassAnnotationAndConstantLoaderImpl(
|
||||
|
||||
override fun loadAnnotation(
|
||||
annotationClassId: ClassId,
|
||||
source: SourceElement,
|
||||
result: MutableList<AnnotationDescriptor>
|
||||
): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||
val annotationClass = resolveClass(annotationClassId)
|
||||
@@ -127,7 +125,7 @@ public class BinaryClassAnnotationAndConstantLoaderImpl(
|
||||
|
||||
override fun visitAnnotation(name: Name, classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||
val list = ArrayList<AnnotationDescriptor>()
|
||||
val visitor = loadAnnotation(classId, list)!!
|
||||
val visitor = loadAnnotation(classId, SourceElement.NO_SOURCE, list)!!
|
||||
return object: KotlinJvmBinaryClass.AnnotationArgumentVisitor by visitor {
|
||||
override fun visitEnd() {
|
||||
visitor.visitEnd()
|
||||
@@ -149,7 +147,7 @@ public class BinaryClassAnnotationAndConstantLoaderImpl(
|
||||
}
|
||||
|
||||
override fun visitEnd() {
|
||||
result.add(AnnotationDescriptorImpl(annotationClass.getDefaultType(), arguments))
|
||||
result.add(AnnotationDescriptorImpl(annotationClass.getDefaultType(), arguments, source))
|
||||
}
|
||||
|
||||
private fun createConstant(name: Name?, value: Any?): ConstantValue<*> {
|
||||
|
||||
+3
-2
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.load.kotlin;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement;
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader;
|
||||
import org.jetbrains.kotlin.name.ClassId;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
@@ -51,14 +52,14 @@ public interface KotlinJvmBinaryClass {
|
||||
|
||||
interface AnnotationVisitor {
|
||||
@Nullable
|
||||
AnnotationArgumentVisitor visitAnnotation(@NotNull ClassId classId);
|
||||
AnnotationArgumentVisitor visitAnnotation(@NotNull ClassId classId, @NotNull SourceElement source);
|
||||
|
||||
void visitEnd();
|
||||
}
|
||||
|
||||
interface MethodAnnotationVisitor extends AnnotationVisitor {
|
||||
@Nullable
|
||||
AnnotationArgumentVisitor visitParameterAnnotation(int index, @NotNull ClassId classId);
|
||||
AnnotationArgumentVisitor visitParameterAnnotation(int index, @NotNull ClassId classId, @NotNull SourceElement source);
|
||||
}
|
||||
|
||||
interface AnnotationArgumentVisitor {
|
||||
|
||||
+2
-1
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.load.kotlin.header;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement;
|
||||
import org.jetbrains.kotlin.load.java.AbiVersionUtil;
|
||||
import org.jetbrains.kotlin.name.ClassId;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
@@ -88,7 +89,7 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public AnnotationArgumentVisitor visitAnnotation(@NotNull ClassId classId) {
|
||||
public AnnotationArgumentVisitor visitAnnotation(@NotNull ClassId classId, @NotNull SourceElement source) {
|
||||
if (headerKind != null) {
|
||||
// Ignore all Kotlin annotations except the first found
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user