[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
@@ -5,13 +5,13 @@
package org.jetbrains.kotlin.analysis.api.fir.annotations
import org.jetbrains.kotlin.analysis.api.annotations.AnnotationUseSiteTargetFilter
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationInfo
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationWithArgumentsInfo
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList
import org.jetbrains.kotlin.analysis.api.impl.base.annotations.KtEmptyAnnotationsList
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.name.ClassId
@@ -31,20 +31,15 @@ internal class KtFirAnnotationListForDeclaration private constructor(
annotationInfos(firSymbol, useSiteSession)
}
override fun hasAnnotation(
override fun hasAnnotation(classId: ClassId, useSiteTargetFilter: AnnotationUseSiteTargetFilter): Boolean = withValidityAssertion {
hasAnnotation(firSymbol, classId, useSiteTargetFilter, useSiteSession)
}
override fun annotationsByClassId(
classId: ClassId,
useSiteTarget: AnnotationUseSiteTarget?,
acceptAnnotationsWithoutUseSite: Boolean,
): Boolean = withValidityAssertion {
hasAnnotation(firSymbol, classId, useSiteSession, useSiteTarget, acceptAnnotationsWithoutUseSite)
}
override fun hasAnnotation(classId: ClassId): Boolean = withValidityAssertion {
hasAnnotation(firSymbol, classId, useSiteSession)
}
override fun annotationsByClassId(classId: ClassId): List<KtAnnotationApplicationWithArgumentsInfo> = withValidityAssertion {
annotationsByClassId(firSymbol, classId, useSiteSession)
useSiteTargetFilter: AnnotationUseSiteTargetFilter,
): List<KtAnnotationApplicationWithArgumentsInfo> = withValidityAssertion {
annotationsByClassId(firSymbol, classId, useSiteTargetFilter, useSiteSession)
}
override val annotationClassIds: Collection<ClassId>
@@ -5,13 +5,13 @@
package org.jetbrains.kotlin.analysis.api.fir.annotations
import org.jetbrains.kotlin.analysis.api.annotations.AnnotationUseSiteTargetFilter
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationInfo
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationWithArgumentsInfo
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList
import org.jetbrains.kotlin.analysis.api.impl.base.annotations.KtEmptyAnnotationsList
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
@@ -33,20 +33,15 @@ internal class KtFirAnnotationListForReceiverParameter private constructor(
annotationInfos(firCallableSymbol, useSiteSession, receiverParameter)
}
override fun hasAnnotation(
override fun hasAnnotation(classId: ClassId, useSiteTargetFilter: AnnotationUseSiteTargetFilter): Boolean = withValidityAssertion {
hasAnnotation(firCallableSymbol, classId, useSiteTargetFilter, useSiteSession, receiverParameter)
}
override fun annotationsByClassId(
classId: ClassId,
useSiteTarget: AnnotationUseSiteTarget?,
acceptAnnotationsWithoutUseSite: Boolean,
): Boolean = withValidityAssertion {
hasAnnotation(firCallableSymbol, classId, useSiteSession, useSiteTarget, acceptAnnotationsWithoutUseSite, receiverParameter)
}
override fun hasAnnotation(classId: ClassId): Boolean = withValidityAssertion {
hasAnnotation(firCallableSymbol, classId, useSiteSession, receiverParameter)
}
override fun annotationsByClassId(classId: ClassId): List<KtAnnotationApplicationWithArgumentsInfo> = withValidityAssertion {
annotationsByClassId(firCallableSymbol, classId, useSiteSession, receiverParameter)
useSiteTargetFilter: AnnotationUseSiteTargetFilter,
): List<KtAnnotationApplicationWithArgumentsInfo> = withValidityAssertion {
annotationsByClassId(firCallableSymbol, classId, useSiteTargetFilter, useSiteSession, receiverParameter)
}
override val annotationClassIds: Collection<ClassId>
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.analysis.api.fir.annotations
import org.jetbrains.kotlin.analysis.api.annotations.AnnotationUseSiteTargetFilter
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationInfo
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationWithArgumentsInfo
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList
@@ -13,10 +14,8 @@ import org.jetbrains.kotlin.analysis.api.fir.toKtAnnotationInfo
import org.jetbrains.kotlin.analysis.api.impl.base.annotations.KtEmptyAnnotationsList
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.hasAnnotation
import org.jetbrains.kotlin.fir.declarations.toAnnotationClassId
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.symbols.resolvedAnnotationsWithArguments
@@ -45,24 +44,21 @@ internal class KtFirAnnotationListForType private constructor(
}
}
override fun hasAnnotation(
classId: ClassId,
useSiteTarget: AnnotationUseSiteTarget?,
acceptAnnotationsWithoutUseSite: Boolean,
): Boolean = withValidityAssertion {
override fun hasAnnotation(classId: ClassId, useSiteTargetFilter: AnnotationUseSiteTargetFilter): Boolean = withValidityAssertion {
coneType.customAnnotationsWithLazyResolve(FirResolvePhase.TYPES).any {
(it.useSiteTarget == useSiteTarget || acceptAnnotationsWithoutUseSite && it.useSiteTarget == null) &&
it.toAnnotationClassId(useSiteSession) == classId
useSiteTargetFilter.isAllowed(it.useSiteTarget) && it.toAnnotationClassId(useSiteSession) == classId
}
}
override fun hasAnnotation(classId: ClassId): Boolean = withValidityAssertion {
coneType.customAnnotationsWithLazyResolve(FirResolvePhase.TYPES).hasAnnotation(classId, useSiteSession)
}
override fun annotationsByClassId(classId: ClassId): List<KtAnnotationApplicationWithArgumentsInfo> = withValidityAssertion {
override fun annotationsByClassId(
classId: ClassId,
useSiteTargetFilter: AnnotationUseSiteTargetFilter,
): List<KtAnnotationApplicationWithArgumentsInfo> = withValidityAssertion {
coneType.customAnnotationsWithLazyResolve(FirResolvePhase.ANNOTATIONS_ARGUMENTS_MAPPING).mapIndexedNotNull { index, annotation ->
if (annotation.toAnnotationClassId(useSiteSession) != classId) return@mapIndexedNotNull null
if (!useSiteTargetFilter.isAllowed(annotation.useSiteTarget) || annotation.toAnnotationClassId(useSiteSession) != classId) {
return@mapIndexedNotNull null
}
annotation.toKtAnnotationApplication(useSiteSession, index)
}
}
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.analysis.api.fir.annotations
import org.jetbrains.kotlin.analysis.api.annotations.AnnotationUseSiteTargetFilter
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationInfo
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationWithArgumentsInfo
import org.jetbrains.kotlin.analysis.api.fir.toKtAnnotationApplication
@@ -12,10 +13,12 @@ import org.jetbrains.kotlin.analysis.api.fir.toKtAnnotationInfo
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirEntry
import org.jetbrains.kotlin.analysis.utils.errors.checkWithAttachmentBuilder
import org.jetbrains.kotlin.analysis.utils.errors.withClassEntry
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.resolved
import org.jetbrains.kotlin.fir.declarations.toAnnotationClassId
import org.jetbrains.kotlin.fir.declarations.toAnnotationClassIdSafe
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirExpression
@@ -43,17 +46,24 @@ internal fun mapAnnotationParameters(annotation: FirAnnotation): Map<Name, FirEx
internal fun annotationsByClassId(
firSymbol: FirBasedSymbol<*>,
classId: ClassId,
useSiteTargetFilter: AnnotationUseSiteTargetFilter,
useSiteSession: FirSession,
annotationContainer: FirAnnotationContainer = firSymbol.fir,
): List<KtAnnotationApplicationWithArgumentsInfo> =
if (firSymbol.isFromCompilerRequiredAnnotationsPhase(classId)) {
annotationContainer.resolvedCompilerRequiredAnnotations(firSymbol).mapIndexedNotNull { index, annotation ->
if (annotation.toAnnotationClassIdSafe(useSiteSession) != classId) return@mapIndexedNotNull null
if (!useSiteTargetFilter.isAllowed(annotation.useSiteTarget) || annotation.toAnnotationClassIdSafe(useSiteSession) != classId) {
return@mapIndexedNotNull null
}
annotation.toKtAnnotationApplication(useSiteSession, index)
}
} else {
annotationContainer.resolvedAnnotationsWithArguments(firSymbol).mapIndexedNotNull { index, annotation ->
if (annotation.toAnnotationClassId(useSiteSession) != classId) return@mapIndexedNotNull null
if (!useSiteTargetFilter.isAllowed(annotation.useSiteTarget) || annotation.toAnnotationClassId(useSiteSession) != classId) {
return@mapIndexedNotNull null
}
annotation.toKtAnnotationApplication(useSiteSession, index)
}
}
@@ -86,34 +96,19 @@ internal fun annotationClassIds(
internal fun hasAnnotation(
firSymbol: FirBasedSymbol<*>,
classId: ClassId,
useSiteTargetFilter: AnnotationUseSiteTargetFilter,
useSiteSession: FirSession,
useSiteTarget: AnnotationUseSiteTarget?,
acceptAnnotationsWithoutUseSite: Boolean,
annotationContainer: FirAnnotationContainer = firSymbol.fir,
): Boolean =
if (firSymbol.isFromCompilerRequiredAnnotationsPhase(classId)) {
annotationContainer.resolvedCompilerRequiredAnnotations(firSymbol).any {
(it.useSiteTarget == useSiteTarget || acceptAnnotationsWithoutUseSite && it.useSiteTarget == null) &&
it.toAnnotationClassIdSafe(useSiteSession) == classId
useSiteTargetFilter.isAllowed(it.useSiteTarget) && it.toAnnotationClassIdSafe(useSiteSession) == classId
}
} else {
annotationContainer.resolvedAnnotationsWithClassIds(firSymbol).any {
(it.useSiteTarget == useSiteTarget || acceptAnnotationsWithoutUseSite && it.useSiteTarget == null) &&
it.toAnnotationClassId(useSiteSession) == classId
useSiteTargetFilter.isAllowed(it.useSiteTarget) && it.toAnnotationClassId(useSiteSession) == classId
}
}
internal fun hasAnnotation(
firSymbol: FirBasedSymbol<*>,
classId: ClassId,
useSiteSession: FirSession,
annotationContainer: FirAnnotationContainer = firSymbol.fir,
): Boolean =
if (firSymbol.isFromCompilerRequiredAnnotationsPhase(classId)) {
annotationContainer.resolvedCompilerRequiredAnnotations(firSymbol).hasAnnotationSafe(classId, useSiteSession)
} else {
annotationContainer.resolvedAnnotationsWithClassIds(firSymbol).hasAnnotation(classId, useSiteSession)
}
private fun FirBasedSymbol<*>.isFromCompilerRequiredAnnotationsPhase(classId: ClassId): Boolean =
fir.resolvePhase < FirResolvePhase.TYPES && classId in CompilerRequiredAnnotationsHelper.REQUIRED_ANNOTATIONS