Refactor: extract AnnotationDescriptor.annotationClass utility

This commit is contained in:
Pavel V. Talanov
2017-04-28 18:41:48 +03:00
parent 7ef18fe5ba
commit 55a0e138fc
19 changed files with 55 additions and 33 deletions
@@ -37,6 +37,8 @@ import org.jetbrains.org.objectweb.asm.*;
import java.lang.annotation.*; import java.lang.annotation.*;
import java.util.*; import java.util.*;
import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt.getAnnotationClass;
public abstract class AnnotationCodegen { public abstract class AnnotationCodegen {
public static final class JvmFlagAnnotation { public static final class JvmFlagAnnotation {
@@ -289,7 +291,7 @@ public abstract class AnnotationCodegen {
@Nullable @Nullable
private String genAnnotation(@NotNull AnnotationDescriptor annotationDescriptor) { private String genAnnotation(@NotNull AnnotationDescriptor annotationDescriptor) {
ClassifierDescriptor classifierDescriptor = annotationDescriptor.getType().getConstructor().getDeclarationDescriptor(); ClassifierDescriptor classifierDescriptor = getAnnotationClass(annotationDescriptor);
assert classifierDescriptor != null : "Annotation descriptor has no class: " + annotationDescriptor; assert classifierDescriptor != null : "Annotation descriptor has no class: " + annotationDescriptor;
RetentionPolicy rp = getRetentionPolicy(classifierDescriptor); RetentionPolicy rp = getRetentionPolicy(classifierDescriptor);
if (rp == RetentionPolicy.SOURCE && !typeMapper.getClassBuilderMode().generateSourceRetentionAnnotations) { if (rp == RetentionPolicy.SOURCE && !typeMapper.getClassBuilderMode().generateSourceRetentionAnnotations) {
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.psi.KtModifierListOwner import org.jetbrains.kotlin.psi.KtModifierListOwner
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.TypeUtils
@@ -44,7 +45,7 @@ interface AnnotationBasedExtension {
visitedAnnotations: MutableSet<String> = hashSetOf(), visitedAnnotations: MutableSet<String> = hashSetOf(),
allowMetaAnnotations: Boolean = true allowMetaAnnotations: Boolean = true
): Boolean { ): Boolean {
val annotationType = type.constructor.declarationDescriptor ?: return false val annotationType = annotationClass ?: return false
val annotationFqName = annotationType.fqNameSafe.asString() val annotationFqName = annotationType.fqNameSafe.asString()
if (annotationFqName in visitedAnnotations) return false // Prevent infinite recursion if (annotationFqName in visitedAnnotations) return false // Prevent infinite recursion
if (annotationFqName in getAnnotationFqNames(modifierListOwner)) return true if (annotationFqName in getAnnotationFqNames(modifierListOwner)) return true
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getAnnotationEntries import org.jetbrains.kotlin.psi.psiUtil.getAnnotationEntries
import org.jetbrains.kotlin.resolve.constants.ArrayValue import org.jetbrains.kotlin.resolve.constants.ArrayValue
import org.jetbrains.kotlin.resolve.constants.EnumValue import org.jetbrains.kotlin.resolve.constants.EnumValue
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.resolve.descriptorUtil.getAnnotationRetention import org.jetbrains.kotlin.resolve.descriptorUtil.getAnnotationRetention
import org.jetbrains.kotlin.resolve.descriptorUtil.isRepeatableAnnotation import org.jetbrains.kotlin.resolve.descriptorUtil.isRepeatableAnnotation
import org.jetbrains.kotlin.resolve.inline.InlineUtil import org.jetbrains.kotlin.resolve.inline.InlineUtil
@@ -135,7 +136,7 @@ class AnnotationChecker(private val additionalCheckers: Iterable<AdditionalAnnot
if (KotlinTarget.FUNCTION !in applicableTargets) return if (KotlinTarget.FUNCTION !in applicableTargets) return
val annotatedExpression = entry.parent as? KtAnnotatedExpression ?: return val annotatedExpression = entry.parent as? KtAnnotatedExpression ?: return
val descriptor = trace.get(BindingContext.ANNOTATION, entry) ?: return val descriptor = trace.get(BindingContext.ANNOTATION, entry) ?: return
val retention = descriptor.type.constructor.declarationDescriptor?.getAnnotationRetention() val retention = descriptor.annotationClass?.getAnnotationRetention()
if (retention == KotlinRetention.SOURCE) return if (retention == KotlinRetention.SOURCE) return
val functionLiteralExpression = annotatedExpression.baseExpression as? KtLambdaExpression ?: return val functionLiteralExpression = annotatedExpression.baseExpression as? KtLambdaExpression ?: return
@@ -173,7 +174,7 @@ class AnnotationChecker(private val additionalCheckers: Iterable<AdditionalAnnot
} }
@JvmStatic fun applicableTargetSet(descriptor: AnnotationDescriptor): Set<KotlinTarget> { @JvmStatic fun applicableTargetSet(descriptor: AnnotationDescriptor): Set<KotlinTarget> {
val classDescriptor = descriptor.type.constructor.declarationDescriptor as? ClassDescriptor ?: return emptySet() val classDescriptor = descriptor.annotationClass ?: return emptySet()
return applicableTargetSet(classDescriptor) ?: KotlinTarget.DEFAULT_TARGET_SET return applicableTargetSet(classDescriptor) ?: KotlinTarget.DEFAULT_TARGET_SET
} }
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getImplicitReceivers import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getImplicitReceivers
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers
import org.jetbrains.kotlin.resolve.scopes.LexicalScope import org.jetbrains.kotlin.resolve.scopes.LexicalScope
@@ -79,10 +80,10 @@ private fun ReceiverValue.extractDslMarkerFqNames(): Set<FqName> {
} }
private fun Annotations.extractDslMarkerFqNames() = private fun Annotations.extractDslMarkerFqNames() =
filter(AnnotationDescriptor::isDslMarker).map { it.type.constructor.declarationDescriptor!!.fqNameSafe } filter(AnnotationDescriptor::isDslMarker).map { it.annotationClass!!.fqNameSafe }
private fun AnnotationDescriptor.isDslMarker(): Boolean { private fun AnnotationDescriptor.isDslMarker(): Boolean {
val classDescriptor = type.constructor.declarationDescriptor as? ClassDescriptor ?: return false val classDescriptor = annotationClass ?: return false
return classDescriptor.annotations.hasAnnotation(DSL_MARKER_FQ_NAME) return classDescriptor.annotations.hasAnnotation(DSL_MARKER_FQ_NAME)
} }
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.AnnotationChecker import org.jetbrains.kotlin.resolve.AnnotationChecker
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.resolve.source.getPsi import org.jetbrains.kotlin.resolve.source.getPsi
@@ -96,7 +97,7 @@ private fun lightAnnotationsForEntries(lightModifierList: KtLightModifierList<*>
return getAnnotationDescriptors(annotatedKtDeclaration, lightModifierListOwner) return getAnnotationDescriptors(annotatedKtDeclaration, lightModifierListOwner)
.mapNotNull { descriptor -> .mapNotNull { descriptor ->
val fqName = descriptor.type.constructor.declarationDescriptor?.fqNameUnsafe?.asString() ?: return@mapNotNull null val fqName = descriptor.annotationClass?.fqNameUnsafe?.asString() ?: return@mapNotNull null
val entry = descriptor.source.getPsi() as? KtAnnotationEntry ?: return@mapNotNull null val entry = descriptor.source.getPsi() as? KtAnnotationEntry ?: return@mapNotNull null
Pair(fqName, entry) Pair(fqName, entry)
} }
@@ -111,6 +112,7 @@ private fun lightAnnotationsForEntries(lightModifierList: KtLightModifierList<*>
} }
} }
} }
private fun getAnnotationDescriptors(declaration: KtDeclaration?, annotatedLightElement: KtLightElement<*, *>): List<AnnotationDescriptor> { private fun getAnnotationDescriptors(declaration: KtDeclaration?, annotatedLightElement: KtLightElement<*, *>): List<AnnotationDescriptor> {
val descriptor = declaration?.let { LightClassGenerationSupport.getInstance(it.project).resolveToDescriptor(it) } val descriptor = declaration?.let { LightClassGenerationSupport.getInstance(it.project).resolveToDescriptor(it) }
val annotatedDescriptor = when { val annotatedDescriptor = when {
@@ -147,4 +149,4 @@ private fun AnnotationWithTarget.matches(annotated: KtLightElement<*, *>): Boole
val declarationSiteTargets = AnnotationChecker.applicableTargetSet(annotation) val declarationSiteTargets = AnnotationChecker.applicableTargetSet(annotation)
return KotlinTarget.FIELD in declarationSiteTargets && KotlinTarget.PROPERTY !in declarationSiteTargets return KotlinTarget.FIELD in declarationSiteTargets && KotlinTarget.PROPERTY !in declarationSiteTargets
} }
@@ -20,14 +20,14 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationArgumentVisitor import org.jetbrains.kotlin.descriptors.annotations.AnnotationArgumentVisitor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.resolve.constants.* import org.jetbrains.kotlin.resolve.constants.*
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.serialization.ProtoBuf.Annotation.Argument.Value import org.jetbrains.kotlin.serialization.ProtoBuf.Annotation.Argument.Value
import org.jetbrains.kotlin.serialization.ProtoBuf.Annotation.Argument.Value.Type import org.jetbrains.kotlin.serialization.ProtoBuf.Annotation.Argument.Value.Type
import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.ErrorUtils
class AnnotationSerializer(private val stringTable: StringTable) { class AnnotationSerializer(private val stringTable: StringTable) {
fun serializeAnnotation(annotation: AnnotationDescriptor): ProtoBuf.Annotation = ProtoBuf.Annotation.newBuilder().apply { fun serializeAnnotation(annotation: AnnotationDescriptor): ProtoBuf.Annotation = ProtoBuf.Annotation.newBuilder().apply {
val annotationClass = annotation.type.constructor.declarationDescriptor as? ClassDescriptor val annotationClass = annotation.annotationClass ?: error("Annotation type is not a class: ${annotation.type}")
?: error("Annotation type is not a class: ${annotation.type}")
if (ErrorUtils.isError(annotationClass)) { if (ErrorUtils.isError(annotationClass)) {
error("Unresolved annotation type: ${annotation.type} at ${annotation.source.containingFile}") error("Unresolved annotation type: ${annotation.type} at ${annotation.source.containingFile}")
} }
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.platform.JvmBuiltIns
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.MultiTargetPlatform import org.jetbrains.kotlin.resolve.MultiTargetPlatform
import org.jetbrains.kotlin.resolve.constants.EnumValue import org.jetbrains.kotlin.resolve.constants.EnumValue
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.jvm.JvmAnalyzerFacade import org.jetbrains.kotlin.resolve.jvm.JvmAnalyzerFacade
import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters
@@ -158,7 +159,7 @@ class MultiModuleJavaAnalysisCustomTest : KtUsefulTestCase() {
}.forEach { checkDescriptor(it, callable) } }.forEach { checkDescriptor(it, callable) }
callable.annotations.forEach { callable.annotations.forEach {
val annotationClassDescriptor = it.type.constructor.declarationDescriptor as ClassDescriptor val annotationClassDescriptor = it.annotationClass!!
checkDescriptor(annotationClassDescriptor, callable) checkDescriptor(annotationClassDescriptor, callable)
Assert.assertEquals( Assert.assertEquals(
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
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
import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.resolve.descriptorUtil.resolveTopLevelClass import org.jetbrains.kotlin.resolve.descriptorUtil.resolveTopLevelClass
import org.jetbrains.kotlin.serialization.deserialization.findNonGenericClassAcrossDependencies import org.jetbrains.kotlin.serialization.deserialization.findNonGenericClassAcrossDependencies
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
@@ -86,7 +87,7 @@ class LazyJavaAnnotationDescriptor(
} }
} }
private fun getAnnotationClass() = getType().constructor.declarationDescriptor as ClassDescriptor private fun getAnnotationClass() = annotationClass!!
private fun resolveAnnotationArgument(argument: JavaAnnotationArgument?): ConstantValue<*>? { private fun resolveAnnotationArgument(argument: JavaAnnotationArgument?): ConstantValue<*>? {
return when (argument) { return when (argument) {
@@ -16,9 +16,9 @@
package org.jetbrains.kotlin.descriptors.annotations package org.jetbrains.kotlin.descriptors.annotations
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
interface Annotated { interface Annotated {
val annotations: Annotations val annotations: Annotations
@@ -76,8 +76,8 @@ interface Annotations : Iterable<AnnotationDescriptor> {
} }
fun checkAnnotationName(annotation: AnnotationDescriptor, fqName: FqName): Boolean { fun checkAnnotationName(annotation: AnnotationDescriptor, fqName: FqName): Boolean {
val descriptor = annotation.type.constructor.declarationDescriptor val descriptor = annotation.annotationClass
return descriptor is ClassDescriptor && fqName.toUnsafe() == DescriptorUtils.getFqName(descriptor) return descriptor != null && fqName.toUnsafe() == DescriptorUtils.getFqName(descriptor)
} }
class FilteredAnnotations( class FilteredAnnotations(
@@ -108,7 +108,7 @@ class FilteredAnnotations(
override fun iterator() = delegate.filter { shouldBeReturned(it) }.iterator() override fun iterator() = delegate.filter { shouldBeReturned(it) }.iterator()
private fun shouldBeReturned(annotation: AnnotationDescriptor): Boolean { private fun shouldBeReturned(annotation: AnnotationDescriptor): Boolean {
val descriptor = annotation.type.constructor.declarationDescriptor val descriptor = annotation.annotationClass
return descriptor != null && DescriptorUtils.getFqName(descriptor).let { fqName -> return descriptor != null && DescriptorUtils.getFqName(descriptor).let { fqName ->
fqName.isSafe && fqNameFilter(fqName.toSafe()) fqName.isSafe && fqNameFilter(fqName.toSafe())
} }
@@ -16,9 +16,9 @@
package org.jetbrains.kotlin.descriptors.annotations package org.jetbrains.kotlin.descriptors.annotations
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
class AnnotationsImpl : Annotations { class AnnotationsImpl : Annotations {
private val annotations: List<AnnotationDescriptor> private val annotations: List<AnnotationDescriptor>
@@ -41,8 +41,8 @@ class AnnotationsImpl : Annotations {
override fun isEmpty() = targetedAnnotations.isEmpty() override fun isEmpty() = targetedAnnotations.isEmpty()
override fun findAnnotation(fqName: FqName) = annotations.firstOrNull { override fun findAnnotation(fqName: FqName) = annotations.firstOrNull {
val descriptor = it.type.constructor.declarationDescriptor val descriptor = it.annotationClass
descriptor is ClassDescriptor && fqName.toUnsafe() == DescriptorUtils.getFqName(descriptor) descriptor != null && fqName.toUnsafe() == DescriptorUtils.getFqName(descriptor)
} }
override fun getUseSiteTargetedAnnotations(): List<AnnotationWithTarget> { override fun getUseSiteTargetedAnnotations(): List<AnnotationWithTarget> {
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.resolve.constants.AnnotationValue
import org.jetbrains.kotlin.resolve.constants.ArrayValue import org.jetbrains.kotlin.resolve.constants.ArrayValue
import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.constants.KClassValue import org.jetbrains.kotlin.resolve.constants.KClassValue
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
import org.jetbrains.kotlin.serialization.deserialization.NotFoundClasses import org.jetbrains.kotlin.serialization.deserialization.NotFoundClasses
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
@@ -396,7 +397,7 @@ internal class DescriptorRendererImpl(
val sortedAnnotations = annotated.annotations.getAllAnnotations() val sortedAnnotations = annotated.annotations.getAllAnnotations()
for ((annotation, target) in sortedAnnotations) { for ((annotation, target) in sortedAnnotations) {
val annotationClass = annotation.type.constructor.declarationDescriptor as ClassDescriptor val annotationClass = annotation.annotationClass!!
if (!excluded.contains(DescriptorUtils.getFqNameSafe(annotationClass))) { if (!excluded.contains(DescriptorUtils.getFqNameSafe(annotationClass))) {
append(renderAnnotation(annotation, target)).append(" ") append(renderAnnotation(annotation, target)).append(" ")
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.ClassKind.* import org.jetbrains.kotlin.descriptors.ClassKind.*
import org.jetbrains.kotlin.descriptors.annotations.Annotated import org.jetbrains.kotlin.descriptors.annotations.Annotated
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.LookupLocation
@@ -407,4 +408,7 @@ fun DeclarationDescriptor.isAncestorOf(descriptor: DeclarationDescriptor, strict
fun DeclarationDescriptor.isCompanionObject(): Boolean = DescriptorUtils.isCompanionObject(this) fun DeclarationDescriptor.isCompanionObject(): Boolean = DescriptorUtils.isCompanionObject(this)
fun ClassDescriptor.isSubclassOf(superclass: ClassDescriptor): Boolean = DescriptorUtils.isSubclass(this, superclass) fun ClassDescriptor.isSubclassOf(superclass: ClassDescriptor): Boolean = DescriptorUtils.isSubclass(this, superclass)
val AnnotationDescriptor.annotationClass: ClassDescriptor?
get() = type.constructor.declarationDescriptor as? ClassDescriptor
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
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.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
class DeserializedAnnotations( class DeserializedAnnotations(
@@ -42,8 +43,8 @@ open class DeserializedAnnotationsWithPossibleTargets(
override fun findAnnotation(fqName: FqName) = annotations().firstOrNull { override fun findAnnotation(fqName: FqName) = annotations().firstOrNull {
annotationWithTarget -> annotationWithTarget ->
if (annotationWithTarget.target != null) return@firstOrNull false if (annotationWithTarget.target != null) return@firstOrNull false
val descriptor = annotationWithTarget.annotation.type.constructor.declarationDescriptor val descriptor = annotationWithTarget.annotation.annotationClass
descriptor is ClassDescriptor && fqName.toUnsafe() == DescriptorUtils.getFqName(descriptor) descriptor != null && fqName.toUnsafe() == DescriptorUtils.getFqName(descriptor)
}?.annotation }?.annotation
override fun findExternalAnnotation(fqName: FqName) = null override fun findExternalAnnotation(fqName: FqName) = null
@@ -42,6 +42,7 @@ import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
class KotlinAnnotatedElementsSearcher : QueryExecutor<PsiModifierListOwner, AnnotatedElementsSearch.Parameters> { class KotlinAnnotatedElementsSearcher : QueryExecutor<PsiModifierListOwner, AnnotatedElementsSearch.Parameters> {
@@ -101,7 +102,7 @@ class KotlinAnnotatedElementsSearcher : QueryExecutor<PsiModifierListOwner, Anno
val context = elt.analyze(BodyResolveMode.PARTIAL) val context = elt.analyze(BodyResolveMode.PARTIAL)
val annotationDescriptor = context.get(BindingContext.ANNOTATION, elt) ?: return true val annotationDescriptor = context.get(BindingContext.ANNOTATION, elt) ?: return true
val descriptor = annotationDescriptor.type.constructor.declarationDescriptor ?: return true val descriptor = annotationDescriptor.annotationClass ?: return true
if (DescriptorUtils.getFqName(descriptor).asString() != annotationFQN) return true if (DescriptorUtils.getFqName(descriptor).asString() != annotationFQN) return true
} }
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.psi.KtAnnotationEntry
import org.jetbrains.kotlin.resolve.AdditionalAnnotationChecker import org.jetbrains.kotlin.resolve.AdditionalAnnotationChecker
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
object JsQualifierChecker : AdditionalAnnotationChecker { object JsQualifierChecker : AdditionalAnnotationChecker {
@@ -29,7 +30,7 @@ object JsQualifierChecker : AdditionalAnnotationChecker {
val bindingContext = trace.bindingContext val bindingContext = trace.bindingContext
for (entry in entries) { for (entry in entries) {
val annotation = bindingContext[BindingContext.ANNOTATION, entry] ?: continue val annotation = bindingContext[BindingContext.ANNOTATION, entry] ?: continue
if (annotation.type.constructor.declarationDescriptor?.fqNameSafe != AnnotationsUtils.JS_QUALIFIER_ANNOTATION) continue if (annotation.annotationClass?.fqNameSafe != AnnotationsUtils.JS_QUALIFIER_ANNOTATION) continue
val argument = annotation.allValueArguments.values.singleOrNull()?.value as? String ?: continue val argument = annotation.allValueArguments.values.singleOrNull()?.value as? String ?: continue
if (!validateQualifier(argument)) { if (!validateQualifier(argument)) {
val argumentPsi = entry.valueArgumentList!!.arguments[0] val argumentPsi = entry.valueArgumentList!!.arguments[0]
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.checkers.SimpleDeclarationChecker import org.jetbrains.kotlin.resolve.checkers.SimpleDeclarationChecker
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.resolve.descriptorUtil.getAnnotationRetention import org.jetbrains.kotlin.resolve.descriptorUtil.getAnnotationRetention
import org.jetbrains.kotlin.resolve.source.PsiSourceElement import org.jetbrains.kotlin.resolve.source.PsiSourceElement
@@ -36,7 +37,7 @@ object JsRuntimeAnnotationChecker : SimpleDeclarationChecker {
bindingContext: BindingContext bindingContext: BindingContext
) { ) {
for ((annotationDescriptor, _) in descriptor.annotations.getAllAnnotations()) { for ((annotationDescriptor, _) in descriptor.annotations.getAllAnnotations()) {
val annotationClass = annotationDescriptor.type.constructor.declarationDescriptor as? ClassDescriptor ?: continue val annotationClass = annotationDescriptor.annotationClass ?: continue
if (annotationClass.getAnnotationRetention() != KotlinRetention.RUNTIME) continue if (annotationClass.getAnnotationRetention() != KotlinRetention.RUNTIME) continue
val annotationPsi = (annotationDescriptor.source as? PsiSourceElement)?.psi ?: declaration val annotationPsi = (annotationDescriptor.source as? PsiSourceElement)?.psi ?: declaration
@@ -38,6 +38,8 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt.getAnnotationClass;
public final class AnnotationsUtils { public final class AnnotationsUtils {
private static final String JS_NAME = "kotlin.js.JsName"; private static final String JS_NAME = "kotlin.js.JsName";
public static final FqName JS_MODULE_ANNOTATION = new FqName("kotlin.js.JsModule"); public static final FqName JS_MODULE_ANNOTATION = new FqName("kotlin.js.JsModule");
@@ -218,10 +220,10 @@ public final class AnnotationsUtils {
@NotNull FqName annotationFqName @NotNull FqName annotationFqName
) { ) {
for (AnnotationDescriptor annotation : getContainingFileAnnotations(bindingContext, declaration)) { for (AnnotationDescriptor annotation : getContainingFileAnnotations(bindingContext, declaration)) {
DeclarationDescriptor annotationType = annotation.getType().getConstructor().getDeclarationDescriptor(); DeclarationDescriptor annotationType = getAnnotationClass(annotation);
if (annotationType == null) continue; if (annotationType == null) continue;
FqNameUnsafe fqName = DescriptorUtils.getFqName(annotation.getType().getConstructor().getDeclarationDescriptor()); FqNameUnsafe fqName = DescriptorUtils.getFqName(annotationType);
if (fqName.equals(annotationFqName.toUnsafe())) { if (fqName.equals(annotationFqName.toUnsafe())) {
return extractSingleStringArgument(annotation); return extractSingleStringArgument(annotation);
} }
@@ -235,10 +237,10 @@ public final class AnnotationsUtils {
public static boolean isFromNonModuleFile(@NotNull BindingContext bindingContext, @NotNull DeclarationDescriptor declaration) { public static boolean isFromNonModuleFile(@NotNull BindingContext bindingContext, @NotNull DeclarationDescriptor declaration) {
for (AnnotationDescriptor annotation : getContainingFileAnnotations(bindingContext, declaration)) { for (AnnotationDescriptor annotation : getContainingFileAnnotations(bindingContext, declaration)) {
DeclarationDescriptor annotationType = annotation.getType().getConstructor().getDeclarationDescriptor(); DeclarationDescriptor annotationType = getAnnotationClass(annotation);
if (annotationType == null) continue; if (annotationType == null) continue;
DeclarationDescriptor annotationTypeDescriptor = annotation.getType().getConstructor().getDeclarationDescriptor(); DeclarationDescriptor annotationTypeDescriptor = getAnnotationClass(annotation);
assert annotationTypeDescriptor != null : "Annotation type should have descriptor: " + annotation.getType(); assert annotationTypeDescriptor != null : "Annotation type should have descriptor: " + annotation.getType();
FqNameUnsafe fqName = DescriptorUtils.getFqName(annotationTypeDescriptor); FqNameUnsafe fqName = DescriptorUtils.getFqName(annotationTypeDescriptor);
@@ -65,6 +65,7 @@ import static org.jetbrains.kotlin.js.translate.utils.TranslationUtils.translate
import static org.jetbrains.kotlin.resolve.BindingContext.*; import static org.jetbrains.kotlin.resolve.BindingContext.*;
import static org.jetbrains.kotlin.resolve.BindingContextUtils.isVarCapturedInClosure; import static org.jetbrains.kotlin.resolve.BindingContextUtils.isVarCapturedInClosure;
import static org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt.getResolvedCallWithAssert; import static org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt.getResolvedCallWithAssert;
import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt.getAnnotationClass;
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionExpression; import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionExpression;
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionLiteral; import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionLiteral;
@@ -573,7 +574,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
AnnotationDescriptor descriptor = context.bindingContext().get(BindingContext.ANNOTATION, entry); AnnotationDescriptor descriptor = context.bindingContext().get(BindingContext.ANNOTATION, entry);
if (descriptor == null) continue; if (descriptor == null) continue;
ClassifierDescriptor classifierDescriptor = descriptor.getType().getConstructor().getDeclarationDescriptor(); ClassifierDescriptor classifierDescriptor = getAnnotationClass(descriptor);
if (classifierDescriptor == null) continue; if (classifierDescriptor == null) continue;
KotlinRetention retention = DescriptorUtilsKt.getAnnotationRetention(classifierDescriptor); KotlinRetention retention = DescriptorUtilsKt.getAnnotationRetention(classifierDescriptor);
@@ -4,6 +4,7 @@ import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.psi.KtAnnotationEntry import org.jetbrains.kotlin.psi.KtAnnotationEntry
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.uast.* import org.jetbrains.uast.*
@@ -14,7 +15,7 @@ class KotlinUAnnotation(
private val resolvedAnnotation by lz { psi.analyze()[BindingContext.ANNOTATION, psi] } private val resolvedAnnotation by lz { psi.analyze()[BindingContext.ANNOTATION, psi] }
override val qualifiedName: String? override val qualifiedName: String?
get() = resolvedAnnotation?.type?.constructor?.declarationDescriptor?.fqNameSafe?.asString() get() = resolvedAnnotation?.annotationClass?.fqNameSafe?.asString()
override val attributeValues by lz { override val attributeValues by lz {
val context = getUastContext() val context = getUastContext()
@@ -28,7 +29,7 @@ class KotlinUAnnotation(
} }
override fun resolve(): PsiClass? { override fun resolve(): PsiClass? {
val descriptor = resolvedAnnotation?.type?.constructor?.declarationDescriptor ?: return null val descriptor = resolvedAnnotation?.annotationClass ?: return null
return descriptor.toSource()?.getMaybeLightElement(this) as? PsiClass return descriptor.toSource()?.getMaybeLightElement(this) as? PsiClass
} }