[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,6 +5,7 @@
package org.jetbrains.kotlin.analysis.api.descriptors.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
@@ -12,10 +13,10 @@ import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.maybeLocalClassId
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtAnnotationApplication
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtAnnotationInfo
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.useSiteTarget
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
@@ -63,21 +64,21 @@ internal class KtFe10AnnotationsList private constructor(
}
}
override fun hasAnnotation(classId: ClassId): Boolean = withValidityAssertion {
override fun hasAnnotation(classId: ClassId, useSiteTargetFilter: AnnotationUseSiteTargetFilter): Boolean = withValidityAssertion {
fe10Annotations.hasAnnotation(classId.asSingleFqName())
}
override fun hasAnnotation(
override fun annotationsByClassId(
classId: ClassId,
useSiteTarget: AnnotationUseSiteTarget?,
acceptAnnotationsWithoutUseSite: Boolean,
): Boolean = hasAnnotation(classId)
override fun annotationsByClassId(classId: ClassId): List<KtAnnotationApplicationWithArgumentsInfo> = withValidityAssertion {
useSiteTargetFilter: AnnotationUseSiteTargetFilter,
): List<KtAnnotationApplicationWithArgumentsInfo> = withValidityAssertion {
if (classId in annotationsToIgnore) return@withValidityAssertion emptyList()
fe10Annotations.mapIndexedNotNull { index, annotation ->
if (annotation.annotationClass?.maybeLocalClassId != classId) return@mapIndexedNotNull null
if (!useSiteTargetFilter.isAllowed(annotation.useSiteTarget) || annotation.annotationClass?.maybeLocalClassId != classId) {
return@mapIndexedNotNull null
}
annotation.toKtAnnotationApplication(analysisContext, index)
}
}
@@ -630,7 +630,7 @@ internal fun AnnotationDescriptor.toKtAnnotationInfo(index: Int): KtAnnotationAp
private val AnnotationDescriptor.psi: KtCallElement? get() = (source as? PsiSourceElement)?.psi as? KtCallElement
private val AnnotationDescriptor.classIdIfNonLocal: ClassId? get() = annotationClass?.maybeLocalClassId
private val AnnotationDescriptor.useSiteTarget: AnnotationUseSiteTarget?
internal val AnnotationDescriptor.useSiteTarget: AnnotationUseSiteTarget?
get() = (this as? LazyAnnotationDescriptor)?.annotationEntry?.useSiteTarget?.getAnnotationUseSiteTarget()
internal fun AnnotationDescriptor.getKtNamedAnnotationArguments(analysisContext: Fe10AnalysisContext): List<KtNamedAnnotationValue> =
@@ -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
@@ -5,12 +5,12 @@
package org.jetbrains.kotlin.analysis.api.impl.base.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.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() {
@@ -20,15 +20,13 @@ class KtEmptyAnnotationsList(override val token: KtLifetimeToken) : KtAnnotation
override fun hasAnnotation(
classId: ClassId,
useSiteTarget: AnnotationUseSiteTarget?,
acceptAnnotationsWithoutUseSite: Boolean,
useSiteTargetFilter: AnnotationUseSiteTargetFilter,
): Boolean = withValidityAssertion { false }
override fun hasAnnotation(classId: ClassId): Boolean = withValidityAssertion { false }
override fun annotationsByClassId(classId: ClassId): List<KtAnnotationApplicationWithArgumentsInfo> = withValidityAssertion {
emptyList()
}
override fun annotationsByClassId(
classId: ClassId,
useSiteTargetFilter: AnnotationUseSiteTargetFilter,
): List<KtAnnotationApplicationWithArgumentsInfo> = withValidityAssertion { emptyList() }
override val annotationClassIds: Collection<ClassId> get() = withValidityAssertion { emptyList() }
}
@@ -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].
@@ -11,40 +11,35 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtClassLikeSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtAnnotatedSymbol
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.light.classes.symbol.withSymbol
import org.jetbrains.kotlin.name.ClassId
internal class SymbolAnnotationsProvider<T : KtAnnotatedSymbol>(
private val ktModule: KtModule,
private val annotatedSymbolPointer: KtSymbolPointer<T>,
private val annotationUseSiteTarget: AnnotationUseSiteTarget? = null,
private val acceptAnnotationsWithoutSite: Boolean = false,
private val annotationUseSiteTargetFilter: AnnotationUseSiteTargetFilter = AnyAnnotationUseSiteTargetFilter,
) : AnnotationsProvider {
private inline fun <T> withAnnotatedSymbol(crossinline action: context(KtAnalysisSession) (KtAnnotatedSymbol) -> T): T =
annotatedSymbolPointer.withSymbol(ktModule, action)
override fun annotationInfos(): List<KtAnnotationApplicationInfo> = withAnnotatedSymbol { annotatedSymbol ->
annotatedSymbol.annotationInfos.filter {
it.useSiteTarget == annotationUseSiteTarget || acceptAnnotationsWithoutSite && it.useSiteTarget == null
annotationUseSiteTargetFilter.isAllowed(it.useSiteTarget)
}
}
override fun get(classId: ClassId): Collection<KtAnnotationApplicationWithArgumentsInfo> = withAnnotatedSymbol { annotatedSymbol ->
annotatedSymbol.annotationsByClassId(classId).filter {
it.useSiteTarget == annotationUseSiteTarget || acceptAnnotationsWithoutSite && it.useSiteTarget == null
}
annotatedSymbol.annotationsByClassId(classId, annotationUseSiteTargetFilter)
}
override fun contains(classId: ClassId): Boolean = withAnnotatedSymbol { annotatedSymbol ->
annotatedSymbol.hasAnnotation(classId, annotationUseSiteTarget, acceptAnnotationsWithoutSite)
annotatedSymbol.hasAnnotation(classId, annotationUseSiteTargetFilter)
}
override fun isTheSameAs(other: Any?): Boolean = other === this ||
other is SymbolAnnotationsProvider<*> &&
other.ktModule == ktModule &&
other.annotationUseSiteTarget == annotationUseSiteTarget &&
other.acceptAnnotationsWithoutSite == acceptAnnotationsWithoutSite &&
other.annotationUseSiteTargetFilter == annotationUseSiteTargetFilter &&
annotatedSymbolPointer.pointsToTheSameSymbolAs(other.annotatedSymbolPointer)
override fun ownerClassId(): ClassId? = withAnnotatedSymbol { annotatedSymbol ->
@@ -24,13 +24,26 @@ import org.jetbrains.kotlin.name.JvmNames.JVM_SYNTHETIC_ANNOTATION_CLASS_ID
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue
internal fun KtAnnotatedSymbol.hasJvmSyntheticAnnotation(
annotationUseSiteTarget: AnnotationUseSiteTarget? = null,
acceptAnnotationsWithoutUseSite: Boolean = false,
): Boolean = hasAnnotation(JVM_SYNTHETIC_ANNOTATION_CLASS_ID, annotationUseSiteTarget, acceptAnnotationsWithoutUseSite)
internal fun AnnotationUseSiteTarget?.toFilterWithAdditionalNull(): AnnotationUseSiteTargetFilter {
if (this == null) return NullAnnotationUseSiteTargetFilter
internal fun KtAnnotatedSymbol.getJvmNameFromAnnotation(annotationUseSiteTarget: AnnotationUseSiteTarget? = null): String? {
val annotation = findAnnotation(StandardClassIds.Annotations.JvmName, annotationUseSiteTarget, acceptAnnotationsWithoutUseSite = true)
return annotationUseSiteTargetFilterOf(NullAnnotationUseSiteTargetFilter, toFilter())
}
internal fun annotationUseSiteTargetFilterOf(
vararg filters: AnnotationUseSiteTargetFilter,
): AnnotationUseSiteTargetFilter = AnnotationUseSiteTargetFilter { useSiteTarget ->
filters.any { filter -> filter.isAllowed(useSiteTarget) }
}
internal fun KtAnnotatedSymbol.hasJvmSyntheticAnnotation(
useSiteTargetFilter: AnnotationUseSiteTargetFilter = AnyAnnotationUseSiteTargetFilter,
): Boolean = hasAnnotation(JVM_SYNTHETIC_ANNOTATION_CLASS_ID, useSiteTargetFilter)
internal fun KtAnnotatedSymbol.getJvmNameFromAnnotation(
useSiteTargetFilter: AnnotationUseSiteTargetFilter = AnyAnnotationUseSiteTargetFilter,
): String? {
val annotation = findAnnotation(StandardClassIds.Annotations.JvmName, useSiteTargetFilter)
return annotation?.let {
(it.arguments.firstOrNull()?.expression as? KtConstantAnnotationValue)?.constantValue?.value as? String
}
@@ -45,56 +58,49 @@ internal fun isHiddenByDeprecation(
context(KtAnalysisSession)
internal fun KtAnnotatedSymbol.isHiddenOrSynthetic(
annotationUseSiteTarget: AnnotationUseSiteTarget? = null,
acceptAnnotationsWithoutUseSite: Boolean = false,
) = isHiddenByDeprecation(this, annotationUseSiteTarget) ||
hasJvmSyntheticAnnotation(annotationUseSiteTarget, acceptAnnotationsWithoutUseSite)
useSiteTargetFilter: AnnotationUseSiteTargetFilter = annotationUseSiteTarget.toFilter(),
) = isHiddenByDeprecation(this, annotationUseSiteTarget) || hasJvmSyntheticAnnotation(useSiteTargetFilter)
internal fun KtAnnotatedSymbol.hasJvmFieldAnnotation(): Boolean = hasAnnotation(StandardClassIds.Annotations.JvmField)
internal fun KtAnnotatedSymbol.hasPublishedApiAnnotation(annotationUseSiteTarget: AnnotationUseSiteTarget? = null): Boolean =
hasAnnotation(StandardClassIds.Annotations.PublishedApi, annotationUseSiteTarget)
internal fun KtAnnotatedSymbol.hasPublishedApiAnnotation(
useSiteTargetFilter: AnnotationUseSiteTargetFilter = AnyAnnotationUseSiteTargetFilter,
): Boolean = hasAnnotation(StandardClassIds.Annotations.PublishedApi, useSiteTargetFilter)
internal fun KtAnnotatedSymbol.hasDeprecatedAnnotation(
annotationUseSiteTarget: AnnotationUseSiteTarget? = null,
acceptAnnotationsWithoutUseSite: Boolean = false,
): Boolean = hasAnnotation(StandardClassIds.Annotations.Deprecated, annotationUseSiteTarget, acceptAnnotationsWithoutUseSite)
useSiteTargetFilter: AnnotationUseSiteTargetFilter = AnyAnnotationUseSiteTargetFilter,
): Boolean = hasAnnotation(StandardClassIds.Annotations.Deprecated, useSiteTargetFilter)
internal fun KtAnnotatedSymbol.hasJvmOverloadsAnnotation(): Boolean = hasAnnotation(JVM_OVERLOADS_CLASS_ID)
internal fun KtAnnotatedSymbol.hasJvmStaticAnnotation(
annotationUseSiteTarget: AnnotationUseSiteTarget? = null,
acceptAnnotationsWithoutUseSite: Boolean = false,
): Boolean = hasAnnotation(StandardClassIds.Annotations.JvmStatic, annotationUseSiteTarget, acceptAnnotationsWithoutUseSite)
useSiteTargetFilter: AnnotationUseSiteTargetFilter = AnyAnnotationUseSiteTargetFilter,
): Boolean = hasAnnotation(StandardClassIds.Annotations.JvmStatic, useSiteTargetFilter)
internal fun KtAnnotatedSymbol.hasInlineOnlyAnnotation(): Boolean = hasAnnotation(StandardClassIds.Annotations.InlineOnly)
internal fun KtAnnotatedSymbol.findAnnotation(
classId: ClassId,
annotationUseSiteTarget: AnnotationUseSiteTarget?,
acceptAnnotationsWithoutUseSite: Boolean = false,
useSiteTargetFilter: AnnotationUseSiteTargetFilter = AnyAnnotationUseSiteTargetFilter,
): KtAnnotationApplicationWithArgumentsInfo? {
if (!hasAnnotation(classId, annotationUseSiteTarget, acceptAnnotationsWithoutUseSite)) return null
if (!hasAnnotation(classId, useSiteTargetFilter)) return null
return annotations.find {
val useSiteTarget = it.useSiteTarget
(useSiteTarget == annotationUseSiteTarget || acceptAnnotationsWithoutUseSite && useSiteTarget == null) && it.classId == classId
}
return annotationsByClassId(classId, useSiteTargetFilter).firstOrNull()
}
context(KtAnalysisSession)
internal fun KtAnnotatedSymbol.computeThrowsList(
builder: LightReferenceListBuilder,
annotationUseSiteTarget: AnnotationUseSiteTarget?,
useSitePosition: PsiElement,
containingClass: SymbolLightClassBase,
acceptAnnotationsWithoutUseSite: Boolean = false,
useSiteTargetFilter: AnnotationUseSiteTargetFilter = AnyAnnotationUseSiteTargetFilter,
) {
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, acceptAnnotationsWithoutUseSite) ?: return
val annoApp = findAnnotation(StandardClassIds.Annotations.Throws, useSiteTargetFilter) ?: return
fun handleAnnotationValue(annotationValue: KtAnnotationValue) = when (annotationValue) {
is KtArrayAnnotationValue -> {
@@ -71,8 +71,7 @@ class SymbolLightClassForFacade(
annotationsProvider = SymbolAnnotationsProvider(
ktModule = this.ktModule,
annotatedSymbolPointer = firstFileInFacade.symbolPointerOfType<KtFileSymbol>(),
annotationUseSiteTarget = AnnotationUseSiteTarget.FILE,
acceptAnnotationsWithoutSite = true,
annotationUseSiteTargetFilter = AnnotationUseSiteTarget.FILE.toFilterWithAdditionalNull(),
)
)
},
@@ -34,10 +34,7 @@ import org.jetbrains.kotlin.config.JvmDefaultMode
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.lexer.KtTokens.*
import org.jetbrains.kotlin.light.classes.symbol.annotations.hasJvmFieldAnnotation
import org.jetbrains.kotlin.light.classes.symbol.annotations.hasJvmOverloadsAnnotation
import org.jetbrains.kotlin.light.classes.symbol.annotations.hasJvmStaticAnnotation
import org.jetbrains.kotlin.light.classes.symbol.annotations.isHiddenOrSynthetic
import org.jetbrains.kotlin.light.classes.symbol.annotations.*
import org.jetbrains.kotlin.light.classes.symbol.copy
import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightField
import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightFieldForEnumEntry
@@ -311,15 +308,16 @@ internal fun SymbolLightClassBase.createPropertyAccessors(
if (this !is SymbolLightClassForFacade && propertyTypeIsValueClass) return
fun KtPropertyAccessorSymbol.needToCreateAccessor(siteTarget: AnnotationUseSiteTarget): Boolean {
val useSiteTargetFilterForPropertyAccessor = siteTarget.toFilterWithAdditionalNull()
if (onlyJvmStatic &&
!hasJvmStaticAnnotation(siteTarget, acceptAnnotationsWithoutUseSite = true) &&
!declaration.hasJvmStaticAnnotation(siteTarget, acceptAnnotationsWithoutUseSite = true)
!hasJvmStaticAnnotation(useSiteTargetFilterForPropertyAccessor) &&
!declaration.hasJvmStaticAnnotation(useSiteTargetFilterForPropertyAccessor)
) return false
if (declaration.hasReifiedParameters) return false
if (!hasBody && visibility.isPrivateOrPrivateToThis()) return false
if (declaration.isHiddenOrSynthetic(siteTarget)) return false
return !isHiddenOrSynthetic(siteTarget, acceptAnnotationsWithoutUseSite = true)
return !isHiddenOrSynthetic(siteTarget, useSiteTargetFilterForPropertyAccessor)
}
val originalElement = declaration.sourcePsiSafe<KtDeclaration>()
@@ -403,8 +401,9 @@ private fun hasBackingField(property: KtPropertySymbol): Boolean {
return hasBackingFieldByPsi
}
val fieldUseSite = AnnotationUseSiteTarget.FIELD
if (property.modality == Modality.ABSTRACT ||
property.isHiddenOrSynthetic(AnnotationUseSiteTarget.FIELD, acceptAnnotationsWithoutUseSite = true)
property.isHiddenOrSynthetic(fieldUseSite, fieldUseSite.toFilterWithAdditionalNull())
) return false
return hasBackingFieldByPsi ?: property.hasBackingField
@@ -7,14 +7,17 @@ package org.jetbrains.kotlin.light.classes.symbol.fields
import com.intellij.psi.*
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.annotations.FieldAnnotationUseSiteTargetFilter
import org.jetbrains.kotlin.analysis.api.annotations.NullAnnotationUseSiteTargetFilter
import org.jetbrains.kotlin.analysis.api.annotations.PropertyAnnotationUseSiteTargetFilter
import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntrySymbol
import org.jetbrains.kotlin.analysis.api.symbols.pointers.symbolPointerOfType
import org.jetbrains.kotlin.asJava.classes.cannotModify
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.light.classes.symbol.analyzeForLightClasses
import org.jetbrains.kotlin.light.classes.symbol.annotations.LazyAnnotationsBox
import org.jetbrains.kotlin.light.classes.symbol.annotations.SymbolAnnotationsProvider
import org.jetbrains.kotlin.light.classes.symbol.annotations.annotationUseSiteTargetFilterOf
import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassForClassOrObject
import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassForEnumEntry
import org.jetbrains.kotlin.light.classes.symbol.isOriginEquivalentTo
@@ -42,8 +45,11 @@ internal class SymbolLightFieldForEnumEntry(
annotationsProvider = SymbolAnnotationsProvider(
ktModule = ktModule,
annotatedSymbolPointer = enumEntry.symbolPointerOfType<KtEnumEntrySymbol>(),
annotationUseSiteTarget = AnnotationUseSiteTarget.FIELD,
acceptAnnotationsWithoutSite = true,
annotationUseSiteTargetFilter = annotationUseSiteTargetFilterOf(
NullAnnotationUseSiteTargetFilter,
FieldAnnotationUseSiteTargetFilter,
PropertyAnnotationUseSiteTargetFilter,
),
)
),
)
@@ -19,10 +19,7 @@ import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.light.classes.symbol.*
import org.jetbrains.kotlin.light.classes.symbol.annotations.LazyAnnotationsBox
import org.jetbrains.kotlin.light.classes.symbol.annotations.NullabilityAnnotationsProvider
import org.jetbrains.kotlin.light.classes.symbol.annotations.SymbolAnnotationsProvider
import org.jetbrains.kotlin.light.classes.symbol.annotations.hasDeprecatedAnnotation
import org.jetbrains.kotlin.light.classes.symbol.annotations.*
import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassBase
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.LazyModifiersBox
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightMemberModifierList
@@ -90,7 +87,7 @@ internal class SymbolLightFieldForProperty private constructor(
private val _isDeprecated: Boolean by lazyPub {
withPropertySymbol { propertySymbol ->
propertySymbol.hasDeprecatedAnnotation(AnnotationUseSiteTarget.FIELD, acceptAnnotationsWithoutUseSite = true)
propertySymbol.hasDeprecatedAnnotation(AnnotationUseSiteTarget.FIELD.toFilterWithAdditionalNull())
}
}
@@ -126,12 +123,20 @@ internal class SymbolLightFieldForProperty private constructor(
}
PsiModifier.VOLATILE -> withPropertySymbol { propertySymbol ->
val hasAnnotation = propertySymbol.hasAnnotation(VOLATILE_ANNOTATION_CLASS_ID, null)
val hasAnnotation = propertySymbol.hasAnnotation(
VOLATILE_ANNOTATION_CLASS_ID,
AnnotationUseSiteTarget.FIELD.toFilterWithAdditionalNull(),
)
mapOf(modifier to hasAnnotation)
}
PsiModifier.TRANSIENT -> withPropertySymbol { propertySymbol ->
val hasAnnotation = propertySymbol.hasAnnotation(TRANSIENT_ANNOTATION_CLASS_ID, null)
val hasAnnotation = propertySymbol.hasAnnotation(
TRANSIENT_ANNOTATION_CLASS_ID,
AnnotationUseSiteTarget.FIELD.toFilterWithAdditionalNull(),
)
mapOf(modifier to hasAnnotation)
}
@@ -152,8 +157,7 @@ internal class SymbolLightFieldForProperty private constructor(
annotationsProvider = SymbolAnnotationsProvider(
ktModule = ktModule,
annotatedSymbolPointer = propertySymbolPointer,
annotationUseSiteTarget = AnnotationUseSiteTarget.FIELD,
acceptAnnotationsWithoutSite = true,
annotationUseSiteTargetFilter = AnnotationUseSiteTarget.FIELD.toFilterWithAdditionalNull(),
),
additionalAnnotationsProvider = NullabilityAnnotationsProvider {
withPropertySymbol { propertySymbol ->
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.KtConstantInitializerValue
import org.jetbrains.kotlin.analysis.api.KtConstantValueForAnnotation
import org.jetbrains.kotlin.analysis.api.KtNonConstantInitializerValue
import org.jetbrains.kotlin.analysis.api.annotations.toFilter
import org.jetbrains.kotlin.analysis.api.symbols.*
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.analysis.api.types.KtTypeMappingMode
@@ -90,7 +91,7 @@ internal class SymbolLightAccessorMethod private constructor(
private val _name: String by lazyPub {
analyzeForLightClasses(ktModule) {
propertyAccessorSymbol().getJvmNameFromAnnotation(accessorSite) ?: run {
propertyAccessorSymbol().getJvmNameFromAnnotation(accessorSite.toFilterWithAdditionalNull()) ?: run {
val symbol = propertySymbol()
val defaultName = symbol.name.identifier.let {
if (this@SymbolLightAccessorMethod.containingClass.isAnnotationType) it else it.abiName()
@@ -133,10 +134,9 @@ internal class SymbolLightAccessorMethod private constructor(
propertyAccessorSymbolPointer.withSymbol(ktModule) { accessorSymbol ->
accessorSymbol.computeThrowsList(
builder,
accessorSite,
this@SymbolLightAccessorMethod,
containingClass,
acceptAnnotationsWithoutUseSite = true,
accessorSite.toFilterWithAdditionalNull(),
)
}
}
@@ -171,9 +171,12 @@ internal class SymbolLightAccessorMethod private constructor(
private fun isStatic(): Boolean = analyzeForLightClasses(ktModule) {
val propertySymbol = propertySymbol()
propertySymbol.isStatic ||
propertySymbol.hasJvmStaticAnnotation(accessorSite, acceptAnnotationsWithoutUseSite = true) ||
propertyAccessorSymbol().hasJvmStaticAnnotation(accessorSite, acceptAnnotationsWithoutUseSite = true)
if (propertySymbol.isStatic) {
return@analyzeForLightClasses true
}
val filter = accessorSite.toFilterWithAdditionalNull()
propertySymbol.hasJvmStaticAnnotation(filter) || propertyAccessorSymbol().hasJvmStaticAnnotation(filter)
}
private val _modifierList: PsiModifierList by lazyPub {
@@ -185,13 +188,12 @@ internal class SymbolLightAccessorMethod private constructor(
SymbolAnnotationsProvider(
ktModule = ktModule,
annotatedSymbolPointer = propertyAccessorSymbolPointer,
annotationUseSiteTarget = accessorSite,
acceptAnnotationsWithoutSite = true,
annotationUseSiteTargetFilter = accessorSite.toFilterWithAdditionalNull(),
),
SymbolAnnotationsProvider(
ktModule = ktModule,
annotatedSymbolPointer = containingPropertySymbolPointer,
annotationUseSiteTarget = accessorSite,
annotationUseSiteTargetFilter = accessorSite.toFilter(),
),
),
additionalAnnotationsProvider = NullabilityAnnotationsProvider {
@@ -217,8 +219,8 @@ internal class SymbolLightAccessorMethod private constructor(
private val _isDeprecated: Boolean by lazyPub {
analyzeForLightClasses(ktModule) {
propertySymbol().hasDeprecatedAnnotation(accessorSite, acceptAnnotationsWithoutUseSite = true) ||
propertyAccessorSymbol().hasDeprecatedAnnotation(accessorSite, acceptAnnotationsWithoutUseSite = true)
val filter = accessorSite.toFilterWithAdditionalNull()
propertySymbol().hasDeprecatedAnnotation(filter) || propertyAccessorSymbol().hasDeprecatedAnnotation(filter)
}
}
@@ -128,9 +128,8 @@ internal abstract class SymbolLightMethod<FType : KtFunctionLikeSymbol> private
withFunctionSymbol { functionSymbol ->
functionSymbol.computeThrowsList(
builder,
annotationUseSiteTarget = null,
this@SymbolLightMethod,
containingClass
containingClass,
)
}
}
@@ -12,6 +12,7 @@ import com.intellij.psi.impl.light.LightReferenceListBuilder
import com.intellij.psi.util.MethodSignature
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.annotations.toFilter
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtAnnotatedSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithVisibility
@@ -28,6 +29,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.light.classes.symbol.SymbolLightMemberBase
import org.jetbrains.kotlin.light.classes.symbol.annotations.getJvmNameFromAnnotation
import org.jetbrains.kotlin.light.classes.symbol.annotations.hasPublishedApiAnnotation
import org.jetbrains.kotlin.light.classes.symbol.annotations.toFilterWithAdditionalNull
import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassBase
internal abstract class SymbolLightMethodBase(
@@ -105,12 +107,13 @@ internal abstract class SymbolLightMethodBase(
protected fun <T> T.computeJvmMethodName(
defaultName: String,
containingClass: SymbolLightClassBase,
annotationUseSiteTarget: AnnotationUseSiteTarget?,
annotationUseSiteTarget: AnnotationUseSiteTarget? = null,
): String where T : KtAnnotatedSymbol, T : KtSymbolWithVisibility, T : KtCallableSymbol {
getJvmNameFromAnnotation(annotationUseSiteTarget)?.let { return it }
getJvmNameFromAnnotation(annotationUseSiteTarget.toFilterWithAdditionalNull())?.let { return it }
if (visibility != Visibilities.Internal) return defaultName
if (containingClass is KtLightClassForFacade) return defaultName
if (hasPublishedApiAnnotation(annotationUseSiteTarget)) return defaultName
if (hasPublishedApiAnnotation(annotationUseSiteTarget.toFilter())) return defaultName
val moduleName = (ktModule as? KtSourceModule)?.moduleName ?: return defaultName
return mangleInternalName(defaultName, moduleName)
@@ -50,7 +50,6 @@ internal class SymbolLightSimpleMethod(
functionSymbol.computeJvmMethodName(
functionSymbol.name.asString(),
this@SymbolLightSimpleMethod.containingClass,
annotationUseSiteTarget = null,
)
}
}
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.light.classes.symbol.annotations.LazyAnnotationsBox
import org.jetbrains.kotlin.light.classes.symbol.annotations.NullabilityAnnotationsProvider
import org.jetbrains.kotlin.light.classes.symbol.annotations.SymbolAnnotationsProvider
import org.jetbrains.kotlin.light.classes.symbol.annotations.toFilterWithAdditionalNull
import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightMethodBase
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList
import org.jetbrains.kotlin.light.classes.symbol.withSymbol
@@ -34,10 +35,9 @@ internal class SymbolLightParameter(
annotationsProvider = SymbolAnnotationsProvider(
ktModule = ktModule,
annotatedSymbolPointer = parameterSymbolPointer,
annotationUseSiteTarget = isConstructorParameterSymbol.ifTrue {
annotationUseSiteTargetFilter = isConstructorParameterSymbol.ifTrue {
AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER
},
acceptAnnotationsWithoutSite = true,
}.toFilterWithAdditionalNull(),
),
additionalAnnotationsProvider = NullabilityAnnotationsProvider(::nullabilityType),
),
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.light.classes.symbol.*
import org.jetbrains.kotlin.light.classes.symbol.annotations.LazyAnnotationsBox
import org.jetbrains.kotlin.light.classes.symbol.annotations.NullabilityAnnotationsProvider
import org.jetbrains.kotlin.light.classes.symbol.annotations.SymbolAnnotationsProvider
import org.jetbrains.kotlin.light.classes.symbol.annotations.toFilterWithAdditionalNull
import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightMethodBase
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList
import org.jetbrains.kotlin.psi.KtParameter
@@ -71,8 +72,7 @@ internal class SymbolLightParameterForReceiver private constructor(
annotationsProvider = SymbolAnnotationsProvider(
ktModule = ktModule,
annotatedSymbolPointer = receiverPointer,
annotationUseSiteTarget = AnnotationUseSiteTarget.RECEIVER,
acceptAnnotationsWithoutSite = true,
annotationUseSiteTargetFilter = AnnotationUseSiteTarget.RECEIVER.toFilterWithAdditionalNull(),
),
additionalAnnotationsProvider = NullabilityAnnotationsProvider {
withReceiverSymbol { receiver ->
@@ -7,15 +7,13 @@ package org.jetbrains.kotlin.light.classes.symbol.parameters
import com.intellij.psi.PsiModifierList
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.annotations.SetterParameterAnnotationUseSiteTargetFilter
import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.light.classes.symbol.annotations.CompositeAnnotationsProvider
import org.jetbrains.kotlin.light.classes.symbol.annotations.LazyAnnotationsBox
import org.jetbrains.kotlin.light.classes.symbol.annotations.NullabilityAnnotationsProvider
import org.jetbrains.kotlin.light.classes.symbol.annotations.SymbolAnnotationsProvider
import org.jetbrains.kotlin.light.classes.symbol.annotations.*
import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightMethodBase
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList
import org.jetbrains.kotlin.light.classes.symbol.withSymbol
@@ -48,13 +46,12 @@ internal class SymbolLightSetterParameter(
SymbolAnnotationsProvider(
ktModule = ktModule,
annotatedSymbolPointer = parameterSymbolPointer,
annotationUseSiteTarget = AnnotationUseSiteTarget.SETTER_PARAMETER,
acceptAnnotationsWithoutSite = true,
annotationUseSiteTargetFilter = AnnotationUseSiteTarget.SETTER_PARAMETER.toFilterWithAdditionalNull(),
),
SymbolAnnotationsProvider(
ktModule = ktModule,
annotatedSymbolPointer = containingPropertySymbolPointer,
annotationUseSiteTarget = AnnotationUseSiteTarget.SETTER_PARAMETER,
annotationUseSiteTargetFilter = SetterParameterAnnotationUseSiteTargetFilter,
),
),
additionalAnnotationsProvider = NullabilityAnnotationsProvider(::nullabilityType),
@@ -120,6 +120,12 @@ public class SymbolLightClassesByPsiForLibraryTestGenerated extends AbstractSymb
runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/exposedAnonymousType.kt");
}
@Test
@TestMetadata("fieldModifiers.kt")
public void testFieldModifiers() throws Exception {
runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/fieldModifiers.kt");
}
@Test
@TestMetadata("generics.kt")
public void testGenerics() throws Exception {
@@ -120,6 +120,12 @@ public class SymbolLightClassesByPsiForSourceTestGenerated extends AbstractSymbo
runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/exposedAnonymousType.kt");
}
@Test
@TestMetadata("fieldModifiers.kt")
public void testFieldModifiers() throws Exception {
runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/fieldModifiers.kt");
}
@Test
@TestMetadata("generics.kt")
public void testGenerics() throws Exception {
@@ -1,5 +1,5 @@
public enum AnnotationsOnEnumEntry /* two.AnnotationsOnEnumEntry*/ {
@two.PropertyImplicitly() @two.FieldImplicitly() @two.FieldExplicitly() EntryWithoutConstructor,
@two.PropertyImplicitly() @two.PropertyExplicitly() @two.FieldImplicitly() @two.FieldExplicitly() EntryWithoutConstructor,
@two.PropertyImplicitly() @two.FieldImplicitly() EntryWithConstructor,
EntryWithConstructor2;
@@ -1,39 +0,0 @@
public enum AnnotationsOnEnumEntry /* two.AnnotationsOnEnumEntry*/ {
@two.PropertyImplicitly() @two.PropertyExplicitly() @two.FieldImplicitly() @two.FieldExplicitly() EntryWithoutConstructor,
@two.PropertyImplicitly() @two.FieldImplicitly() EntryWithConstructor,
EntryWithConstructor2;
@org.jetbrains.annotations.NotNull()
public static two.AnnotationsOnEnumEntry valueOf(java.lang.String) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;// valueOf(java.lang.String)
@org.jetbrains.annotations.NotNull()
public static two.AnnotationsOnEnumEntry[] values();// values()
private AnnotationsOnEnumEntry(int);// .ctor(int)
public final void foo();// foo()
}
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.FIELD})
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.FIELD})
public abstract @interface FieldExplicitly /* two.FieldExplicitly*/ {
}
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.FIELD})
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.FIELD})
public abstract @interface FieldImplicitly /* two.FieldImplicitly*/ {
}
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {})
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.PROPERTY})
public abstract @interface PropertyExplicitly /* two.PropertyExplicitly*/ {
}
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {})
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.PROPERTY})
public abstract @interface PropertyImplicitly /* two.PropertyImplicitly*/ {
}
@@ -0,0 +1,19 @@
public final class FieldModifiersKt /* FieldModifiersKt*/ {
@kotlin.jvm.Transient()
@kotlin.jvm.Volatile()
@org.jetbrains.annotations.NotNull()
private static transient volatile java.lang.String explicit;
@kotlin.jvm.Transient()
@kotlin.jvm.Volatile()
private static transient volatile int implicit;
@org.jetbrains.annotations.NotNull()
public static final java.lang.String getExplicit();// getExplicit()
public static final int getImplicit();// getImplicit()
public static final void setExplicit(@org.jetbrains.annotations.NotNull() java.lang.String);// setExplicit(java.lang.String)
public static final void setImplicit(int);// setImplicit(int)
}
@@ -0,0 +1,19 @@
public final class FieldModifiersKt /* FieldModifiersKt*/ {
@kotlin.jvm.Transient()
@kotlin.jvm.Volatile()
@org.jetbrains.annotations.NotNull()
private static transient volatile java.lang.String explicit = "1" /* initializer type: java.lang.String */;
@kotlin.jvm.Transient()
@kotlin.jvm.Volatile()
private static transient volatile int implicit = 0 /* initializer type: int */;
@org.jetbrains.annotations.NotNull()
public static final java.lang.String getExplicit();// getExplicit()
public static final int getImplicit();// getImplicit()
public static final void setExplicit(@org.jetbrains.annotations.NotNull() java.lang.String);// setExplicit(java.lang.String)
public static final void setImplicit(int);// setImplicit(int)
}
@@ -0,0 +1,7 @@
@Volatile
@Transient
var implicit: Int = 0
@field:Volatile
@field:Transient
var explicit: String = "1"
@@ -0,0 +1,15 @@
public final class FieldModifiersKt /* FieldModifiersKt*/ {
@org.jetbrains.annotations.NotNull()
private static transient volatile java.lang.String explicit;
private static transient volatile int implicit;
@org.jetbrains.annotations.NotNull()
public static final java.lang.String getExplicit();// getExplicit()
public static final int getImplicit();// getImplicit()
public static final void setExplicit(@org.jetbrains.annotations.NotNull() java.lang.String);// setExplicit(java.lang.String)
public static final void setImplicit(int);// setImplicit(int)
}