From 5a74fec3aceaa06a79b7aeec65a6b5f1b8da0e3b Mon Sep 17 00:00:00 2001 From: Dmitrii Gridin Date: Fri, 6 Jan 2023 16:19:44 +0100 Subject: [PATCH] [AA] KtAnnotated: split hasAnnotation to two extensions --- .../annotations/KtFe10AnnotationsList.kt | 10 ++++--- .../KtFirAnnotationListForDeclaration.kt | 11 +++++-- ...KtFirAnnotationListForReceiverParameter.kt | 11 +++++-- .../annotations/KtFirAnnotationListForType.kt | 11 +++++-- .../annotations/KtEmptyAnnotationsList.kt | 4 ++- .../analysis/api/annotations/KtAnnotated.kt | 13 +++++++-- .../api/annotations/KtAnnotationsList.kt | 19 ++++++++++-- .../annotations/symbolAnnotationsUtils.kt | 29 ++++++++++--------- .../symbol/classes/symbolLightClassUtils.kt | 8 ++--- .../fields/SymbolLightFieldForProperty.kt | 6 ++-- .../methods/SymbolLightAccessorMethod.kt | 12 ++++---- 11 files changed, 90 insertions(+), 44 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 cd769b24d7f..7333edf6d20 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 @@ -45,13 +45,15 @@ internal class KtFe10AnnotationsList private constructor( } } + override fun hasAnnotation(classId: ClassId): Boolean = withValidityAssertion { + fe10Annotations.hasAnnotation(classId.asSingleFqName()) + } + override fun hasAnnotation( classId: ClassId, useSiteTarget: AnnotationUseSiteTarget?, - strictUseSite: Boolean, - ): Boolean = withValidityAssertion { - fe10Annotations.hasAnnotation(classId.asSingleFqName()) - } + acceptAnnotationsWithoutUseSite: Boolean, + ): Boolean = hasAnnotation(classId) override fun annotationsByClassId(classId: ClassId): List = withValidityAssertion { if (classId in annotationsToIgnore) return@withValidityAssertion emptyList() 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 8b67b0bbcaa..35aba4ce982 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 @@ -33,10 +33,17 @@ internal class KtFirAnnotationListForDeclaration private constructor( override fun hasAnnotation( classId: ClassId, useSiteTarget: AnnotationUseSiteTarget?, - strictUseSite: Boolean, + acceptAnnotationsWithoutUseSite: Boolean, ): Boolean = withValidityAssertion { firSymbol.resolvedAnnotationsWithClassIds.any { - (it.useSiteTarget == useSiteTarget || !strictUseSite && it.useSiteTarget == null) && it.fullyExpandedClassId(useSiteSession) == classId + (it.useSiteTarget == useSiteTarget || acceptAnnotationsWithoutUseSite && it.useSiteTarget == null) && + it.fullyExpandedClassId(useSiteSession) == classId + } + } + + override fun hasAnnotation(classId: ClassId): Boolean = withValidityAssertion { + firSymbol.resolvedAnnotationsWithClassIds.any { + it.fullyExpandedClassId(useSiteSession) == classId } } 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 bcc2f91e71d..6f4436949a1 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 @@ -38,10 +38,17 @@ internal class KtFirAnnotationListForReceiverParameter private constructor( override fun hasAnnotation( classId: ClassId, useSiteTarget: AnnotationUseSiteTarget?, - strictUseSite: Boolean, + acceptAnnotationsWithoutUseSite: Boolean, ): Boolean = withValidityAssertion { receiverParameter.resolvedAnnotationsWithClassIds(firCallableSymbol).any { - (it.useSiteTarget == useSiteTarget || !strictUseSite && it.useSiteTarget == null) && it.fullyExpandedClassId(useSiteSession) == classId + (it.useSiteTarget == useSiteTarget || acceptAnnotationsWithoutUseSite && it.useSiteTarget == null) && + it.fullyExpandedClassId(useSiteSession) == classId + } + } + + override fun hasAnnotation(classId: ClassId): Boolean = withValidityAssertion { + receiverParameter.resolvedAnnotationsWithClassIds(firCallableSymbol).any { + it.fullyExpandedClassId(useSiteSession) == classId } } 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 566bc35e2f9..70220951247 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 @@ -29,10 +29,17 @@ internal class KtFirAnnotationListForType private constructor( override fun hasAnnotation( classId: ClassId, useSiteTarget: AnnotationUseSiteTarget?, - strictUseSite: Boolean, + acceptAnnotationsWithoutUseSite: Boolean, ): Boolean = withValidityAssertion { coneType.customAnnotations.any { - (it.useSiteTarget == useSiteTarget || !strictUseSite && it.useSiteTarget == null) && it.fullyExpandedClassId(useSiteSession) == classId + (it.useSiteTarget == useSiteTarget || acceptAnnotationsWithoutUseSite && it.useSiteTarget == null) && + it.fullyExpandedClassId(useSiteSession) == classId + } + } + + override fun hasAnnotation(classId: ClassId): Boolean = withValidityAssertion { + coneType.customAnnotations.any { + it.fullyExpandedClassId(useSiteSession) == classId } } 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 0b6d17c49b1..53add953488 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 @@ -19,9 +19,11 @@ class KtEmptyAnnotationsList(override val token: KtLifetimeToken) : KtAnnotation override fun hasAnnotation( classId: ClassId, useSiteTarget: AnnotationUseSiteTarget?, - strictUseSite: Boolean, + acceptAnnotationsWithoutUseSite: Boolean, ): Boolean = withValidityAssertion { false } + override fun hasAnnotation(classId: ClassId): 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 5cdcc93744e..b27ccd2c75d 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 @@ -28,11 +28,18 @@ public val KtAnnotated.annotations: List * * @see [KtAnnotationsList.hasAnnotation] */ +public fun KtAnnotated.hasAnnotation(classId: ClassId): Boolean = annotationsList.hasAnnotation(classId) + +/** + * Checks if entity has annotation with specified [classId] and [useSiteTarget]. + * + * @see [KtAnnotationsList.hasAnnotation] + */ public fun KtAnnotated.hasAnnotation( classId: ClassId, - useSiteTarget: AnnotationUseSiteTarget? = null, - strictUseSite: Boolean = true, -): Boolean = annotationsList.hasAnnotation(classId, useSiteTarget, strictUseSite) + useSiteTarget: AnnotationUseSiteTarget?, + acceptAnnotationsWithoutUseSite: Boolean = false, +): Boolean = annotationsList.hasAnnotation(classId, useSiteTarget, acceptAnnotationsWithoutUseSite) /** * 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 90f4ab67919..2fbdccc11bc 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 @@ -30,16 +30,29 @@ public abstract class KtAnnotationsList : KtLifetimeOwner { * 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 || !strictUseSite && it.useSiteTarget == null) && it.classId == classId + * (it.useSiteTarget == useSiteTarget || acceptAnnotationsWithoutUseSite && it.useSiteTarget == null) && it.classId == classId * } * ``` + * + * @param classId [ClassId] to search + * @param useSiteTarget specific [AnnotationUseSiteTarget] + * @param acceptAnnotationsWithoutUseSite add [ClassId] without specified [AnnotationUseSiteTarget] to search */ public abstract fun hasAnnotation( classId: ClassId, - useSiteTarget: AnnotationUseSiteTarget? = null, - strictUseSite: Boolean = true, + useSiteTarget: AnnotationUseSiteTarget?, + acceptAnnotationsWithoutUseSite: Boolean = false, ): Boolean /** diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/symbolAnnotationsUtils.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/symbolAnnotationsUtils.kt index 6db06abf13f..4bff7e85bca 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/symbolAnnotationsUtils.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/symbolAnnotationsUtils.kt @@ -36,11 +36,11 @@ import java.lang.annotation.ElementType internal fun KtAnnotatedSymbol.hasJvmSyntheticAnnotation( annotationUseSiteTarget: AnnotationUseSiteTarget? = null, - strictUseSite: Boolean = true, -): Boolean = hasAnnotation(JVM_SYNTHETIC_ANNOTATION_CLASS_ID, annotationUseSiteTarget, strictUseSite) + acceptAnnotationsWithoutUseSite: Boolean = false, +): Boolean = hasAnnotation(JVM_SYNTHETIC_ANNOTATION_CLASS_ID, annotationUseSiteTarget, acceptAnnotationsWithoutUseSite) internal fun KtAnnotatedSymbol.getJvmNameFromAnnotation(annotationUseSiteTarget: AnnotationUseSiteTarget? = null): String? { - val annotation = findAnnotation(StandardClassIds.Annotations.JvmName, annotationUseSiteTarget, strictUseSite = false) + val annotation = findAnnotation(StandardClassIds.Annotations.JvmName, annotationUseSiteTarget, acceptAnnotationsWithoutUseSite = true) return annotation?.let { (it.arguments.firstOrNull()?.expression as? KtConstantAnnotationValue)?.constantValue?.value as? String } @@ -55,8 +55,9 @@ internal fun isHiddenByDeprecation( context(KtAnalysisSession) internal fun KtAnnotatedSymbol.isHiddenOrSynthetic( annotationUseSiteTarget: AnnotationUseSiteTarget? = null, - strictUseSite: Boolean = true, -) = isHiddenByDeprecation(this, annotationUseSiteTarget) || hasJvmSyntheticAnnotation(annotationUseSiteTarget, strictUseSite) + acceptAnnotationsWithoutUseSite: Boolean = false, +) = isHiddenByDeprecation(this, annotationUseSiteTarget) || + hasJvmSyntheticAnnotation(annotationUseSiteTarget, acceptAnnotationsWithoutUseSite) internal fun KtAnnotatedSymbol.hasJvmFieldAnnotation(): Boolean = hasAnnotation(StandardClassIds.Annotations.JvmField) @@ -65,28 +66,28 @@ internal fun KtAnnotatedSymbol.hasPublishedApiAnnotation(annotationUseSiteTarget internal fun KtAnnotatedSymbol.hasDeprecatedAnnotation( annotationUseSiteTarget: AnnotationUseSiteTarget? = null, - strictUseSite: Boolean = true, -): Boolean = hasAnnotation(StandardClassIds.Annotations.Deprecated, annotationUseSiteTarget, strictUseSite) + acceptAnnotationsWithoutUseSite: Boolean = false, +): Boolean = hasAnnotation(StandardClassIds.Annotations.Deprecated, annotationUseSiteTarget, acceptAnnotationsWithoutUseSite) internal fun KtAnnotatedSymbol.hasJvmOverloadsAnnotation(): Boolean = hasAnnotation(JVM_OVERLOADS_CLASS_ID) internal fun KtAnnotatedSymbol.hasJvmStaticAnnotation( annotationUseSiteTarget: AnnotationUseSiteTarget? = null, - strictUseSite: Boolean = true, -): Boolean = hasAnnotation(StandardClassIds.Annotations.JvmStatic, annotationUseSiteTarget, strictUseSite) + acceptAnnotationsWithoutUseSite: Boolean = false, +): Boolean = hasAnnotation(StandardClassIds.Annotations.JvmStatic, annotationUseSiteTarget, acceptAnnotationsWithoutUseSite) internal fun KtAnnotatedSymbol.hasInlineOnlyAnnotation(): Boolean = hasAnnotation(StandardClassIds.Annotations.InlineOnly) internal fun KtAnnotatedSymbol.findAnnotation( classId: ClassId, annotationUseSiteTarget: AnnotationUseSiteTarget?, - strictUseSite: Boolean = true, + acceptAnnotationsWithoutUseSite: Boolean = false, ): KtAnnotationApplication? { - if (!hasAnnotation(classId, annotationUseSiteTarget, strictUseSite)) return null + if (!hasAnnotation(classId, annotationUseSiteTarget, acceptAnnotationsWithoutUseSite)) return null return annotations.find { val useSiteTarget = it.useSiteTarget - (useSiteTarget == annotationUseSiteTarget || !strictUseSite && useSiteTarget == null) && it.classId == classId + (useSiteTarget == annotationUseSiteTarget || acceptAnnotationsWithoutUseSite && useSiteTarget == null) && it.classId == classId } } @@ -291,14 +292,14 @@ internal fun KtAnnotatedSymbol.computeThrowsList( annotationUseSiteTarget: AnnotationUseSiteTarget?, useSitePosition: PsiElement, containingClass: SymbolLightClassBase, - strictUseSite: Boolean = true, + acceptAnnotationsWithoutUseSite: Boolean = false, ) { if (containingClass.isEnum && this is KtFunctionSymbol && name == StandardNames.ENUM_VALUE_OF && isStatic) { builder.addReference(java.lang.IllegalArgumentException::class.qualifiedName) builder.addReference(java.lang.NullPointerException::class.qualifiedName) } - val annoApp = findAnnotation(StandardClassIds.Annotations.Throws, annotationUseSiteTarget, strictUseSite) ?: return + val annoApp = findAnnotation(StandardClassIds.Annotations.Throws, annotationUseSiteTarget, acceptAnnotationsWithoutUseSite) ?: return fun handleAnnotationValue(annotationValue: KtAnnotationValue) = when (annotationValue) { is KtArrayAnnotationValue -> { diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt index 8a5f14eb5fa..f3b0e783977 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt @@ -292,14 +292,14 @@ internal fun SymbolLightClassBase.createPropertyAccessors( fun KtPropertyAccessorSymbol.needToCreateAccessor(siteTarget: AnnotationUseSiteTarget): Boolean { if (onlyJvmStatic && - !hasJvmStaticAnnotation(siteTarget, strictUseSite = false) && - !declaration.hasJvmStaticAnnotation(siteTarget, strictUseSite = false) + !hasJvmStaticAnnotation(siteTarget, acceptAnnotationsWithoutUseSite = true) && + !declaration.hasJvmStaticAnnotation(siteTarget, acceptAnnotationsWithoutUseSite = true) ) return false if (declaration.hasReifiedParameters) return false if (!hasBody && visibility.isPrivateOrPrivateToThis()) return false if (declaration.isHiddenOrSynthetic(siteTarget)) return false - return !isHiddenOrSynthetic(siteTarget, strictUseSite = false) + return !isHiddenOrSynthetic(siteTarget, acceptAnnotationsWithoutUseSite = true) } val originalElement = declaration.sourcePsiSafe() @@ -384,7 +384,7 @@ private fun hasBackingField(property: KtPropertySymbol): Boolean { } if (property.modality == Modality.ABSTRACT || - property.isHiddenOrSynthetic(AnnotationUseSiteTarget.FIELD, strictUseSite = false) + property.isHiddenOrSynthetic(AnnotationUseSiteTarget.FIELD, acceptAnnotationsWithoutUseSite = true) ) return false return hasBackingFieldByPsi ?: property.hasBackingField diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForProperty.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForProperty.kt index d41865ff95f..8beefaf7014 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForProperty.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForProperty.kt @@ -83,7 +83,7 @@ internal class SymbolLightFieldForProperty private constructor( private val _isDeprecated: Boolean by lazyPub { withPropertySymbol { propertySymbol -> - propertySymbol.hasDeprecatedAnnotation(AnnotationUseSiteTarget.FIELD, strictUseSite = false) + propertySymbol.hasDeprecatedAnnotation(AnnotationUseSiteTarget.FIELD, acceptAnnotationsWithoutUseSite = true) } } @@ -115,12 +115,12 @@ internal class SymbolLightFieldForProperty private constructor( } PsiModifier.VOLATILE -> withPropertySymbol { propertySymbol -> - val hasAnnotation = propertySymbol.hasAnnotation(VOLATILE_ANNOTATION_CLASS_ID) + val hasAnnotation = propertySymbol.hasAnnotation(VOLATILE_ANNOTATION_CLASS_ID, null) mapOf(modifier to hasAnnotation) } PsiModifier.TRANSIENT -> withPropertySymbol { propertySymbol -> - val hasAnnotation = propertySymbol.hasAnnotation(TRANSIENT_ANNOTATION_CLASS_ID) + val hasAnnotation = propertySymbol.hasAnnotation(TRANSIENT_ANNOTATION_CLASS_ID, null) mapOf(modifier to hasAnnotation) } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightAccessorMethod.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightAccessorMethod.kt index 76fdae7d189..1d8b9e1792c 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightAccessorMethod.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightAccessorMethod.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. */ @@ -136,7 +136,7 @@ internal class SymbolLightAccessorMethod private constructor( accessorSite, this@SymbolLightAccessorMethod, containingClass, - strictUseSite = false + acceptAnnotationsWithoutUseSite = true, ) } } @@ -197,8 +197,8 @@ internal class SymbolLightAccessorMethod private constructor( private fun isStatic(): Boolean = analyzeForLightClasses(ktModule) { val propertySymbol = propertySymbol() propertySymbol.isStatic || - propertySymbol.hasJvmStaticAnnotation(accessorSite, strictUseSite = false) || - propertyAccessorSymbol().hasJvmStaticAnnotation(accessorSite, strictUseSite = false) + propertySymbol.hasJvmStaticAnnotation(accessorSite, acceptAnnotationsWithoutUseSite = true) || + propertyAccessorSymbol().hasJvmStaticAnnotation(accessorSite, acceptAnnotationsWithoutUseSite = true) } private val _modifierList: PsiModifierList by lazyPub { @@ -215,8 +215,8 @@ internal class SymbolLightAccessorMethod private constructor( private val _isDeprecated: Boolean by lazyPub { analyzeForLightClasses(ktModule) { - propertySymbol().hasDeprecatedAnnotation(accessorSite, strictUseSite = false) || - propertyAccessorSymbol().hasDeprecatedAnnotation(accessorSite, strictUseSite = false) + propertySymbol().hasDeprecatedAnnotation(accessorSite, acceptAnnotationsWithoutUseSite = true) || + propertyAccessorSymbol().hasDeprecatedAnnotation(accessorSite, acceptAnnotationsWithoutUseSite = true) } }