[FIR] Add to new types of annotation predicates

- `ParentAnnotatedWith` matches declarations, which parent is annotated
- `HasAnnotatedWith` matches declarations, which have at least one
     direct child with annotation

Also, `DeclarationPredicate.Any` is removed, because there is no
  intention to support lookup for all declarations in module

^KT-52486 Fixed
This commit is contained in:
Dmitriy Novozhilov
2022-05-25 17:37:29 +03:00
committed by teamcity
parent c62257bbab
commit 23c69f8d17
15 changed files with 226 additions and 82 deletions
@@ -15,17 +15,6 @@ sealed class DeclarationPredicate {
abstract fun <R, D> accept(visitor: DeclarationPredicateVisitor<R, D>, data: D): R
object Any : DeclarationPredicate() {
override val annotations: Set<AnnotationFqn>
get() = emptySet()
override val metaAnnotations: Set<AnnotationFqn>
get() = emptySet()
override fun <R, D> accept(visitor: DeclarationPredicateVisitor<R, D>, data: D): R {
return visitor.visitAny(this, data)
}
}
class Or(val a: DeclarationPredicate, val b: DeclarationPredicate) : DeclarationPredicate() {
override val annotations: Set<AnnotationFqn> = a.annotations + b.annotations
override val metaAnnotations: Set<AnnotationFqn> = a.metaAnnotations + b.metaAnnotations
@@ -45,6 +34,12 @@ sealed class DeclarationPredicate {
}
}
// ------------------------------------ Annotated ------------------------------------
/**
* Base class for all predicates with specific annotations
* Declaration will be matched if at least one of [annotations] is found
*/
sealed class Annotated(final override val annotations: Set<AnnotationFqn>) : DeclarationPredicate() {
init {
require(annotations.isNotEmpty()) {
@@ -60,28 +55,109 @@ sealed class Annotated(final override val annotations: Set<AnnotationFqn>) : Dec
}
}
/**
* Matches declarations, which are annotated with [annotations]
*
* @Ann
* fun foo() {}
*
* fun bar(@Ann param: Int) {}
*
* @Ann
* class A {
* fun baz() {}
*
* class Nested {
* fun foobar() {}
* }
* }
*
* Matched symbols: [fun foo, parameter `param` from fun bar, class A]
*/
class AnnotatedWith(annotations: Set<AnnotationFqn>) : Annotated(annotations) {
override fun <R, D> accept(visitor: DeclarationPredicateVisitor<R, D>, data: D): R {
return visitor.visitAnnotatedWith(this, data)
}
}
/**
* Matches declaration, if one of its containers annotated with [annotations]
*
* @Ann
* fun foo() {}
*
* fun bar(@Ann param: Int) {}
*
* @Ann
* class A {
* fun baz() {}
*
* class Nested {
* fun foobar() {}
* }
* }
*
* Matched symbols: [fun A.baz, class Nested, fun Nested.foobar]
*/
class UnderAnnotatedWith(annotations: Set<AnnotationFqn>) : Annotated(annotations) {
override fun <R, D> accept(visitor: DeclarationPredicateVisitor<R, D>, data: D): R {
return visitor.visitUnderAnnotatedWith(this, data)
}
}
// annotation class AllOpen // from library
/*
@AllOpen
annotation class MyOpen
@MyOpen
class MyClass
/**
* Matches declaration, if its direct container annotated with [annotations]
*
* @Ann
* fun foo() {}
*
* fun bar(@Ann param: Int) {}
*
* @Ann
* class A {
* fun baz() {}
*
* class Nested {
* fun foobar() {}
* }
* }
*
* Matched symbols: [fun A.baz, class Nested]
*/
class ParentAnnotatedWith(annotations: Set<AnnotationFqn>) : Annotated(annotations) {
override fun <R, D> accept(visitor: DeclarationPredicateVisitor<R, D>, data: D): R {
return visitor.visitParentAnnotatedWith(this, data)
}
}
/**
* Matches declaration, if one of its direct child declarations annotated with [annotations]
*
* @Ann
* fun foo() {}
*
* fun bar(@Ann param: Int) {}
*
* class A {
* @Ann
* fun baz() {}
*
* class Nested {
* fun foobar() {}
* }
* }
*
* Matched symbols: [fun bar, class A]
*/
class HasAnnotatedWith(annotations: Set<AnnotationFqn>) : Annotated(annotations) {
override fun <R, D> accept(visitor: DeclarationPredicateVisitor<R, D>, data: D): R {
return visitor.visitHasAnnotatedWith(this, data)
}
}
// ------------------------------------ MetaAnnotated ------------------------------------
sealed class MetaAnnotated(final override val metaAnnotations: Set<AnnotationFqn>) : DeclarationPredicate() {
init {
@@ -110,6 +186,18 @@ class UnderMetaAnnotated(metaAnnotations: Set<AnnotationFqn>) : MetaAnnotated(me
}
}
class ParentMetaAnnotatedWith(metaAnnotations: Set<AnnotationFqn>) : MetaAnnotated(metaAnnotations) {
override fun <R, D> accept(visitor: DeclarationPredicateVisitor<R, D>, data: D): R {
return visitor.visitParentMetaAnnotatedWith(this, data)
}
}
class HasMetaAnnotatedWith(metaAnnotations: Set<AnnotationFqn>) : MetaAnnotated(metaAnnotations) {
override fun <R, D> accept(visitor: DeclarationPredicateVisitor<R, D>, data: D): R {
return visitor.visitHasMetaAnnotatedWith(this, data)
}
}
// -------------------------------------------- DSL --------------------------------------------
infix fun DeclarationPredicate.or(other: DeclarationPredicate): DeclarationPredicate = DeclarationPredicate.Or(this, other)
@@ -117,18 +205,30 @@ infix fun DeclarationPredicate.and(other: DeclarationPredicate): DeclarationPred
// ------------------- varargs -------------------
fun under(vararg annotations: AnnotationFqn): DeclarationPredicate = UnderAnnotatedWith(annotations.toSet())
fun has(vararg annotations: AnnotationFqn): DeclarationPredicate = AnnotatedWith(annotations.toSet())
fun annotated(vararg annotations: AnnotationFqn): DeclarationPredicate = AnnotatedWith(annotations.toSet())
fun parentAnnotated(vararg annotations: AnnotationFqn): DeclarationPredicate = ParentAnnotatedWith(annotations.toSet())
fun hasAnnotated(vararg annotations: AnnotationFqn): DeclarationPredicate = HasAnnotatedWith(annotations.toSet())
fun metaUnder(vararg metaAnnotations: AnnotationFqn): DeclarationPredicate = UnderMetaAnnotated(metaAnnotations.toSet())
fun metaHas(vararg metaAnnotations: AnnotationFqn): DeclarationPredicate = AnnotatedWithMeta(metaAnnotations.toSet())
fun metaAnnotated(vararg metaAnnotations: AnnotationFqn): DeclarationPredicate = AnnotatedWithMeta(metaAnnotations.toSet())
fun parentMetaAnnotated(vararg metaAnnotations: AnnotationFqn): DeclarationPredicate = ParentMetaAnnotatedWith(metaAnnotations.toSet())
fun hasMetaAnnotated(vararg metaAnnotations: AnnotationFqn): DeclarationPredicate = HasMetaAnnotatedWith(metaAnnotations.toSet())
fun hasOrUnder(vararg annotations: AnnotationFqn): DeclarationPredicate = has(*annotations) or under(*annotations)
fun metaHasOrUnder(vararg metaAnnotations: AnnotationFqn): DeclarationPredicate = metaHas(*metaAnnotations) or metaUnder(*metaAnnotations)
fun annotatedOrUnder(vararg annotations: AnnotationFqn): DeclarationPredicate = annotated(*annotations) or under(*annotations)
fun metaAnnotatedOrUnder(vararg metaAnnotations: AnnotationFqn): DeclarationPredicate =
metaAnnotated(*metaAnnotations) or metaUnder(*metaAnnotations)
// ------------------- colelctions -------------------
// ------------------- collections -------------------
fun under(annotations: Collection<AnnotationFqn>): DeclarationPredicate = UnderAnnotatedWith(annotations.toSet())
fun has(annotations: Collection<AnnotationFqn>): DeclarationPredicate = AnnotatedWith(annotations.toSet())
fun metaUnder(metaAnnotations: Collection<AnnotationFqn>): DeclarationPredicate = UnderMetaAnnotated(metaAnnotations.toSet())
fun metaHas(metaAnnotations: Collection<AnnotationFqn>): DeclarationPredicate = AnnotatedWithMeta(metaAnnotations.toSet())
fun annotated(annotations: Collection<AnnotationFqn>): DeclarationPredicate = AnnotatedWith(annotations.toSet())
fun parentAnnotated(annotations: Collection<AnnotationFqn>): DeclarationPredicate = ParentAnnotatedWith(annotations.toSet())
fun hasAnnotated(annotations: Collection<AnnotationFqn>): DeclarationPredicate = HasAnnotatedWith(annotations.toSet())
fun hasOrUnder(annotations: Collection<AnnotationFqn>): DeclarationPredicate = has(annotations) or under(annotations)
fun metaHasOrUnder(metaAnnotations: Collection<AnnotationFqn>): DeclarationPredicate = metaHas(metaAnnotations) or metaUnder(metaAnnotations)
fun metaUnder(metaAnnotations: Collection<AnnotationFqn>): DeclarationPredicate = UnderMetaAnnotated(metaAnnotations.toSet())
fun metaAnnotated(metaAnnotations: Collection<AnnotationFqn>): DeclarationPredicate = AnnotatedWithMeta(metaAnnotations.toSet())
fun parentMetaAnnotated(metaAnnotations: Collection<AnnotationFqn>): DeclarationPredicate = ParentMetaAnnotatedWith(metaAnnotations.toSet())
fun hasMetaAnnotated(metaAnnotations: Collection<AnnotationFqn>): DeclarationPredicate = HasMetaAnnotatedWith(metaAnnotations.toSet())
fun annotatedOrUnder(annotations: Collection<AnnotationFqn>): DeclarationPredicate = annotated(annotations) or under(annotations)
fun metaAnnotatedOrUnder(metaAnnotations: Collection<AnnotationFqn>): DeclarationPredicate =
metaAnnotated(metaAnnotations) or metaUnder(metaAnnotations)
@@ -7,9 +7,6 @@ package org.jetbrains.kotlin.fir.extensions.predicate
abstract class DeclarationPredicateVisitor<R, D> {
abstract fun visitPredicate(predicate: DeclarationPredicate, data: D): R
open fun visitAny(predicate: DeclarationPredicate.Any, data: D): R {
return visitPredicate(predicate, data)
}
open fun visitAnd(predicate: DeclarationPredicate.And, data: D): R {
return visitPredicate(predicate, data)
@@ -31,6 +28,14 @@ abstract class DeclarationPredicateVisitor<R, D> {
return visitAnnotated(predicate, data)
}
open fun visitParentAnnotatedWith(predicate: ParentAnnotatedWith, data: D): R {
return visitAnnotated(predicate, data)
}
open fun visitHasAnnotatedWith(predicate: HasAnnotatedWith, data: D): R {
return visitAnnotated(predicate, data)
}
open fun visitMetaAnnotated(predicate: MetaAnnotated, data: D): R {
return visitPredicate(predicate, data)
}
@@ -42,4 +47,12 @@ abstract class DeclarationPredicateVisitor<R, D> {
open fun visitUnderMetaAnnotated(predicate: UnderMetaAnnotated, data: D): R {
return visitMetaAnnotated(predicate, data)
}
open fun visitParentMetaAnnotatedWith(predicate: ParentMetaAnnotatedWith, data: D): R {
return visitMetaAnnotated(predicate, data)
}
open fun visitHasMetaAnnotatedWith(predicate: HasMetaAnnotatedWith, data: D): R {
return visitMetaAnnotated(predicate, data)
}
}