[AA] introduce AnnotationUseSiteTargetFilter to simplify API

^KT-56046
This commit is contained in:
Dmitrii Gridin
2023-01-27 21:05:51 +01:00
committed by Space Team
parent 6e25b45f7d
commit 93232a23df
31 changed files with 325 additions and 249 deletions
@@ -0,0 +1,71 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.analysis.api.annotations
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
public fun interface AnnotationUseSiteTargetFilter {
public fun isAllowed(useSiteTarget: AnnotationUseSiteTarget?): Boolean
}
public fun AnnotationUseSiteTarget?.toFilter(): AnnotationUseSiteTargetFilter = when (this) {
null -> NullAnnotationUseSiteTargetFilter
AnnotationUseSiteTarget.FIELD -> FieldAnnotationUseSiteTargetFilter
AnnotationUseSiteTarget.FILE -> FileAnnotationUseSiteTargetFilter
AnnotationUseSiteTarget.PROPERTY -> PropertyAnnotationUseSiteTargetFilter
AnnotationUseSiteTarget.PROPERTY_GETTER -> PropertyGetterAnnotationUseSiteTargetFilter
AnnotationUseSiteTarget.PROPERTY_SETTER -> PropertySetterAnnotationUseSiteTargetFilter
AnnotationUseSiteTarget.RECEIVER -> ReceiverAnnotationUseSiteTargetFilter
AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER -> ConstructorParameterAnnotationUseSiteTargetFilter
AnnotationUseSiteTarget.SETTER_PARAMETER -> SetterParameterAnnotationUseSiteTargetFilter
AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD -> PropertyDelegateFieldAnnotationUseSiteTargetFilter
}
public object AnyAnnotationUseSiteTargetFilter : AnnotationUseSiteTargetFilter {
override fun isAllowed(useSiteTarget: AnnotationUseSiteTarget?): Boolean = true
}
public object NullAnnotationUseSiteTargetFilter : AnnotationUseSiteTargetFilter {
override fun isAllowed(useSiteTarget: AnnotationUseSiteTarget?): Boolean = useSiteTarget == null
}
public object FieldAnnotationUseSiteTargetFilter : AnnotationUseSiteTargetFilter {
override fun isAllowed(useSiteTarget: AnnotationUseSiteTarget?): Boolean = useSiteTarget == AnnotationUseSiteTarget.FIELD
}
public object FileAnnotationUseSiteTargetFilter : AnnotationUseSiteTargetFilter {
override fun isAllowed(useSiteTarget: AnnotationUseSiteTarget?): Boolean = useSiteTarget == AnnotationUseSiteTarget.FILE
}
public object PropertyAnnotationUseSiteTargetFilter : AnnotationUseSiteTargetFilter {
override fun isAllowed(useSiteTarget: AnnotationUseSiteTarget?): Boolean = useSiteTarget == AnnotationUseSiteTarget.PROPERTY
}
public object PropertyGetterAnnotationUseSiteTargetFilter : AnnotationUseSiteTargetFilter {
override fun isAllowed(useSiteTarget: AnnotationUseSiteTarget?): Boolean = useSiteTarget == AnnotationUseSiteTarget.PROPERTY_GETTER
}
public object PropertySetterAnnotationUseSiteTargetFilter : AnnotationUseSiteTargetFilter {
override fun isAllowed(useSiteTarget: AnnotationUseSiteTarget?): Boolean = useSiteTarget == AnnotationUseSiteTarget.PROPERTY_SETTER
}
public object ReceiverAnnotationUseSiteTargetFilter : AnnotationUseSiteTargetFilter {
override fun isAllowed(useSiteTarget: AnnotationUseSiteTarget?): Boolean = useSiteTarget == AnnotationUseSiteTarget.RECEIVER
}
public object ConstructorParameterAnnotationUseSiteTargetFilter : AnnotationUseSiteTargetFilter {
override fun isAllowed(useSiteTarget: AnnotationUseSiteTarget?): Boolean =
useSiteTarget == AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER
}
public object SetterParameterAnnotationUseSiteTargetFilter : AnnotationUseSiteTargetFilter {
override fun isAllowed(useSiteTarget: AnnotationUseSiteTarget?): Boolean = useSiteTarget == AnnotationUseSiteTarget.SETTER_PARAMETER
}
public object PropertyDelegateFieldAnnotationUseSiteTargetFilter : AnnotationUseSiteTargetFilter {
override fun isAllowed(useSiteTarget: AnnotationUseSiteTarget?): Boolean =
useSiteTarget == AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD
}
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.analysis.api.annotations
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.name.ClassId
/**
@@ -32,30 +31,24 @@ public val KtAnnotated.annotationInfos: List<KtAnnotationApplicationInfo>
get() = annotationsList.annotationInfos
/**
* Checks if entity has annotation with specified [classId].
*
* @see [KtAnnotationsList.hasAnnotation]
*/
public fun KtAnnotated.hasAnnotation(classId: ClassId): Boolean = annotationsList.hasAnnotation(classId)
/**
* Checks if entity has annotation with specified [classId] and [useSiteTarget].
* Checks if entity has annotation with specified [classId] and filtered by [useSiteTargetFilter].
*
* @see [KtAnnotationsList.hasAnnotation]
*/
public fun KtAnnotated.hasAnnotation(
classId: ClassId,
useSiteTarget: AnnotationUseSiteTarget?,
acceptAnnotationsWithoutUseSite: Boolean = false,
): Boolean = annotationsList.hasAnnotation(classId, useSiteTarget, acceptAnnotationsWithoutUseSite)
useSiteTargetFilter: AnnotationUseSiteTargetFilter = AnyAnnotationUseSiteTargetFilter,
): Boolean = annotationsList.hasAnnotation(classId, useSiteTargetFilter)
/**
* A list of annotations applied with specified [classId].
* A list of annotations applied with specified [classId] and filtered by [useSiteTargetFilter].
*
* @see [KtAnnotationsList.annotationClassIds]
*/
public fun KtAnnotated.annotationsByClassId(classId: ClassId): List<KtAnnotationApplicationWithArgumentsInfo> =
annotationsList.annotationsByClassId(classId)
public fun KtAnnotated.annotationsByClassId(
classId: ClassId,
useSiteTargetFilter: AnnotationUseSiteTargetFilter = AnyAnnotationUseSiteTargetFilter,
): List<KtAnnotationApplicationWithArgumentsInfo> = annotationsList.annotationsByClassId(classId, useSiteTargetFilter)
/**
* A list of annotations applied.
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.analysis.api.annotations
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeOwner
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.name.ClassId
/**
@@ -34,49 +33,40 @@ public abstract class KtAnnotationsList : KtLifetimeOwner {
public abstract val annotationInfos: List<KtAnnotationApplicationInfo>
/**
* Checks if entity contains annotation with specified [classId].
* Checks if entity contains annotation with specified [classId] and filtered by [useSiteTargetFilter].
*
* The semantic is equivalent to
* ```
* annotationsList.hasAnnotation(classId) == annotationsList.annotations.any { it.classId == classId }
* ```
*/
public abstract fun hasAnnotation(classId: ClassId): Boolean
/**
* Checks if entity contains annotation with specified [classId] and [useSiteTarget].
* If [useSiteTarget] is **null** [acceptAnnotationsWithoutUseSite] effectively unused.
*
* The semantic is equivalent to
* ```
* annotationsList.hasAnnotation(classId, useSiteTarget, strictUseSite) == annotationsList.annotations.any {
* (it.useSiteTarget == useSiteTarget || acceptAnnotationsWithoutUseSite && it.useSiteTarget == null) && it.classId == classId
* annotationsList.hasAnnotation(classId, useSiteTargetFilter) == annotationsList.annotations.any {
* it.classId == classId && useSiteTargetFilter.isAllowed(it.useSiteTarget)
* }
* ```
*
* @param classId [ClassId] to search
* @param useSiteTarget specific [AnnotationUseSiteTarget]
* @param acceptAnnotationsWithoutUseSite add [ClassId] without specified [AnnotationUseSiteTarget] to search
* @param useSiteTargetFilter specific [AnnotationUseSiteTargetFilter]
*/
public abstract fun hasAnnotation(
classId: ClassId,
useSiteTarget: AnnotationUseSiteTarget?,
acceptAnnotationsWithoutUseSite: Boolean = false,
useSiteTargetFilter: AnnotationUseSiteTargetFilter = AnyAnnotationUseSiteTargetFilter,
): Boolean
/**
* A list of annotations applied with specified [classId].
* A list of annotations applied with specified [classId] and filtered by [useSiteTargetFilter].
*
* To check if annotation is present, please use [hasAnnotation].
*
* The semantic is equivalent to
* ```
* annotationsList.annotationsByClassId(classId) == annotationsList.annotations.filter { it.classId == classId }
* annotationsList.annotationsByClassId(classId) == annotationsList.annotations.filter {
* it.classId == classId && useSiteTargetFilter.isAllowed(it.useSiteTarget)
* }
* ```
*
* @see KtAnnotationApplicationWithArgumentsInfo
*/
public abstract fun annotationsByClassId(classId: ClassId): List<KtAnnotationApplicationWithArgumentsInfo>
public abstract fun annotationsByClassId(
classId: ClassId,
useSiteTargetFilter: AnnotationUseSiteTargetFilter = AnyAnnotationUseSiteTargetFilter,
): List<KtAnnotationApplicationWithArgumentsInfo>
/**
* A list of annotations [ClassId].