Add SourceElement to AnnotationDescriptor

Use KotlinSourceElement in the compiler for annotations resolved from PSI,
introduce ReflectAnnotationSource for reflection
This commit is contained in:
Alexander Udalov
2015-07-24 02:07:42 +03:00
parent ef4a5e78ed
commit d0562b7b90
17 changed files with 110 additions and 58 deletions
@@ -20,13 +20,17 @@ import com.intellij.openapi.util.Ref;
import kotlin.jvm.functions.Function3; import kotlin.jvm.functions.Function3;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.SourceElement;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames; import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader; import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader;
import org.jetbrains.kotlin.load.kotlin.header.ReadKotlinClassHeaderAnnotationVisitor; import org.jetbrains.kotlin.load.kotlin.header.ReadKotlinClassHeaderAnnotationVisitor;
import org.jetbrains.kotlin.name.ClassId; import org.jetbrains.kotlin.name.ClassId;
import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.name.Name;
import org.jetbrains.org.objectweb.asm.*; import org.jetbrains.org.objectweb.asm.ClassReader;
import org.jetbrains.org.objectweb.asm.ClassVisitor;
import org.jetbrains.org.objectweb.asm.FieldVisitor;
import org.jetbrains.org.objectweb.asm.MethodVisitor;
import java.util.*; import java.util.*;
@@ -149,7 +153,7 @@ public abstract class FileBasedKotlinClass implements KotlinJvmBinaryClass {
private static org.jetbrains.org.objectweb.asm.AnnotationVisitor convertAnnotationVisitor( private static org.jetbrains.org.objectweb.asm.AnnotationVisitor convertAnnotationVisitor(
@NotNull AnnotationVisitor visitor, @NotNull String desc, @NotNull InnerClassesInfo innerClasses @NotNull AnnotationVisitor visitor, @NotNull String desc, @NotNull InnerClassesInfo innerClasses
) { ) {
AnnotationArgumentVisitor v = visitor.visitAnnotation(resolveNameByDesc(desc, innerClasses)); AnnotationArgumentVisitor v = visitor.visitAnnotation(resolveNameByDesc(desc, innerClasses), SourceElement.NO_SOURCE);
return v == null ? null : convertAnnotationVisitor(v, innerClasses); return v == null ? null : convertAnnotationVisitor(v, innerClasses);
} }
@@ -236,7 +240,7 @@ public abstract class FileBasedKotlinClass implements KotlinJvmBinaryClass {
@Override @Override
public org.jetbrains.org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int parameter, @NotNull String desc, boolean visible) { public org.jetbrains.org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int parameter, @NotNull String desc, boolean visible) {
AnnotationArgumentVisitor av = v.visitParameterAnnotation(parameter, resolveNameByDesc(desc, innerClasses)); AnnotationArgumentVisitor av = v.visitParameterAnnotation(parameter, resolveNameByDesc(desc, innerClasses), SourceElement.NO_SOURCE);
return av == null ? null : convertAnnotationVisitor(av, innerClasses); return av == null ? null : convertAnnotationVisitor(av, innerClasses);
} }
@@ -19,10 +19,7 @@ package org.jetbrains.kotlin.resolve.constants.evaluate
import com.intellij.psi.util.PsiTreeUtil import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.JetNodeTypes import org.jetbrains.kotlin.JetNodeTypes
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl
import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.lexer.JetTokens import org.jetbrains.kotlin.lexer.JetTokens
@@ -587,7 +584,8 @@ private class ConstantExpressionEvaluatorVisitor(
if (DescriptorUtils.isAnnotationClass(classDescriptor)) { if (DescriptorUtils.isAnnotationClass(classDescriptor)) {
val descriptor = AnnotationDescriptorImpl( val descriptor = AnnotationDescriptorImpl(
classDescriptor.getDefaultType(), classDescriptor.getDefaultType(),
constantExpressionEvaluator.resolveAnnotationArguments(call, trace) constantExpressionEvaluator.resolveAnnotationArguments(call, trace),
SourceElement.NO_SOURCE
) )
return AnnotationValue(descriptor).wrap() return AnnotationValue(descriptor).wrap()
} }
@@ -21,11 +21,15 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.JetAnnotationEntry import org.jetbrains.kotlin.psi.JetAnnotationEntry
import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.AnnotationResolver
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil
import org.jetbrains.kotlin.resolve.lazy.LazyEntity import org.jetbrains.kotlin.resolve.lazy.LazyEntity
import org.jetbrains.kotlin.resolve.scopes.JetScope import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.resolve.source.toSourceElement
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
abstract class LazyAnnotationsContext( abstract class LazyAnnotationsContext(
@@ -98,12 +102,14 @@ public class LazyAnnotationDescriptor(
) )
} }
override fun getType() = type()
private val valueArguments = c.storageManager.createLazyValue { private val valueArguments = c.storageManager.createLazyValue {
computeValueArguments() computeValueArguments()
} }
private val source = annotationEntry.toSourceElement()
override fun getType() = type()
override fun getAllValueArguments() = valueArguments() override fun getAllValueArguments() = valueArguments()
private fun computeValueArguments(): Map<ValueParameterDescriptor, ConstantValue<*>> { private fun computeValueArguments(): Map<ValueParameterDescriptor, ConstantValue<*>> {
@@ -121,6 +127,8 @@ public class LazyAnnotationDescriptor(
.filterValues { it != null } as Map<ValueParameterDescriptor, ConstantValue<*>> .filterValues { it != null } as Map<ValueParameterDescriptor, ConstantValue<*>>
} }
override fun getSource() = source
override fun forceResolveAllContents() { override fun forceResolveAllContents() {
ForceResolveUtil.forceResolveAllContents(getType()) ForceResolveUtil.forceResolveAllContents(getType())
getAllValueArguments() getAllValueArguments()
@@ -18,29 +18,22 @@ package org.jetbrains.kotlin.load.java.components
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor 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.JvmAnnotationNames
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
import org.jetbrains.kotlin.load.java.lazy.descriptors.resolveAnnotation import org.jetbrains.kotlin.load.java.lazy.descriptors.resolveAnnotation
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation import org.jetbrains.kotlin.load.java.structure.*
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.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName 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.*
import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory import org.jetbrains.kotlin.types.ErrorUtils
import java.lang.annotation.Retention import java.lang.annotation.Retention
import java.lang.annotation.Target import java.lang.annotation.Target
import java.util.* import java.util.EnumSet
public object JavaAnnotationMapper { public object JavaAnnotationMapper {
@@ -93,11 +86,16 @@ public object JavaAnnotationMapper {
} }
abstract class AbstractJavaAnnotationDescriptor( abstract class AbstractJavaAnnotationDescriptor(
c: LazyJavaResolverContext,
annotation: JavaAnnotation?, annotation: JavaAnnotation?,
private val kotlinAnnotationClassDescriptor: ClassDescriptor private val kotlinAnnotationClassDescriptor: ClassDescriptor
): AnnotationDescriptor { ): AnnotationDescriptor {
private val source = annotation?.let { c.sourceElementFactory.source(it) } ?: SourceElement.NO_SOURCE
override fun getType() = kotlinAnnotationClassDescriptor.defaultType override fun getType() = kotlinAnnotationClassDescriptor.defaultType
override fun getSource() = source
protected val valueParameters: List<ValueParameterDescriptor> protected val valueParameters: List<ValueParameterDescriptor>
get() = kotlinAnnotationClassDescriptor.constructors.single().valueParameters get() = kotlinAnnotationClassDescriptor.constructors.single().valueParameters
@@ -107,7 +105,7 @@ abstract class AbstractJavaAnnotationDescriptor(
class JavaDeprecatedAnnotationDescriptor( class JavaDeprecatedAnnotationDescriptor(
annotation: JavaAnnotation, annotation: JavaAnnotation,
c: LazyJavaResolverContext c: LazyJavaResolverContext
): AbstractJavaAnnotationDescriptor(annotation, c.module.builtIns.deprecatedAnnotation) { ): AbstractJavaAnnotationDescriptor(c, annotation, c.module.builtIns.deprecatedAnnotation) {
private val valueArguments = c.storageManager.createLazyValue { private val valueArguments = c.storageManager.createLazyValue {
val parameterDescriptor = valueParameters.firstOrNull { val parameterDescriptor = valueParameters.firstOrNull {
@@ -123,7 +121,7 @@ class JavaRetentionRepeatableAnnotationDescriptor(
retentionAnnotation: JavaAnnotation?, retentionAnnotation: JavaAnnotation?,
repeatable: Boolean, repeatable: Boolean,
c: LazyJavaResolverContext c: LazyJavaResolverContext
): AbstractJavaAnnotationDescriptor(retentionAnnotation, c.module.builtIns.annotationAnnotation) { ): AbstractJavaAnnotationDescriptor(c, retentionAnnotation, c.module.builtIns.annotationAnnotation) {
private val valueArguments = c.storageManager.createLazyValue { private val valueArguments = c.storageManager.createLazyValue {
val retentionArgument = when (firstArgument) { val retentionArgument = when (firstArgument) {
@@ -147,7 +145,7 @@ class JavaRetentionRepeatableAnnotationDescriptor(
class JavaTargetAnnotationDescriptor( class JavaTargetAnnotationDescriptor(
annotation: JavaAnnotation, annotation: JavaAnnotation,
c: LazyJavaResolverContext c: LazyJavaResolverContext
): AbstractJavaAnnotationDescriptor(annotation, c.module.builtIns.targetAnnotation) { ): AbstractJavaAnnotationDescriptor(c, annotation, c.module.builtIns.targetAnnotation) {
private val valueArguments = c.storageManager.createLazyValue { private val valueArguments = c.storageManager.createLazyValue {
val targetArgument = when (firstArgument) { val targetArgument = when (firstArgument) {
@@ -60,6 +60,8 @@ class LazyJavaAnnotationDescriptor(
annotationClass?.getDefaultType() ?: ErrorUtils.createErrorType(fqName.asString()) annotationClass?.getDefaultType() ?: ErrorUtils.createErrorType(fqName.asString())
} }
private val source = c.sourceElementFactory.source(javaAnnotation)
private val factory = ConstantValueFactory(c.module.builtIns) private val factory = ConstantValueFactory(c.module.builtIns)
override fun getType(): JetType = type() override fun getType(): JetType = type()
@@ -70,6 +72,8 @@ class LazyJavaAnnotationDescriptor(
override fun getAllValueArguments() = allValueArguments() override fun getAllValueArguments() = allValueArguments()
override fun getSource() = source
private fun computeValueArguments(): Map<ValueParameterDescriptor, ConstantValue<*>> { private fun computeValueArguments(): Map<ValueParameterDescriptor, ConstantValue<*>> {
val constructors = getAnnotationClass().getConstructors() val constructors = getAnnotationClass().getConstructors()
if (constructors.isEmpty()) return mapOf() if (constructors.isEmpty()) return mapOf()
@@ -18,19 +18,16 @@ package org.jetbrains.kotlin.load.java.typeEnhacement
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor 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.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations import org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations
import org.jetbrains.kotlin.load.java.JvmAnnotationNames 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.MUTABLE
import org.jetbrains.kotlin.load.java.typeEnhacement.MutabilityQualifier.READ_ONLY 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.NOT_NULL
import org.jetbrains.kotlin.load.java.typeEnhacement.NullabilityQualifier.NULLABLE import org.jetbrains.kotlin.load.java.typeEnhacement.NullabilityQualifier.NULLABLE
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
// The index in the lambda is the position of the type component: // 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 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 getType() = throwError()
override fun getAllValueArguments() = throwError() override fun getAllValueArguments() = throwError()
override fun getSource() = throwError()
override fun toString() = "[EnhancedType]" override fun toString() = "[EnhancedType]"
} }
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.load.kotlin package org.jetbrains.kotlin.load.kotlin
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
@@ -47,6 +48,7 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
protected abstract fun loadAnnotation( protected abstract fun loadAnnotation(
annotationClassId: ClassId, annotationClassId: ClassId,
source: SourceElement,
result: MutableList<A> result: MutableList<A>
): KotlinJvmBinaryClass.AnnotationArgumentVisitor? ): KotlinJvmBinaryClass.AnnotationArgumentVisitor?
@@ -54,11 +56,12 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
private fun loadAnnotationIfNotSpecial( private fun loadAnnotationIfNotSpecial(
annotationClassId: ClassId, annotationClassId: ClassId,
source: SourceElement,
result: MutableList<A> result: MutableList<A>
): KotlinJvmBinaryClass.AnnotationArgumentVisitor? { ): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
if (JvmAnnotationNames.isSpecialAnnotation(annotationClassId, true)) return null 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> { 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) val result = ArrayList<A>(1)
kotlinClass.loadClassAnnotations(object : KotlinJvmBinaryClass.AnnotationVisitor { kotlinClass.loadClassAnnotations(object : KotlinJvmBinaryClass.AnnotationVisitor {
override fun visitAnnotation(classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor? { override fun visitAnnotation(classId: ClassId, source: SourceElement): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
return loadAnnotationIfNotSpecial(classId, result) return loadAnnotationIfNotSpecial(classId, source, result)
} }
override fun visitEnd() { override fun visitEnd() {
@@ -220,22 +223,24 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
inner class AnnotationVisitorForMethod(signature: MemberSignature) : MemberAnnotationVisitor(signature), KotlinJvmBinaryClass.MethodAnnotationVisitor { 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) val paramSignature = MemberSignature.fromMethodSignatureAndParameterIndex(signature, index)
var result = memberAnnotations[paramSignature] var result = memberAnnotations[paramSignature]
if (result == null) { if (result == null) {
result = ArrayList<A>() result = ArrayList<A>()
memberAnnotations[paramSignature] = result memberAnnotations[paramSignature] = result
} }
return loadAnnotationIfNotSpecial(classId, result) return loadAnnotationIfNotSpecial(classId, source, result)
} }
} }
open inner class MemberAnnotationVisitor(protected val signature: MemberSignature) : KotlinJvmBinaryClass.AnnotationVisitor { open inner class MemberAnnotationVisitor(protected val signature: MemberSignature) : KotlinJvmBinaryClass.AnnotationVisitor {
private val result = ArrayList<A>() private val result = ArrayList<A>()
override fun visitAnnotation(classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor? { override fun visitAnnotation(classId: ClassId, source: SourceElement): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
return loadAnnotationIfNotSpecial(classId, result) return loadAnnotationIfNotSpecial(classId, source, result)
} }
override fun visitEnd() { override fun visitEnd() {
@@ -16,10 +16,7 @@
package org.jetbrains.kotlin.load.kotlin package org.jetbrains.kotlin.load.kotlin
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl
import org.jetbrains.kotlin.load.java.components.DescriptorResolverUtils import org.jetbrains.kotlin.load.java.components.DescriptorResolverUtils
@@ -86,6 +83,7 @@ public class BinaryClassAnnotationAndConstantLoaderImpl(
override fun loadAnnotation( override fun loadAnnotation(
annotationClassId: ClassId, annotationClassId: ClassId,
source: SourceElement,
result: MutableList<AnnotationDescriptor> result: MutableList<AnnotationDescriptor>
): KotlinJvmBinaryClass.AnnotationArgumentVisitor? { ): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
val annotationClass = resolveClass(annotationClassId) val annotationClass = resolveClass(annotationClassId)
@@ -127,7 +125,7 @@ public class BinaryClassAnnotationAndConstantLoaderImpl(
override fun visitAnnotation(name: Name, classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor? { override fun visitAnnotation(name: Name, classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
val list = ArrayList<AnnotationDescriptor>() val list = ArrayList<AnnotationDescriptor>()
val visitor = loadAnnotation(classId, list)!! val visitor = loadAnnotation(classId, SourceElement.NO_SOURCE, list)!!
return object: KotlinJvmBinaryClass.AnnotationArgumentVisitor by visitor { return object: KotlinJvmBinaryClass.AnnotationArgumentVisitor by visitor {
override fun visitEnd() { override fun visitEnd() {
visitor.visitEnd() visitor.visitEnd()
@@ -149,7 +147,7 @@ public class BinaryClassAnnotationAndConstantLoaderImpl(
} }
override fun visitEnd() { override fun visitEnd() {
result.add(AnnotationDescriptorImpl(annotationClass.getDefaultType(), arguments)) result.add(AnnotationDescriptorImpl(annotationClass.getDefaultType(), arguments, source))
} }
private fun createConstant(name: Name?, value: Any?): ConstantValue<*> { private fun createConstant(name: Name?, value: Any?): ConstantValue<*> {
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.load.kotlin;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.SourceElement;
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader; import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader;
import org.jetbrains.kotlin.name.ClassId; import org.jetbrains.kotlin.name.ClassId;
import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.name.Name;
@@ -51,14 +52,14 @@ public interface KotlinJvmBinaryClass {
interface AnnotationVisitor { interface AnnotationVisitor {
@Nullable @Nullable
AnnotationArgumentVisitor visitAnnotation(@NotNull ClassId classId); AnnotationArgumentVisitor visitAnnotation(@NotNull ClassId classId, @NotNull SourceElement source);
void visitEnd(); void visitEnd();
} }
interface MethodAnnotationVisitor extends AnnotationVisitor { interface MethodAnnotationVisitor extends AnnotationVisitor {
@Nullable @Nullable
AnnotationArgumentVisitor visitParameterAnnotation(int index, @NotNull ClassId classId); AnnotationArgumentVisitor visitParameterAnnotation(int index, @NotNull ClassId classId, @NotNull SourceElement source);
} }
interface AnnotationArgumentVisitor { interface AnnotationArgumentVisitor {
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.load.kotlin.header;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.SourceElement;
import org.jetbrains.kotlin.load.java.AbiVersionUtil; import org.jetbrains.kotlin.load.java.AbiVersionUtil;
import org.jetbrains.kotlin.name.ClassId; import org.jetbrains.kotlin.name.ClassId;
import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.name.Name;
@@ -88,7 +89,7 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
@Nullable @Nullable
@Override @Override
public AnnotationArgumentVisitor visitAnnotation(@NotNull ClassId classId) { public AnnotationArgumentVisitor visitAnnotation(@NotNull ClassId classId, @NotNull SourceElement source) {
if (headerKind != null) { if (headerKind != null) {
// Ignore all Kotlin annotations except the first found // Ignore all Kotlin annotations except the first found
return null; return null;
@@ -0,0 +1,21 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.load.kotlin.reflect
import org.jetbrains.kotlin.descriptors.SourceElement
public class ReflectAnnotationSource(public val annotation: Annotation) : SourceElement
@@ -99,7 +99,7 @@ private object ReflectClassStructure {
for ((parameterIndex, annotations) in method.getParameterAnnotations().withIndex()) { for ((parameterIndex, annotations) in method.getParameterAnnotations().withIndex()) {
for (annotation in annotations) { for (annotation in annotations) {
val annotationType = annotation.annotationType() val annotationType = annotation.annotationType()
visitor.visitParameterAnnotation(parameterIndex, annotationType.classId)?.let { visitor.visitParameterAnnotation(parameterIndex, annotationType.classId, ReflectAnnotationSource(annotation))?.let {
processAnnotationArguments(it, annotation, annotationType) processAnnotationArguments(it, annotation, annotationType)
} }
} }
@@ -130,7 +130,9 @@ private object ReflectClassStructure {
for ((parameterIndex, annotations) in parameterAnnotations.withIndex()) { for ((parameterIndex, annotations) in parameterAnnotations.withIndex()) {
for (annotation in annotations) { for (annotation in annotations) {
val annotationType = annotation.annotationType() val annotationType = annotation.annotationType()
visitor.visitParameterAnnotation(parameterIndex + shift, annotationType.classId)?.let { visitor.visitParameterAnnotation(
parameterIndex + shift, annotationType.classId, ReflectAnnotationSource(annotation)
)?.let {
processAnnotationArguments(it, annotation, annotationType) processAnnotationArguments(it, annotation, annotationType)
} }
} }
@@ -155,7 +157,7 @@ private object ReflectClassStructure {
private fun processAnnotation(visitor: KotlinJvmBinaryClass.AnnotationVisitor, annotation: Annotation) { private fun processAnnotation(visitor: KotlinJvmBinaryClass.AnnotationVisitor, annotation: Annotation) {
val annotationType = annotation.annotationType() val annotationType = annotation.annotationType()
visitor.visitAnnotation(annotationType.classId)?.let { visitor.visitAnnotation(annotationType.classId, ReflectAnnotationSource(annotation))?.let {
processAnnotationArguments(it, annotation, annotationType) processAnnotationArguments(it, annotation, annotationType)
} }
} }
@@ -709,7 +709,7 @@ public class KotlinBuiltIns {
@NotNull @NotNull
public AnnotationDescriptor createExtensionAnnotation() { public AnnotationDescriptor createExtensionAnnotation() {
return new AnnotationDescriptorImpl(getBuiltInClassByName("extension").getDefaultType(), return new AnnotationDescriptorImpl(getBuiltInClassByName("extension").getDefaultType(),
Collections.<ValueParameterDescriptor, ConstantValue<?>>emptyMap()); Collections.<ValueParameterDescriptor, ConstantValue<?>>emptyMap(), SourceElement.NO_SOURCE);
} }
private static boolean isTypeAnnotatedWithExtension(@NotNull JetType type) { private static boolean isTypeAnnotatedWithExtension(@NotNull JetType type) {
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.descriptors.annotations;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.ReadOnly; import org.jetbrains.annotations.ReadOnly;
import org.jetbrains.kotlin.descriptors.SourceElement;
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor; import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
import org.jetbrains.kotlin.resolve.constants.ConstantValue; import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.types.JetType; import org.jetbrains.kotlin.types.JetType;
@@ -31,4 +32,7 @@ public interface AnnotationDescriptor {
@NotNull @NotNull
@ReadOnly @ReadOnly
Map<ValueParameterDescriptor, ConstantValue<?>> getAllValueArguments(); Map<ValueParameterDescriptor, ConstantValue<?>> getAllValueArguments();
@NotNull
SourceElement getSource();
} }
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.descriptors.annotations; package org.jetbrains.kotlin.descriptors.annotations;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.descriptors.SourceElement;
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor; import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
import org.jetbrains.kotlin.renderer.DescriptorRenderer; import org.jetbrains.kotlin.renderer.DescriptorRenderer;
import org.jetbrains.kotlin.resolve.constants.ConstantValue; import org.jetbrains.kotlin.resolve.constants.ConstantValue;
@@ -28,13 +29,16 @@ import java.util.Map;
public class AnnotationDescriptorImpl implements AnnotationDescriptor { public class AnnotationDescriptorImpl implements AnnotationDescriptor {
private final JetType annotationType; private final JetType annotationType;
private final Map<ValueParameterDescriptor, ConstantValue<?>> valueArguments; private final Map<ValueParameterDescriptor, ConstantValue<?>> valueArguments;
private final SourceElement source;
public AnnotationDescriptorImpl( public AnnotationDescriptorImpl(
@NotNull JetType annotationType, @NotNull JetType annotationType,
@NotNull Map<ValueParameterDescriptor, ConstantValue<?>> valueArguments @NotNull Map<ValueParameterDescriptor, ConstantValue<?>> valueArguments,
@NotNull SourceElement source
) { ) {
this.annotationType = annotationType; this.annotationType = annotationType;
this.valueArguments = Collections.unmodifiableMap(valueArguments); this.valueArguments = Collections.unmodifiableMap(valueArguments);
this.source = source;
} }
@Override @Override
@@ -49,6 +53,12 @@ public class AnnotationDescriptorImpl implements AnnotationDescriptor {
return valueArguments; return valueArguments;
} }
@Override
@NotNull
public SourceElement getSource() {
return source;
}
@Override @Override
public String toString() { public String toString() {
return DescriptorRenderer.FQ_NAMES_IN_TYPES.renderAnnotation(this); return DescriptorRenderer.FQ_NAMES_IN_TYPES.renderAnnotation(this);
@@ -17,10 +17,7 @@
package org.jetbrains.kotlin.serialization.deserialization package org.jetbrains.kotlin.serialization.deserialization
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
@@ -55,7 +52,7 @@ public class AnnotationDeserializer(private val module: ModuleDescriptor) {
arguments.toMap() arguments.toMap()
} }
return AnnotationDescriptorImpl(annotationClass.getDefaultType(), arguments) return AnnotationDescriptorImpl(annotationClass.getDefaultType(), arguments, SourceElement.NO_SOURCE)
} }
private fun resolveArgument( private fun resolveArgument(
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.idea.decompiler.stubBuilder package org.jetbrains.kotlin.idea.decompiler.stubBuilder
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.load.kotlin.AbstractBinaryClassAnnotationAndConstantLoader import org.jetbrains.kotlin.load.kotlin.AbstractBinaryClassAnnotationAndConstantLoader
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
@@ -109,7 +110,9 @@ class AnnotationLoaderForStubBuilder(
override fun loadConstant(desc: String, initializer: Any) = null override fun loadConstant(desc: String, initializer: Any) = null
override fun loadAnnotation(annotationClassId: ClassId, result: MutableList<ClassId>): KotlinJvmBinaryClass.AnnotationArgumentVisitor? { override fun loadAnnotation(
annotationClassId: ClassId, source: SourceElement, result: MutableList<ClassId>
): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
result.add(annotationClassId) result.add(annotationClassId)
return null return null
} }