From 4626b19fceec34a46d5a5df56df670c611ea9d7d Mon Sep 17 00:00:00 2001 From: Dmitrii Gridin Date: Wed, 4 Jan 2023 20:59:49 +0100 Subject: [PATCH] [AA] KtAnnotated: introduce more flexible search API --- .../annotations/KtFe10AnnotationsList.kt | 11 ++++++++--- .../KtFirAnnotationListForDeclaration.kt | 14 ++++++++++---- .../KtFirAnnotationListForReceiverParameter.kt | 14 +++++++++++--- .../fir/annotations/KtFirAnnotationListForType.kt | 14 ++++++++++---- .../base/annotations/KtEmptyAnnotationsList.kt | 9 +++++++-- .../analysis/api/annotations/KtAnnotated.kt | 10 +++++++--- .../analysis/api/annotations/KtAnnotationsList.kt | 15 ++++++++++++--- 7 files changed, 65 insertions(+), 22 deletions(-) diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/annotations/KtFe10AnnotationsList.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/annotations/KtFe10AnnotationsList.kt index 63bc90a7abe..cd769b24d7f 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/annotations/KtFe10AnnotationsList.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/annotations/KtFe10AnnotationsList.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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. */ @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.bas 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.descriptors.annotations.Annotations import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass @@ -44,8 +45,12 @@ internal class KtFe10AnnotationsList private constructor( } } - override fun hasAnnotation(classId: ClassId): Boolean = withValidityAssertion { - return fe10Annotations.hasAnnotation(classId.asSingleFqName()) + override fun hasAnnotation( + classId: ClassId, + useSiteTarget: AnnotationUseSiteTarget?, + strictUseSite: Boolean, + ): Boolean = withValidityAssertion { + fe10Annotations.hasAnnotation(classId.asSingleFqName()) } override fun annotationsByClassId(classId: ClassId): List = withValidityAssertion { diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/KtFirAnnotationListForDeclaration.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/KtFirAnnotationListForDeclaration.kt index 8c274cc23f9..8b67b0bbcaa 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/KtFirAnnotationListForDeclaration.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/KtFirAnnotationListForDeclaration.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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. */ @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.analysis.api.fir.toKtAnnotationApplication 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.fullyExpandedClassId import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol @@ -29,9 +30,14 @@ internal class KtFirAnnotationListForDeclaration private constructor( } } - - override fun hasAnnotation(classId: ClassId): Boolean = withValidityAssertion { - firSymbol.resolvedAnnotationClassIds.contains(classId) + override fun hasAnnotation( + classId: ClassId, + useSiteTarget: AnnotationUseSiteTarget?, + strictUseSite: Boolean, + ): Boolean = withValidityAssertion { + firSymbol.resolvedAnnotationsWithClassIds.any { + (it.useSiteTarget == useSiteTarget || !strictUseSite && it.useSiteTarget == null) && it.fullyExpandedClassId(useSiteSession) == classId + } } override fun annotationsByClassId(classId: ClassId): List = withValidityAssertion { diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/KtFirAnnotationListForReceiverParameter.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/KtFirAnnotationListForReceiverParameter.kt index 8f41619a5d8..bcc2f91e71d 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/KtFirAnnotationListForReceiverParameter.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/KtFirAnnotationListForReceiverParameter.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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. */ @@ -11,12 +11,14 @@ import org.jetbrains.kotlin.analysis.api.fir.toKtAnnotationApplication 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.declarations.fullyExpandedClassId import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.resolvedAnnotationClassIds import org.jetbrains.kotlin.fir.symbols.resolvedAnnotationsWithArguments +import org.jetbrains.kotlin.fir.symbols.resolvedAnnotationsWithClassIds import org.jetbrains.kotlin.name.ClassId internal class KtFirAnnotationListForReceiverParameter private constructor( @@ -33,8 +35,14 @@ internal class KtFirAnnotationListForReceiverParameter private constructor( } } - override fun hasAnnotation(classId: ClassId): Boolean = withValidityAssertion { - classId in receiverParameter.resolvedAnnotationClassIds(firCallableSymbol) + override fun hasAnnotation( + classId: ClassId, + useSiteTarget: AnnotationUseSiteTarget?, + strictUseSite: Boolean, + ): Boolean = withValidityAssertion { + receiverParameter.resolvedAnnotationsWithClassIds(firCallableSymbol).any { + (it.useSiteTarget == useSiteTarget || !strictUseSite && it.useSiteTarget == null) && it.fullyExpandedClassId(useSiteSession) == classId + } } override fun annotationsByClassId(classId: ClassId): List = withValidityAssertion { diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/KtFirAnnotationListForType.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/KtFirAnnotationListForType.kt index edca47c828a..566bc35e2f9 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/KtFirAnnotationListForType.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/KtFirAnnotationListForType.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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. */ @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.analysis.api.fir.toKtAnnotationApplication 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.fullyExpandedClassId import org.jetbrains.kotlin.fir.types.ConeKotlinType @@ -25,9 +26,14 @@ internal class KtFirAnnotationListForType private constructor( override val annotations: List get() = withValidityAssertion { coneType.customAnnotations.map { it.toKtAnnotationApplication(useSiteSession) } } - - override fun hasAnnotation(classId: ClassId): Boolean = withValidityAssertion { - coneType.customAnnotations.any { it.fullyExpandedClassId(useSiteSession) == classId } + override fun hasAnnotation( + classId: ClassId, + useSiteTarget: AnnotationUseSiteTarget?, + strictUseSite: Boolean, + ): Boolean = withValidityAssertion { + coneType.customAnnotations.any { + (it.useSiteTarget == useSiteTarget || !strictUseSite && it.useSiteTarget == null) && it.fullyExpandedClassId(useSiteSession) == classId + } } override fun annotationsByClassId(classId: ClassId): List = withValidityAssertion { diff --git a/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/annotations/KtEmptyAnnotationsList.kt b/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/annotations/KtEmptyAnnotationsList.kt index 769a20e2e10..0b6d17c49b1 100644 --- a/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/annotations/KtEmptyAnnotationsList.kt +++ b/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/annotations/KtEmptyAnnotationsList.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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. */ @@ -9,13 +9,18 @@ import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplication import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList 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.name.ClassId class KtEmptyAnnotationsList(override val token: KtLifetimeToken) : KtAnnotationsList() { override val annotations: List get() = withValidityAssertion { emptyList() } - override fun hasAnnotation(classId: ClassId): Boolean = withValidityAssertion { false } + override fun hasAnnotation( + classId: ClassId, + useSiteTarget: AnnotationUseSiteTarget?, + strictUseSite: Boolean, + ): Boolean = withValidityAssertion { false } override fun annotationsByClassId(classId: ClassId): List = withValidityAssertion { emptyList() } diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/annotations/KtAnnotated.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/annotations/KtAnnotated.kt index 002c07e2c47..5cdcc93744e 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/annotations/KtAnnotated.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/annotations/KtAnnotated.kt @@ -1,10 +1,11 @@ /* - * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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 import org.jetbrains.kotlin.name.ClassId /** @@ -27,8 +28,11 @@ public val KtAnnotated.annotations: List * * @see [KtAnnotationsList.hasAnnotation] */ -public fun KtAnnotated.hasAnnotation(classId: ClassId): Boolean = - annotationsList.hasAnnotation(classId) +public fun KtAnnotated.hasAnnotation( + classId: ClassId, + useSiteTarget: AnnotationUseSiteTarget? = null, + strictUseSite: Boolean = true, +): Boolean = annotationsList.hasAnnotation(classId, useSiteTarget, strictUseSite) /** * A list of annotations applied with specified [classId]. diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/annotations/KtAnnotationsList.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/annotations/KtAnnotationsList.kt index c25c5d28cc7..90f4ab67919 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/annotations/KtAnnotationsList.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/annotations/KtAnnotationsList.kt @@ -1,11 +1,12 @@ /* - * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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.analysis.api.lifetime.KtLifetimeOwner +import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.name.ClassId /** @@ -28,10 +29,18 @@ public abstract class KtAnnotationsList : KtLifetimeOwner { * * The semantic is equivalent to * ``` - * annotationsList.containsAnnotation(classId) == annotationsList.annotations.any { it.classId == classId } + * annotationsList.hasAnnotation(classId) == annotationsList.annotations.any { it.classId == classId } + * + * annotationsList.hasAnnotation(classId, useSiteTarget, strictUseSite) == annotationsList.annotations.any { + * (it.useSiteTarget == useSiteTarget || !strictUseSite && it.useSiteTarget == null) && it.classId == classId + * } * ``` */ - public abstract fun hasAnnotation(classId: ClassId): Boolean + public abstract fun hasAnnotation( + classId: ClassId, + useSiteTarget: AnnotationUseSiteTarget? = null, + strictUseSite: Boolean = true, + ): Boolean /** * A list of annotations applied with specified [classId].