Use AnnotationDescriptor.fqName instead of type

Also use the annotationClass extension property instead of
TypeUtils.getClassDescriptor(annotation.type)
This commit is contained in:
Alexander Udalov
2017-07-04 18:38:36 +03:00
parent 541b9dab52
commit def3f73fdd
16 changed files with 48 additions and 100 deletions
@@ -35,7 +35,6 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.getAnnotationRetention
import org.jetbrains.kotlin.resolve.descriptorUtil.isRepeatableAnnotation
import org.jetbrains.kotlin.resolve.inline.InlineUtil
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
import org.jetbrains.kotlin.types.isError
@@ -107,7 +106,7 @@ class AnnotationChecker(private val additionalCheckers: Iterable<AdditionalAnnot
for (entry in entries) {
checkAnnotationEntry(entry, actualTargets, trace)
val descriptor = trace.get(BindingContext.ANNOTATION, entry) ?: continue
val classDescriptor = TypeUtils.getClassDescriptor(descriptor.type) ?: continue
val classDescriptor = descriptor.annotationClass ?: continue
val useSiteTarget = entry.useSiteTarget?.getAnnotationUseSiteTarget() ?: annotated.getDefaultUseSiteTarget(descriptor)
val existingTargetsForAnnotation = entryTypesWithAnnotations.getOrPut(descriptor.type) { arrayListOf() }
@@ -169,8 +168,7 @@ class AnnotationChecker(private val additionalCheckers: Iterable<AdditionalAnnot
val descriptor = trace.get(BindingContext.ANNOTATION, entry) ?: return KotlinTarget.DEFAULT_TARGET_SET
// For descriptor with error type, all targets are considered as possible
if (descriptor.type.isError) return KotlinTarget.ALL_TARGET_SET
val classDescriptor = TypeUtils.getClassDescriptor(descriptor.type) ?: return KotlinTarget.DEFAULT_TARGET_SET
return applicableTargetSet(classDescriptor) ?: KotlinTarget.DEFAULT_TARGET_SET
return descriptor.annotationClass?.let(this::applicableTargetSet) ?: KotlinTarget.DEFAULT_TARGET_SET
}
@JvmStatic fun applicableTargetSet(descriptor: AnnotationDescriptor): Set<KotlinTarget> {
@@ -142,10 +142,10 @@ class TypeAliasExpander(
}
private fun checkRepeatedAnnotations(existingAnnotations: Annotations, newAnnotations: Annotations) {
val existingAnnotationTypes = existingAnnotations.mapTo(hashSetOf()) { it.type }
val existingAnnotationFqNames = existingAnnotations.mapTo(hashSetOf()) { it.fqName }
for (annotation in newAnnotations) {
if (annotation.type in existingAnnotationTypes) {
if (annotation.fqName in existingAnnotationFqNames) {
reportStrategy.repeatedAnnotation(annotation)
}
}
@@ -25,27 +25,22 @@ import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.types.TypeUtils
object PublishedApiUsageChecker {
fun check(
declaration: KtDeclaration,
descriptor: DeclarationDescriptor,
trace: BindingTrace
) {
if (descriptor !is DeclarationDescriptorWithVisibility || descriptor.visibility == Visibilities.INTERNAL) return
/*Don't report diagnostic twise*/
// Don't report the diagnostic twice
if (descriptor is PropertyAccessorDescriptor) return
for (entry in declaration.annotationEntries) {
val annotationDescriptor = trace.get(BindingContext.ANNOTATION, entry) ?: continue
val classDescriptor = TypeUtils.getClassDescriptor(annotationDescriptor.type) ?: continue
if (classDescriptor.fqNameSafe == KotlinBuiltIns.FQ_NAMES.publishedApi) {
if (annotationDescriptor.fqName == KotlinBuiltIns.FQ_NAMES.publishedApi) {
trace.report(Errors.NON_INTERNAL_PUBLISHED_API.on(entry))
}
}
}
}
}
@@ -171,7 +171,7 @@ abstract class KotlinSuppressCache {
builder.addAll(suppressStringProvider[annotationDescriptor])
}
if (!KotlinBuiltIns.isSuppressAnnotation(annotationDescriptor)) return
if (annotationDescriptor.fqName != KotlinBuiltIns.FQ_NAMES.suppress) return
// We only add strings and skip other values to facilitate recovery in presence of erroneous code
for (arrayValue in annotationDescriptor.allValueArguments.values) {
@@ -16,17 +16,12 @@
package org.jetbrains.kotlin.resolve.diagnostics
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
import org.jetbrains.kotlin.diagnostics.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0
val FUNCTION_NO_BODY_ERRORS: List<DiagnosticFactory1<KtFunction, SimpleFunctionDescriptor>> =
listOf(Errors.NON_ABSTRACT_FUNCTION_WITH_NO_BODY, Errors.NON_MEMBER_FUNCTION_NO_BODY)
@@ -36,18 +31,13 @@ val PROPERTY_NOT_INITIALIZED_ERRORS: List<DiagnosticFactory0<KtProperty>> =
abstract class SuppressDiagnosticsByAnnotations(
diagnosticsToSuppress: List<DiagnosticFactory<out Diagnostic>>,
vararg annotationsFqName: FqName
vararg annotationFqNames: FqName
) : SuppressStringProvider {
private val stringsToSuppress = diagnosticsToSuppress.map { it.name.toLowerCase() }
private val expectedFqNames = annotationsFqName.map(FqName::toString)
private val expectedFqNames = annotationFqNames.toSet()
override fun get(annotationDescriptor: AnnotationDescriptor): List<String> {
val descriptor = DescriptorUtils.getClassDescriptorForType(annotationDescriptor.type)
val actualFqName = DescriptorUtils.getFqName(descriptor).asString()
if (expectedFqNames.any { it == actualFqName }) return stringsToSuppress
return listOf()
return if (annotationDescriptor.fqName in expectedFqNames) stringsToSuppress else emptyList()
}
}
@@ -23,7 +23,10 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtAnnotationEntry
import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.AnnotationResolver
import org.jetbrains.kotlin.resolve.AnnotationResolverImpl
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil
import org.jetbrains.kotlin.resolve.lazy.LazyEntity
@@ -31,7 +34,6 @@ import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.source.toSourceElement
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.storage.getValue
import org.jetbrains.kotlin.types.isError
abstract class LazyAnnotationsContext(
val annotationResolver: AnnotationResolver,
@@ -62,22 +64,7 @@ class LazyAnnotations(
AnnotationWithTarget(descriptor, target)
}
override fun findAnnotation(fqName: FqName): AnnotationDescriptor? {
// We can not efficiently check short names here:
// an annotation class may be renamed on import
for (annotationDescriptor in iterator()) {
val annotationType = annotationDescriptor.type
if (annotationType.isError) continue
val descriptor = annotationType.constructor.declarationDescriptor ?: continue
if (DescriptorUtils.getFqNameSafe(descriptor) == fqName) {
return annotationDescriptor
}
}
return null
}
override fun findAnnotation(fqName: FqName): AnnotationDescriptor? = firstOrNull { it.fqName == fqName }
override fun getUseSiteTargetedAnnotations(): List<AnnotationWithTarget> {
return annotationEntries