[FIR] Update call-sites which are interested in annotation arguments
After the previous commit, enum entry access to the annotation may be presented by two different nodes ^KT-64975
This commit is contained in:
committed by
Space Team
parent
a4e8be8687
commit
3fba3b703e
+1
-2
@@ -61,8 +61,7 @@ fun FirClassLikeSymbol<*>.getAllowedAnnotationTargets(session: FirSession): Set<
|
|||||||
val arguments = targetAnnotation.findArgumentByName(ParameterNames.targetAllowedTargets)?.unwrapAndFlattenArgument(flattenArrays = true).orEmpty()
|
val arguments = targetAnnotation.findArgumentByName(ParameterNames.targetAllowedTargets)?.unwrapAndFlattenArgument(flattenArrays = true).orEmpty()
|
||||||
|
|
||||||
return arguments.mapNotNullTo(mutableSetOf()) { argument ->
|
return arguments.mapNotNullTo(mutableSetOf()) { argument ->
|
||||||
val targetExpression = argument as? FirQualifiedAccessExpression
|
val calleeReference = argument.toReference(session)
|
||||||
val calleeReference = targetExpression?.calleeReference
|
|
||||||
val targetName =
|
val targetName =
|
||||||
calleeReference?.resolved?.name?.asString()
|
calleeReference?.resolved?.name?.asString()
|
||||||
//for java annotations mappings: if java annotation is found in sdk and no kotlin dependency there is provided
|
//for java annotations mappings: if java annotation is found in sdk and no kotlin dependency there is provided
|
||||||
|
|||||||
+3
-7
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.fir.declarations.utils.correspondingValueParameterFr
|
|||||||
import org.jetbrains.kotlin.fir.declarations.utils.isData
|
import org.jetbrains.kotlin.fir.declarations.utils.isData
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.nameOrSpecialName
|
import org.jetbrains.kotlin.fir.declarations.utils.nameOrSpecialName
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
import org.jetbrains.kotlin.fir.expressions.toReference
|
||||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||||
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
@@ -276,13 +276,9 @@ object FirOptInUsageBaseChecker {
|
|||||||
val experimental = getAnnotationByClassId(OptInNames.REQUIRES_OPT_IN_CLASS_ID, session)
|
val experimental = getAnnotationByClassId(OptInNames.REQUIRES_OPT_IN_CLASS_ID, session)
|
||||||
?: return null
|
?: return null
|
||||||
|
|
||||||
val levelArgument = experimental.findArgumentByName(LEVEL) as? FirQualifiedAccessExpression
|
val levelArgument = experimental.findArgumentByName(LEVEL)
|
||||||
|
|
||||||
val levelName = when (val calleeReference = levelArgument?.calleeReference) {
|
val levelName = levelArgument?.extractEnumValueArgumentInfo()?.enumEntryName?.asString()
|
||||||
is FirErrorNamedReference -> null
|
|
||||||
is FirNamedReference -> calleeReference.name.asString()
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
|
|
||||||
val severity = Experimentality.Severity.entries.firstOrNull { it.name == levelName } ?: Experimentality.DEFAULT_SEVERITY
|
val severity = Experimentality.Severity.entries.firstOrNull { it.name == levelName } ?: Experimentality.DEFAULT_SEVERITY
|
||||||
val message = (experimental.findArgumentByName(MESSAGE) as? FirConstExpression<*>)?.value as? String
|
val message = (experimental.findArgumentByName(MESSAGE) as? FirConstExpression<*>)?.value as? String
|
||||||
|
|||||||
+8
@@ -199,6 +199,14 @@ internal object FirToConstantValueTransformer : FirDefaultVisitor<ConstantValue<
|
|||||||
return visitQualifiedAccessExpression(propertyAccessExpression, data)
|
return visitQualifiedAccessExpression(propertyAccessExpression, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun visitEnumEntryDeserializedAccessExpression(
|
||||||
|
enumEntryDeserializedAccessExpression: FirEnumEntryDeserializedAccessExpression,
|
||||||
|
data: FirToConstantValueTransformerData,
|
||||||
|
): ConstantValue<*> {
|
||||||
|
val element = enumEntryDeserializedAccessExpression
|
||||||
|
return EnumValue(element.enumClassId, element.enumEntryName)
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitFunctionCall(
|
override fun visitFunctionCall(
|
||||||
functionCall: FirFunctionCall,
|
functionCall: FirFunctionCall,
|
||||||
data: FirToConstantValueTransformerData
|
data: FirToConstantValueTransformerData
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ class FirJavaElementFinder(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun FirAnnotation.findTargets(): List<String> = buildList {
|
private fun FirAnnotation.findTargets(): List<String> = buildList {
|
||||||
forEachAnnotationTarget { add(it.identifier) }
|
forEachAnnotationTarget(session) { add(it.identifier) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildFieldStubForConst(firProperty: FirProperty, classStub: PsiClassStubImpl<ClsClassImpl>) {
|
private fun buildFieldStubForConst(firProperty: FirProperty, classStub: PsiClassStubImpl<ClsClassImpl>) {
|
||||||
|
|||||||
+21
-68
@@ -5,14 +5,10 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.declarations
|
package org.jetbrains.kotlin.fir.declarations
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
|
||||||
import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.containingClassLookupTag
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
import org.jetbrains.kotlin.fir.references.*
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
|
||||||
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||||
@@ -43,17 +39,9 @@ fun FirAnnotation.toAnnotationClassIdSafe(session: FirSession): ClassId? =
|
|||||||
fun FirAnnotation.toAnnotationClassLikeSymbol(session: FirSession): FirClassLikeSymbol<*>? =
|
fun FirAnnotation.toAnnotationClassLikeSymbol(session: FirSession): FirClassLikeSymbol<*>? =
|
||||||
toAnnotationLookupTag(session)?.toSymbol(session)
|
toAnnotationLookupTag(session)?.toSymbol(session)
|
||||||
|
|
||||||
private fun FirAnnotation.toAnnotationClass(session: FirSession): FirRegularClass? =
|
fun FirAnnotation.toAnnotationClass(session: FirSession): FirRegularClass? =
|
||||||
toAnnotationClassLikeSymbol(session)?.fir as? FirRegularClass
|
toAnnotationClassLikeSymbol(session)?.fir as? FirRegularClass
|
||||||
|
|
||||||
// TODO: this is temporary solution, we need something better
|
|
||||||
private val FirExpression.callableNameOfMetaAnnotationArgument: Name?
|
|
||||||
get() =
|
|
||||||
(this as? FirQualifiedAccessExpression)?.let {
|
|
||||||
val callableSymbol = it.calleeReference.toResolvedCallableSymbol()
|
|
||||||
callableSymbol?.callableId?.callableName
|
|
||||||
}
|
|
||||||
|
|
||||||
private val sourceName = Name.identifier("SOURCE")
|
private val sourceName = Name.identifier("SOURCE")
|
||||||
|
|
||||||
fun List<FirAnnotation>.nonSourceAnnotations(session: FirSession): List<FirAnnotation> =
|
fun List<FirAnnotation>.nonSourceAnnotations(session: FirSession): List<FirAnnotation> =
|
||||||
@@ -62,66 +50,13 @@ fun List<FirAnnotation>.nonSourceAnnotations(session: FirSession): List<FirAnnot
|
|||||||
firAnnotationClass != null && firAnnotationClass.annotations.none { meta ->
|
firAnnotationClass != null && firAnnotationClass.annotations.none { meta ->
|
||||||
meta.toAnnotationClassId(session) == StandardClassIds.Annotations.Retention &&
|
meta.toAnnotationClassId(session) == StandardClassIds.Annotations.Retention &&
|
||||||
meta.findArgumentByName(StandardClassIds.Annotations.ParameterNames.retentionValue)
|
meta.findArgumentByName(StandardClassIds.Annotations.ParameterNames.retentionValue)
|
||||||
?.callableNameOfMetaAnnotationArgument == sourceName
|
?.extractEnumValueArgumentInfo()?.enumEntryName == sourceName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirAnnotationContainer.nonSourceAnnotations(session: FirSession): List<FirAnnotation> =
|
fun FirAnnotationContainer.nonSourceAnnotations(session: FirSession): List<FirAnnotation> =
|
||||||
annotations.nonSourceAnnotations(session)
|
annotations.nonSourceAnnotations(session)
|
||||||
|
|
||||||
fun FirAnnotation.useSiteTargetsFromMetaAnnotation(session: FirSession): Set<AnnotationUseSiteTarget> {
|
|
||||||
return toAnnotationClass(session)
|
|
||||||
?.annotations
|
|
||||||
?.find { it.toAnnotationClassIdSafe(session) == StandardClassIds.Annotations.Target }
|
|
||||||
?.findUseSiteTargets()
|
|
||||||
?: DEFAULT_USE_SITE_TARGETS
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun FirAnnotation.findUseSiteTargets(): Set<AnnotationUseSiteTarget> = buildSet {
|
|
||||||
forEachAnnotationTarget {
|
|
||||||
USE_SITE_TARGET_NAME_MAP[it.identifier]?.let { addAll(it) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun FirAnnotation.forEachAnnotationTarget(action: (Name) -> Unit) {
|
|
||||||
fun take(arg: FirExpression) {
|
|
||||||
if (arg !is FirQualifiedAccessExpression) return@take
|
|
||||||
val callableSymbol = arg.calleeReference.toResolvedCallableSymbol() ?: return@take
|
|
||||||
if (callableSymbol.containingClassLookupTag()?.classId == StandardClassIds.AnnotationTarget) {
|
|
||||||
action(callableSymbol.callableId.callableName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this is FirAnnotationCall) {
|
|
||||||
for (arg in argumentList.arguments) {
|
|
||||||
arg.unwrapAndFlattenArgument(flattenArrays = true).forEach(::take)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
argumentMapping.mapping[StandardClassIds.Annotations.ParameterNames.targetAllowedTargets]
|
|
||||||
?.unwrapAndFlattenArgument(flattenArrays = true)
|
|
||||||
?.forEach(::take)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// See [org.jetbrains.kotlin.descriptors.annotations.KotlinTarget.USE_SITE_MAPPING] (it's in reverse)
|
|
||||||
private val USE_SITE_TARGET_NAME_MAP = mapOf(
|
|
||||||
"FIELD" to setOf(AnnotationUseSiteTarget.FIELD, AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD),
|
|
||||||
"FILE" to setOf(AnnotationUseSiteTarget.FILE),
|
|
||||||
"PROPERTY" to setOf(AnnotationUseSiteTarget.PROPERTY),
|
|
||||||
"PROPERTY_GETTER" to setOf(AnnotationUseSiteTarget.PROPERTY_GETTER),
|
|
||||||
"PROPERTY_SETTER" to setOf(AnnotationUseSiteTarget.PROPERTY_SETTER),
|
|
||||||
"VALUE_PARAMETER" to setOf(
|
|
||||||
AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER,
|
|
||||||
AnnotationUseSiteTarget.RECEIVER,
|
|
||||||
AnnotationUseSiteTarget.SETTER_PARAMETER,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
// See [org.jetbrains.kotlin.descriptors.annotations.KotlinTarget] (the second argument of each entry)
|
|
||||||
private val DEFAULT_USE_SITE_TARGETS: Set<AnnotationUseSiteTarget> =
|
|
||||||
USE_SITE_TARGET_NAME_MAP.values.fold(setOf<AnnotationUseSiteTarget>()) { a, b -> a + b } - setOf(AnnotationUseSiteTarget.FILE)
|
|
||||||
|
|
||||||
fun FirDeclaration.hasAnnotation(classId: ClassId, session: FirSession): Boolean {
|
fun FirDeclaration.hasAnnotation(classId: ClassId, session: FirSession): Boolean {
|
||||||
return annotations.hasAnnotation(classId, session)
|
return annotations.hasAnnotation(classId, session)
|
||||||
}
|
}
|
||||||
@@ -238,3 +173,21 @@ fun hasLowPriorityAnnotation(annotations: List<FirAnnotation>) = annotations.any
|
|||||||
val lookupTag = it.annotationTypeRef.coneTypeSafe<ConeClassLikeType>()?.lookupTag ?: return@any false
|
val lookupTag = it.annotationTypeRef.coneTypeSafe<ConeClassLikeType>()?.lookupTag ?: return@any false
|
||||||
lookupTag.classId == LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_CLASS_ID
|
lookupTag.classId == LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_CLASS_ID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class EnumValueArgumentInfo(val enumClassId: ClassId?, val enumEntryName: Name)
|
||||||
|
|
||||||
|
fun FirExpression.extractEnumValueArgumentInfo(): EnumValueArgumentInfo? {
|
||||||
|
return when (this) {
|
||||||
|
is FirPropertyAccessExpression -> {
|
||||||
|
if (isResolved) {
|
||||||
|
val entrySymbol = calleeReference.toResolvedEnumEntrySymbol() ?: return null
|
||||||
|
EnumValueArgumentInfo(entrySymbol.callableId.classId!!, entrySymbol.callableId.callableName)
|
||||||
|
} else {
|
||||||
|
val enumEntryName = (calleeReference as? FirNamedReference)?.name ?: return null
|
||||||
|
EnumValueArgumentInfo(null, enumEntryName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is FirEnumEntryDeserializedAccessExpression -> EnumValueArgumentInfo(enumClassId, enumEntryName)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+8
-4
@@ -7,10 +7,13 @@ package org.jetbrains.kotlin.fir.declarations
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirEnumEntryDeserializedAccessExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||||
import org.jetbrains.kotlin.fir.references.toResolvedEnumEntrySymbol
|
import org.jetbrains.kotlin.fir.references.toResolvedEnumEntrySymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.name.StandardClassIds
|
import org.jetbrains.kotlin.name.StandardClassIds
|
||||||
|
|
||||||
fun FirRegularClass.getRetention(session: FirSession): AnnotationRetention {
|
fun FirRegularClass.getRetention(session: FirSession): AnnotationRetention {
|
||||||
@@ -22,14 +25,15 @@ fun FirRegularClassSymbol.getRetention(session: FirSession): AnnotationRetention
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun FirAnnotation.getRetention(): AnnotationRetention? {
|
fun FirAnnotation.getRetention(): AnnotationRetention? {
|
||||||
val propertyAccess = findArgumentByName(StandardClassIds.Annotations.ParameterNames.retentionValue) as? FirQualifiedAccessExpression
|
val (enumId, entryName) = findArgumentByName(StandardClassIds.Annotations.ParameterNames.retentionValue)
|
||||||
val callableId = propertyAccess?.calleeReference?.toResolvedEnumEntrySymbol()?.callableId ?: return null
|
?.extractEnumValueArgumentInfo()
|
||||||
|
?: return null
|
||||||
|
|
||||||
if (callableId.classId != StandardClassIds.AnnotationRetention) {
|
if (enumId != StandardClassIds.AnnotationRetention) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
return AnnotationRetention.entries.firstOrNull { it.name == callableId.callableName.asString() }
|
return AnnotationRetention.entries.firstOrNull { it.name == entryName.asString() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirDeclaration.getRetentionAnnotation(session: FirSession): FirAnnotation? {
|
fun FirDeclaration.getRetentionAnnotation(session: FirSession): FirAnnotation? {
|
||||||
|
|||||||
+3
-2
@@ -245,8 +245,9 @@ private fun FirAnnotation.getDeprecationLevel(): DeprecationLevelValue? {
|
|||||||
?.unwrapArgument()
|
?.unwrapArgument()
|
||||||
?: arguments.lastOrNull()
|
?: arguments.lastOrNull()
|
||||||
} ?: return null
|
} ?: return null
|
||||||
val targetExpression = argument as? FirQualifiedAccessExpression ?: return null
|
|
||||||
val targetName = (targetExpression.calleeReference as? FirNamedReference)?.name?.asString() ?: return null
|
val targetName = argument.extractEnumValueArgumentInfo()?.enumEntryName?.asString() ?: return null
|
||||||
|
|
||||||
return DeprecationLevelValue.values().find { it.name == targetName }
|
return DeprecationLevelValue.values().find { it.name == targetName }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+66
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2024 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.fir.declarations
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.containingClassLookupTag
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.name.StandardClassIds
|
||||||
|
|
||||||
|
fun FirAnnotation.useSiteTargetsFromMetaAnnotation(session: FirSession): Set<AnnotationUseSiteTarget> {
|
||||||
|
return toAnnotationClass(session)
|
||||||
|
?.annotations
|
||||||
|
?.find { it.toAnnotationClassIdSafe(session) == StandardClassIds.Annotations.Target }
|
||||||
|
?.findUseSiteTargets(session)
|
||||||
|
?: DEFAULT_USE_SITE_TARGETS
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirAnnotation.findUseSiteTargets(session: FirSession): Set<AnnotationUseSiteTarget> {
|
||||||
|
return buildSet {
|
||||||
|
forEachAnnotationTarget(session) {
|
||||||
|
USE_SITE_TARGET_NAME_MAP[it.identifier]?.let { addAll(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// See [org.jetbrains.kotlin.descriptors.annotations.KotlinTarget.USE_SITE_MAPPING] (it's in reverse)
|
||||||
|
private val USE_SITE_TARGET_NAME_MAP = mapOf(
|
||||||
|
"FIELD" to setOf(AnnotationUseSiteTarget.FIELD, AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD),
|
||||||
|
"FILE" to setOf(AnnotationUseSiteTarget.FILE),
|
||||||
|
"PROPERTY" to setOf(AnnotationUseSiteTarget.PROPERTY),
|
||||||
|
"PROPERTY_GETTER" to setOf(AnnotationUseSiteTarget.PROPERTY_GETTER),
|
||||||
|
"PROPERTY_SETTER" to setOf(AnnotationUseSiteTarget.PROPERTY_SETTER),
|
||||||
|
"VALUE_PARAMETER" to setOf(
|
||||||
|
AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER,
|
||||||
|
AnnotationUseSiteTarget.RECEIVER,
|
||||||
|
AnnotationUseSiteTarget.SETTER_PARAMETER,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
// See [org.jetbrains.kotlin.descriptors.annotations.KotlinTarget] (the second argument of each entry)
|
||||||
|
private val DEFAULT_USE_SITE_TARGETS: Set<AnnotationUseSiteTarget> =
|
||||||
|
USE_SITE_TARGET_NAME_MAP.values.fold(setOf<AnnotationUseSiteTarget>()) { a, b -> a + b } - setOf(AnnotationUseSiteTarget.FILE)
|
||||||
|
|
||||||
|
fun FirAnnotation.forEachAnnotationTarget(session: FirSession, action: (Name) -> Unit) {
|
||||||
|
fun take(arg: FirExpression) {
|
||||||
|
val callableSymbol = arg.toResolvedCallableSymbol(session) ?: return
|
||||||
|
if (callableSymbol.containingClassLookupTag()?.classId == StandardClassIds.AnnotationTarget) {
|
||||||
|
action(callableSymbol.callableId.callableName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this is FirAnnotationCall) {
|
||||||
|
for (arg in argumentList.arguments) {
|
||||||
|
arg.unwrapAndFlattenArgument(flattenArrays = true).forEach(::take)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
argumentMapping.mapping[StandardClassIds.Annotations.ParameterNames.targetAllowedTargets]
|
||||||
|
?.unwrapAndFlattenArgument(flattenArrays = true)
|
||||||
|
?.forEach(::take)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user