Introduce AnnotationDescriptor.fqName

Could be used instead of ".annotationClass.fqName" to avoid the unneeded
resolution of the annotation class descriptor
This commit is contained in:
Alexander Udalov
2017-07-04 15:21:52 +03:00
parent 1d64b61a8f
commit 41ea0e8ef8
18 changed files with 48 additions and 105 deletions
@@ -45,13 +45,12 @@ class LazyJavaAnnotationDescriptor(
private val c: LazyJavaResolverContext,
private val javaAnnotation: JavaAnnotation
) : AnnotationDescriptor {
private val fqName = c.storageManager.createNullableLazyValue {
override val fqName by c.storageManager.createNullableLazyValue {
javaAnnotation.classId?.asSingleFqName()
}
override val type by c.storageManager.createLazyValue {
val fqName = fqName() ?: return@createLazyValue ErrorUtils.createErrorType("No fqName: $javaAnnotation")
val fqName = fqName ?: return@createLazyValue ErrorUtils.createErrorType("No fqName: $javaAnnotation")
val annotationClass = JavaToKotlinClassMap.mapJavaToKotlin(fqName, c.module.builtIns)
?: javaAnnotation.resolve()?.let { javaClass -> c.components.moduleClassResolver.resolveClass(javaClass) }
?: createTypeForMissingDependencies(fqName)
@@ -34,8 +34,6 @@ import org.jetbrains.kotlin.load.kotlin.SignatureBuildingComponents
import org.jetbrains.kotlin.load.kotlin.computeJvmDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.asFlexibleType
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
@@ -48,7 +46,7 @@ import java.util.*
class SignatureEnhancement(private val annotationTypeQualifierResolver: AnnotationTypeQualifierResolver) {
fun extractNullability(annotationDescriptor: AnnotationDescriptor): NullabilityQualifier? {
val annotationFqName = annotationDescriptor.annotationClass?.fqNameSafe ?: return null
val annotationFqName = annotationDescriptor.fqName ?: return null
when (annotationFqName) {
in NULLABLE_ANNOTATIONS -> return NullabilityQualifier.NULLABLE
in NOT_NULL_ANNOTATIONS -> return NullabilityQualifier.NOT_NULL
@@ -58,7 +56,7 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati
when {
annotationFqName == JAVAX_NONNULL_ANNOTATION -> annotationDescriptor
else -> annotationTypeQualifierResolver.resolveTypeQualifierAnnotation(annotationDescriptor)
?.takeIf { it.annotationClass?.fqNameSafe == JAVAX_NONNULL_ANNOTATION }
?.takeIf { it.fqName == JAVAX_NONNULL_ANNOTATION }
} ?: return null
val enumEntryDescriptor =
@@ -16,14 +16,21 @@
package org.jetbrains.kotlin.descriptors.annotations
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.types.KotlinType
interface AnnotationDescriptor {
val type: KotlinType
val fqName: FqName? get() =
(type.constructor.declarationDescriptor as? ClassDescriptor)?.fqNameUnsafe?.takeIf(FqNameUnsafe::isSafe)?.toSafe()
val allValueArguments: Map<ValueParameterDescriptor, ConstantValue<*>>
val source: SourceElement
@@ -17,8 +17,10 @@
package org.jetbrains.kotlin.descriptors.annotations;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.SourceElement;
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.types.KotlinType;
@@ -47,6 +49,12 @@ public class AnnotationDescriptorImpl implements AnnotationDescriptor {
return annotationType;
}
@Nullable
@Override
public FqName getFqName() {
return AnnotationDescriptor.DefaultImpls.getFqName(this);
}
@Override
@NotNull
public Map<ValueParameterDescriptor, ConstantValue<?>> getAllValueArguments() {
@@ -17,8 +17,6 @@
package org.jetbrains.kotlin.descriptors.annotations
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
interface Annotated {
val annotations: Annotations
@@ -55,28 +53,21 @@ interface Annotations : Iterable<AnnotationDescriptor> {
}
fun findAnyAnnotation(annotations: Annotations, fqName: FqName): AnnotationWithTarget? {
return annotations.getAllAnnotations().firstOrNull { checkAnnotationName(it.annotation, fqName) }
return annotations.getAllAnnotations().firstOrNull { it.annotation.fqName == fqName }
}
fun findUseSiteTargetedAnnotation(annotations: Annotations, target: AnnotationUseSiteTarget, fqName: FqName): AnnotationDescriptor? {
return getUseSiteTargetedAnnotations(annotations, target).firstOrNull { checkAnnotationName(it, fqName) }
return getUseSiteTargetedAnnotations(annotations, target).firstOrNull { it.fqName == fqName }
}
private fun getUseSiteTargetedAnnotations(annotations: Annotations, target: AnnotationUseSiteTarget): List<AnnotationDescriptor> {
return annotations.getUseSiteTargetedAnnotations().fold(arrayListOf<AnnotationDescriptor>()) { list, targeted ->
if (target == targeted.target) {
list.add(targeted.annotation)
}
list
return annotations.getUseSiteTargetedAnnotations().mapNotNull { (annotation, annotationTarget) ->
annotation.takeIf { target == annotationTarget }
}
}
}
}
fun checkAnnotationName(annotation: AnnotationDescriptor, fqName: FqName): Boolean {
return annotation.annotationClass?.fqNameUnsafe == fqName.toUnsafe()
}
class FilteredAnnotations(
private val delegate: Annotations,
private val fqNameFilter: (FqName) -> Boolean
@@ -107,8 +98,8 @@ class FilteredAnnotations(
override fun isEmpty() = delegate.any(this::shouldBeReturned)
private fun shouldBeReturned(annotation: AnnotationDescriptor): Boolean =
annotation.annotationClass?.fqNameUnsafe.let { fqName ->
fqName != null && fqName.isSafe && fqNameFilter(fqName.toSafe())
annotation.fqName.let { fqName ->
fqName != null && fqNameFilter(fqName)
}
}
@@ -17,8 +17,6 @@
package org.jetbrains.kotlin.descriptors.annotations
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
class AnnotationsImpl : Annotations {
private val annotations: List<AnnotationDescriptor>
@@ -40,10 +38,7 @@ class AnnotationsImpl : Annotations {
override fun isEmpty() = targetedAnnotations.isEmpty()
override fun findAnnotation(fqName: FqName) = annotations.firstOrNull {
val descriptor = it.annotationClass
descriptor != null && fqName.toUnsafe() == DescriptorUtils.getFqName(descriptor)
}
override fun findAnnotation(fqName: FqName) = annotations.firstOrNull { it.fqName == fqName }
override fun getUseSiteTargetedAnnotations(): List<AnnotationWithTarget> {
return targetedAnnotations
@@ -31,7 +31,6 @@ import org.jetbrains.kotlin.resolve.constants.AnnotationValue
import org.jetbrains.kotlin.resolve.constants.ArrayValue
import org.jetbrains.kotlin.resolve.constants.ConstantValue
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.types.*
import org.jetbrains.kotlin.types.ErrorUtils.UninferredParameterTypeConstructor
@@ -398,15 +397,8 @@ internal class DescriptorRendererImpl(
val excluded = if (annotated is KotlinType) excludedTypeAnnotationClasses else excludedAnnotationClasses
// Sort is needed just to fix some order when annotations resolved from modifiers
// See AnnotationResolver.resolveAndAppendAnnotationsFromModifiers for clarification
// This hack can be removed when modifiers will be resolved without annotations
val sortedAnnotations = annotated.annotations.getAllAnnotations()
for ((annotation, target) in sortedAnnotations) {
val annotationClass = annotation.annotationClass!!
if (!excluded.contains(DescriptorUtils.getFqNameSafe(annotationClass))) {
for ((annotation, target) in annotated.annotations.getAllAnnotations()) {
if (annotation.fqName !in excluded) {
append(renderAnnotation(annotation, target)).append(" ")
}
}
@@ -20,8 +20,6 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.storage.getValue
@@ -33,8 +31,7 @@ open class DeserializedAnnotations(
override fun isEmpty(): Boolean = annotations.isEmpty()
override fun findAnnotation(fqName: FqName) =
annotations.firstOrNull { annotation -> annotation.annotationClass?.fqNameUnsafe == fqName.toUnsafe() }
override fun findAnnotation(fqName: FqName) = annotations.firstOrNull { it.fqName == fqName }
override fun getUseSiteTargetedAnnotations(): List<AnnotationWithTarget> = emptyList()
@@ -59,9 +56,7 @@ open class DeserializedAnnotationsWithPossibleTargets(
override fun isEmpty(): Boolean = annotations.isEmpty()
override fun findAnnotation(fqName: FqName): AnnotationDescriptor? =
annotations.firstOrNull { (annotation, target) ->
target == null && annotation.annotationClass?.fqNameUnsafe == fqName.toUnsafe()
}?.annotation
annotations.firstOrNull { (annotation, target) -> target == null && annotation.fqName == fqName }?.annotation
override fun getUseSiteTargetedAnnotations(): List<AnnotationWithTarget> = annotations.filter { it.target != null }