[FIR] Add ability to specify if meta annotation itself should match metaAnnotated predicate
^KT-55843 Fixed
This commit is contained in:
committed by
Space Team
parent
e88a6af7a0
commit
4363b0815c
+7
-5
@@ -140,7 +140,7 @@ class FirPredicateBasedProviderImpl(private val session: FirSession) : FirPredic
|
||||
|
||||
override fun visitMetaAnnotatedWith(predicate: AbstractPredicate.MetaAnnotatedWith<P>, data: FirDeclaration): Boolean {
|
||||
return data.annotations.any { annotation ->
|
||||
annotation.markedWithMetaAnnotation(session, data, predicate.metaAnnotations)
|
||||
annotation.markedWithMetaAnnotation(session, data, predicate.metaAnnotations, predicate.includeItself)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,23 +190,25 @@ class FirPredicateBasedProviderImpl(private val session: FirSession) : FirPredic
|
||||
fun FirAnnotation.markedWithMetaAnnotation(
|
||||
session: FirSession,
|
||||
containingDeclaration: FirDeclaration,
|
||||
metaAnnotations: Set<AnnotationFqn>
|
||||
metaAnnotations: Set<AnnotationFqn>,
|
||||
includeItself: Boolean
|
||||
): Boolean {
|
||||
containingDeclaration.symbol.lazyResolveToPhase(FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS)
|
||||
return annotationTypeRef.coneTypeSafe<ConeKotlinType>()
|
||||
?.toRegularClassSymbol(session)
|
||||
.markedWithMetaAnnotationImpl(session, metaAnnotations, mutableSetOf())
|
||||
.markedWithMetaAnnotationImpl(session, metaAnnotations, includeItself, mutableSetOf())
|
||||
}
|
||||
|
||||
fun FirRegularClassSymbol?.markedWithMetaAnnotationImpl(
|
||||
session: FirSession,
|
||||
metaAnnotations: Set<AnnotationFqn>,
|
||||
includeItself: Boolean,
|
||||
visited: MutableSet<FirRegularClassSymbol>
|
||||
): Boolean {
|
||||
if (this == null) return false
|
||||
if (!visited.add(this)) return false
|
||||
if (this.classId.asSingleFqName() in metaAnnotations) return true
|
||||
if (this.classId.asSingleFqName() in metaAnnotations) return includeItself
|
||||
return this.resolvedCompilerAnnotationsWithClassIds
|
||||
.mapNotNull { it.annotationTypeRef.coneTypeSafe<ConeKotlinType>()?.toRegularClassSymbol(session) }
|
||||
.any { it.markedWithMetaAnnotationImpl(session, metaAnnotations, visited) }
|
||||
.any { it.markedWithMetaAnnotationImpl(session, metaAnnotations, includeItself = true, visited) }
|
||||
}
|
||||
|
||||
+1
-1
@@ -144,7 +144,7 @@ internal abstract class AbstractFirSpecificAnnotationResolveTransformer(
|
||||
}
|
||||
|
||||
private fun ConeKotlinType.markedWithMetaAnnotation(session: FirSession, metaAnnotations: Set<AnnotationFqn>): Boolean {
|
||||
return toRegularClassSymbol(session).markedWithMetaAnnotationImpl(session, metaAnnotations, mutableSetOf())
|
||||
return toRegularClassSymbol(session).markedWithMetaAnnotationImpl(session, metaAnnotations, includeItself = true, mutableSetOf())
|
||||
}
|
||||
|
||||
|
||||
|
||||
+8
-1
@@ -169,8 +169,13 @@ sealed interface AbstractPredicate<P : AbstractPredicate<P>> {
|
||||
|
||||
/**
|
||||
* Matches declarations, which are annotated with annotations which are annotated with [metaAnnotations]
|
||||
*
|
||||
* [includeItself] flag determines if declaration, annotated with meta-annotation itself will
|
||||
* be considered as matching to predicate
|
||||
*
|
||||
* Relation "annotation with meta annotation" is transitive. E.g. in snippet below some declaration will
|
||||
* be matched with predicate MetaAnnotatedWith("Ann") if it is annotated with `@Ann`, `@Some` or `@Other`
|
||||
* be matched with predicate MetaAnnotatedWith("Ann") if it is annotated with `@Ann` (if [includeItself] set to true),
|
||||
* `@Some` or `@Other`
|
||||
*
|
||||
* @Ann
|
||||
* annotation class Some
|
||||
@@ -200,6 +205,8 @@ sealed interface AbstractPredicate<P : AbstractPredicate<P>> {
|
||||
* and can not be used for global lookup
|
||||
*/
|
||||
sealed interface MetaAnnotatedWith<P : AbstractPredicate<P>> : AbstractPredicate<P> {
|
||||
val includeItself: Boolean
|
||||
|
||||
override fun <R, D> accept(visitor: PredicateVisitor<P, R, D>, data: D): R {
|
||||
return visitor.visitMetaAnnotatedWith(this, data)
|
||||
}
|
||||
|
||||
+6
-3
@@ -91,7 +91,8 @@ sealed class DeclarationPredicate : AbstractPredicate<DeclarationPredicate> {
|
||||
// ------------------------------------ MetaAnnotated ------------------------------------
|
||||
|
||||
class MetaAnnotatedWith(
|
||||
override val metaAnnotations: Set<AnnotationFqn>
|
||||
override val metaAnnotations: Set<AnnotationFqn>,
|
||||
override val includeItself: Boolean
|
||||
) : DeclarationPredicate(), AbstractPredicate.MetaAnnotatedWith<DeclarationPredicate> {
|
||||
init {
|
||||
require(metaAnnotations.isNotEmpty()) {
|
||||
@@ -122,7 +123,8 @@ sealed class DeclarationPredicate : AbstractPredicate<DeclarationPredicate> {
|
||||
override fun annotatedOrUnder(vararg annotations: AnnotationFqn): DeclarationPredicate =
|
||||
annotated(*annotations) or ancestorAnnotated(*annotations)
|
||||
|
||||
fun metaAnnotated(vararg metaAnnotations: AnnotationFqn): DeclarationPredicate = MetaAnnotatedWith(metaAnnotations.toSet())
|
||||
fun metaAnnotated(vararg metaAnnotations: AnnotationFqn, includeItself: Boolean): DeclarationPredicate =
|
||||
MetaAnnotatedWith(metaAnnotations.toSet(), includeItself)
|
||||
|
||||
// ------------------- collections -------------------
|
||||
override fun annotated(annotations: Collection<AnnotationFqn>): DeclarationPredicate = AnnotatedWith(annotations.toSet())
|
||||
@@ -137,7 +139,8 @@ sealed class DeclarationPredicate : AbstractPredicate<DeclarationPredicate> {
|
||||
override fun annotatedOrUnder(annotations: Collection<AnnotationFqn>): DeclarationPredicate =
|
||||
annotated(annotations) or ancestorAnnotated(annotations)
|
||||
|
||||
fun metaAnnotated(metaAnnotations: Collection<AnnotationFqn>): DeclarationPredicate = MetaAnnotatedWith(metaAnnotations.toSet())
|
||||
fun metaAnnotated(metaAnnotations: Collection<AnnotationFqn>, includeItself: Boolean): DeclarationPredicate =
|
||||
MetaAnnotatedWith(metaAnnotations.toSet(), includeItself)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
Reference in New Issue
Block a user