[FIR] Rework predicates system
Now predicates are split into LookupPredicate and DeclarationPredicate hierarchies. First one allows to perform global search for declarations and second one allows to check if some declaration matches the predicate. Predicates with meta annotations are excluded from LookupPredicates, because it's impossible to create index of annotations with meta-annotations, because they can be located inside binary dependencies (so to achieve this we need to scan the whole classpath). Also only one predicate with meta-annotations is left in DeclarationPredicate hierarchy (AnnotatedWithMeta) ^KT-53874 Fixed ^KT-53590 Fixed
This commit is contained in:
committed by
Space Team
parent
7a9a71a089
commit
246dc985a6
+1
-1
@@ -95,7 +95,7 @@ internal class LLFirNonUnderContentRootSessionFactory(private val project: Proje
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
register(FirPredicateBasedProvider::class, FirEmptyPredicateBasedProvider())
|
register(FirPredicateBasedProvider::class, FirEmptyPredicateBasedProvider)
|
||||||
register(FirDependenciesSymbolProvider::class, dependencyProvider)
|
register(FirDependenciesSymbolProvider::class, dependencyProvider)
|
||||||
register(FirDependenciesSymbolProvider::class, dependencyProvider)
|
register(FirDependenciesSymbolProvider::class, dependencyProvider)
|
||||||
register(FirJvmTypeMapper::class, FirJvmTypeMapper(this))
|
register(FirJvmTypeMapper::class, FirJvmTypeMapper(this))
|
||||||
|
|||||||
+53
-61
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.util.getContainingFile
|
|||||||
import org.jetbrains.kotlin.analysis.providers.KotlinAnnotationsResolver
|
import org.jetbrains.kotlin.analysis.providers.KotlinAnnotationsResolver
|
||||||
import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProvider
|
import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProvider
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
|
||||||
import org.jetbrains.kotlin.fir.caches.FirCache
|
import org.jetbrains.kotlin.fir.caches.FirCache
|
||||||
import org.jetbrains.kotlin.fir.caches.createCache
|
import org.jetbrains.kotlin.fir.caches.createCache
|
||||||
import org.jetbrains.kotlin.fir.caches.firCachesFactory
|
import org.jetbrains.kotlin.fir.caches.firCachesFactory
|
||||||
@@ -23,15 +22,20 @@ import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||||
import org.jetbrains.kotlin.fir.extensions.AnnotationFqn
|
import org.jetbrains.kotlin.fir.extensions.AnnotationFqn
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirPredicateBasedProvider
|
import org.jetbrains.kotlin.fir.extensions.FirPredicateBasedProvider
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirRegisteredPluginAnnotations
|
import org.jetbrains.kotlin.fir.extensions.FirRegisteredPluginAnnotations
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.*
|
import org.jetbrains.kotlin.fir.extensions.predicate.AbstractPredicate
|
||||||
|
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
|
||||||
|
import org.jetbrains.kotlin.fir.extensions.predicate.LookupPredicate
|
||||||
|
import org.jetbrains.kotlin.fir.extensions.predicate.PredicateVisitor
|
||||||
import org.jetbrains.kotlin.fir.extensions.registeredPluginAnnotations
|
import org.jetbrains.kotlin.fir.extensions.registeredPluginAnnotations
|
||||||
import org.jetbrains.kotlin.fir.psi
|
import org.jetbrains.kotlin.fir.psi
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.getCorrespondingClassSymbolOrNull
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.classId
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitorVoid
|
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitorVoid
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
@@ -52,8 +56,8 @@ internal class LLFirIdePredicateBasedProvider(
|
|||||||
private val declarationOwnersCache: FirCache<FirFile, FirOwnersStorage, Nothing?> =
|
private val declarationOwnersCache: FirCache<FirFile, FirOwnersStorage, Nothing?> =
|
||||||
session.firCachesFactory.createCache { firFile -> FirOwnersStorage.collectOwners(firFile) }
|
session.firCachesFactory.createCache { firFile -> FirOwnersStorage.collectOwners(firFile) }
|
||||||
|
|
||||||
override fun getSymbolsByPredicate(predicate: DeclarationPredicate): List<FirBasedSymbol<*>> {
|
override fun getSymbolsByPredicate(predicate: LookupPredicate): List<FirBasedSymbol<*>> {
|
||||||
val annotations = registeredPluginAnnotations.getAnnotationsForPredicate(predicate)
|
val annotations = predicate.annotations
|
||||||
val annotatedDeclarations = annotations
|
val annotatedDeclarations = annotations
|
||||||
.asSequence()
|
.asSequence()
|
||||||
.flatMap { annotationsResolver.declarationsByAnnotation(ClassId.topLevel(it)) }
|
.flatMap { annotationsResolver.declarationsByAnnotation(ClassId.topLevel(it)) }
|
||||||
@@ -99,80 +103,83 @@ internal class LLFirIdePredicateBasedProvider(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun matches(predicate: DeclarationPredicate, declaration: FirDeclaration): Boolean {
|
override fun matches(predicate: AbstractPredicate<*>, declaration: FirDeclaration): Boolean {
|
||||||
return predicate.accept(matcher, declaration)
|
return when (predicate) {
|
||||||
|
is DeclarationPredicate -> predicate.accept(declarationPredicateMatcher, declaration)
|
||||||
|
is LookupPredicate -> predicate.accept(lookupPredicateMatcher, declaration)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val matcher: Matcher = Matcher()
|
private val declarationPredicateMatcher = Matcher<DeclarationPredicate>()
|
||||||
|
private val lookupPredicateMatcher = Matcher<LookupPredicate>()
|
||||||
|
|
||||||
private inner class Matcher : DeclarationPredicateVisitor<Boolean, FirDeclaration>() {
|
private inner class Matcher<P : AbstractPredicate<P>> : PredicateVisitor<P, Boolean, FirDeclaration>() {
|
||||||
override fun visitPredicate(predicate: DeclarationPredicate, data: FirDeclaration): Boolean {
|
override fun visitPredicate(predicate: AbstractPredicate<P>, data: FirDeclaration): Boolean {
|
||||||
error("When overrides for all possible DeclarationPredicate subtypes are implemented, " +
|
error(
|
||||||
"this method should never be called, but it was called with $predicate")
|
"When overrides for all possible DeclarationPredicate subtypes are implemented, " +
|
||||||
|
"this method should never be called, but it was called with $predicate"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitAnd(predicate: DeclarationPredicate.And, data: FirDeclaration): Boolean {
|
override fun visitAnd(predicate: AbstractPredicate.And<P>, data: FirDeclaration): Boolean {
|
||||||
return predicate.a.accept(this, data) && predicate.b.accept(this, data)
|
return predicate.a.accept(this, data) && predicate.b.accept(this, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitOr(predicate: DeclarationPredicate.Or, data: FirDeclaration): Boolean {
|
override fun visitOr(predicate: AbstractPredicate.Or<P>, data: FirDeclaration): Boolean {
|
||||||
return predicate.a.accept(this, data) || predicate.b.accept(this, data)
|
return predicate.a.accept(this, data) || predicate.b.accept(this, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitAnnotatedWith(predicate: AnnotatedWith, data: FirDeclaration): Boolean {
|
override fun visitAnnotatedWith(predicate: AbstractPredicate.AnnotatedWith<P>, data: FirDeclaration): Boolean {
|
||||||
return annotationsOnDeclaration(data).any { it in predicate.annotations }
|
return annotationsOnDeclaration(data).any { it in predicate.annotations }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitAncestorAnnotatedWith(predicate: AncestorAnnotatedWith, data: FirDeclaration): Boolean {
|
override fun visitAncestorAnnotatedWith(predicate: AbstractPredicate.AncestorAnnotatedWith<P>, data: FirDeclaration): Boolean {
|
||||||
return annotationsOnOuterDeclarations(data).any { it in predicate.annotations }
|
return annotationsOnOuterDeclarations(data).any { it in predicate.annotations }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitMetaAnnotatedWith(predicate: MetaAnnotatedWith, data: FirDeclaration): Boolean {
|
override fun visitMetaAnnotatedWith(predicate: AbstractPredicate.MetaAnnotatedWith<P>, data: FirDeclaration): Boolean {
|
||||||
return metaAnnotationsOnDeclaration(data).any { it in predicate.metaAnnotations }
|
val visited = mutableSetOf<FirRegularClassSymbol>()
|
||||||
|
return data.annotations.any { annotation ->
|
||||||
|
annotation.markedWithMetaAnnotation(predicate.metaAnnotations, visited)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitAncestorMetaAnnotatedWith(predicate: AncestorMetaAnnotatedWith, data: FirDeclaration): Boolean {
|
private fun FirAnnotation.markedWithMetaAnnotation(
|
||||||
return metaAnnotationsOnOuterDeclarations(data).any { it in predicate.metaAnnotations }
|
metaAnnotations: Set<AnnotationFqn>,
|
||||||
|
visited: MutableSet<FirRegularClassSymbol>
|
||||||
|
): Boolean {
|
||||||
|
val symbol = this.getCorrespondingClassSymbolOrNull(session) ?: return false
|
||||||
|
if (!visited.add(symbol)) return false
|
||||||
|
if (symbol.classId.asSingleFqName() in metaAnnotations) return true
|
||||||
|
if (symbol.resolvedAnnotationsWithClassIds.any { it.markedWithMetaAnnotation(metaAnnotations, visited) }) return true
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitParentAnnotatedWith(predicate: ParentAnnotatedWith, data: FirDeclaration): Boolean {
|
override fun visitParentAnnotatedWith(predicate: AbstractPredicate.ParentAnnotatedWith<P>, data: FirDeclaration): Boolean {
|
||||||
val parent = data.directParentDeclaration ?: return false
|
val parent = data.directParentDeclaration ?: return false
|
||||||
val parentPredicate = AnnotatedWith(predicate.annotations)
|
val parentPredicate = DeclarationPredicate.AnnotatedWith(predicate.annotations)
|
||||||
|
|
||||||
return parentPredicate.accept(this, parent)
|
return parentPredicate.accept(declarationPredicateMatcher, parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitHasAnnotatedWith(predicate: HasAnnotatedWith, data: FirDeclaration): Boolean {
|
override fun visitHasAnnotatedWith(predicate: AbstractPredicate.HasAnnotatedWith<P>, data: FirDeclaration): Boolean {
|
||||||
val childPredicate = AnnotatedWith(predicate.annotations)
|
val childPredicate = DeclarationPredicate.AnnotatedWith(predicate.annotations)
|
||||||
|
|
||||||
return data.anyDirectChildDeclarationMatches(childPredicate)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitParentMetaAnnotatedWith(predicate: ParentMetaAnnotatedWith, data: FirDeclaration): Boolean {
|
|
||||||
val parent = data.directParentDeclaration ?: return false
|
|
||||||
val parentPredicate = MetaAnnotatedWith(predicate.annotations)
|
|
||||||
|
|
||||||
return parentPredicate.accept(this, parent)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitHasMetaAnnotatedWith(predicate: HasMetaAnnotatedWith, data: FirDeclaration): Boolean {
|
|
||||||
val childPredicate = MetaAnnotatedWith(predicate.annotations)
|
|
||||||
|
|
||||||
return data.anyDirectChildDeclarationMatches(childPredicate)
|
return data.anyDirectChildDeclarationMatches(childPredicate)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val FirDeclaration.directParentDeclaration: FirDeclaration?
|
private val FirDeclaration.directParentDeclaration: FirDeclaration?
|
||||||
get() = getOwnersOfDeclaration(this)?.lastOrNull()?.fir
|
get() = getOwnersOfDeclaration(this)?.lastOrNull()?.fir
|
||||||
|
}
|
||||||
|
|
||||||
private fun FirDeclaration.anyDirectChildDeclarationMatches(childPredicate: DeclarationPredicate): Boolean {
|
private fun FirDeclaration.anyDirectChildDeclarationMatches(childPredicate: DeclarationPredicate): Boolean {
|
||||||
var result = false
|
var result = false
|
||||||
|
|
||||||
this.forEachDirectChildDeclaration {
|
this.forEachDirectChildDeclaration {
|
||||||
result = result || childPredicate.accept(this@Matcher, it)
|
result = result || childPredicate.accept(declarationPredicateMatcher, it)
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun annotationsOnDeclaration(declaration: FirDeclaration): Set<AnnotationFqn> {
|
private fun annotationsOnDeclaration(declaration: FirDeclaration): Set<AnnotationFqn> {
|
||||||
@@ -193,24 +200,9 @@ internal class LLFirIdePredicateBasedProvider(
|
|||||||
return psiAnnotations.map { it.asSingleFqName() }.toSet()
|
return psiAnnotations.map { it.asSingleFqName() }.toSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun metaAnnotationsOnDeclaration(declaration: FirDeclaration): Set<AnnotationFqn> {
|
|
||||||
val directAnnotations = annotationsOnDeclaration(declaration)
|
|
||||||
val metaAnnotations = directAnnotations
|
|
||||||
.asSequence()
|
|
||||||
.mapNotNull { declarationProvider.getAllClassesByClassId(ClassId.topLevel(it)).singleOrNull() }
|
|
||||||
.flatMap { annotationsResolver.annotationsOnDeclaration(it) }
|
|
||||||
.toSet()
|
|
||||||
|
|
||||||
return metaAnnotations.map { it.asSingleFqName() }.toSet()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun annotationsOnOuterDeclarations(declaration: FirDeclaration): Set<AnnotationFqn> {
|
private fun annotationsOnOuterDeclarations(declaration: FirDeclaration): Set<AnnotationFqn> {
|
||||||
return getOwnersOfDeclaration(declaration)?.flatMap { annotationsOnDeclaration(it.fir) }.orEmpty().toSet()
|
return getOwnersOfDeclaration(declaration)?.flatMap { annotationsOnDeclaration(it.fir) }.orEmpty().toSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun metaAnnotationsOnOuterDeclarations(declaration: FirDeclaration): Set<AnnotationFqn> {
|
|
||||||
return getOwnersOfDeclaration(declaration)?.flatMap { metaAnnotationsOnDeclaration(it.fir) }.orEmpty().toSet()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class FirOwnersStorage(private val declarationToOwner: Map<FirDeclaration, List<FirBasedSymbol<*>>>) {
|
private class FirOwnersStorage(private val declarationToOwner: Map<FirDeclaration, List<FirBasedSymbol<*>>>) {
|
||||||
|
|||||||
+2
-18
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.providers
|
|||||||
import org.jetbrains.kotlin.analysis.providers.KotlinAnnotationsResolver
|
import org.jetbrains.kotlin.analysis.providers.KotlinAnnotationsResolver
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.caches.*
|
import org.jetbrains.kotlin.fir.caches.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
|
||||||
import org.jetbrains.kotlin.fir.extensions.AbstractFirRegisteredPluginAnnotations
|
import org.jetbrains.kotlin.fir.extensions.AbstractFirRegisteredPluginAnnotations
|
||||||
import org.jetbrains.kotlin.fir.extensions.AnnotationFqn
|
import org.jetbrains.kotlin.fir.extensions.AnnotationFqn
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
@@ -26,25 +25,14 @@ internal class LLFirIdeRegisteredPluginAnnotations(
|
|||||||
get() = allAnnotationsCache.getValue()
|
get() = allAnnotationsCache.getValue()
|
||||||
|
|
||||||
private val allAnnotationsCache: FirLazyValue<Set<AnnotationFqn>, Nothing?> = session.firCachesFactory.createLazyValue {
|
private val allAnnotationsCache: FirLazyValue<Set<AnnotationFqn>, Nothing?> = session.firCachesFactory.createLazyValue {
|
||||||
// at this point, both metaAnnotations and annotationsFromPlugins should be collected
|
// at this point, annotationsFromPlugins should be collected
|
||||||
val result = metaAnnotations.flatMapTo(mutableSetOf()) { getAnnotationsWithMetaAnnotation(it) }
|
annotationsFromPlugins
|
||||||
|
|
||||||
if (result.isEmpty()) {
|
|
||||||
annotationsFromPlugins
|
|
||||||
} else {
|
|
||||||
result += annotationsFromPlugins
|
|
||||||
result
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MetaAnnotation -> Annotations
|
// MetaAnnotation -> Annotations
|
||||||
private val annotationsWithMetaAnnotationCache: FirCache<AnnotationFqn, Set<AnnotationFqn>, Nothing?> =
|
private val annotationsWithMetaAnnotationCache: FirCache<AnnotationFqn, Set<AnnotationFqn>, Nothing?> =
|
||||||
session.firCachesFactory.createCache { metaAnnotation -> collectAnnotationsWithMetaAnnotation(metaAnnotation) }
|
session.firCachesFactory.createCache { metaAnnotation -> collectAnnotationsWithMetaAnnotation(metaAnnotation) }
|
||||||
|
|
||||||
override fun getAnnotationsWithMetaAnnotation(metaAnnotation: AnnotationFqn): Collection<AnnotationFqn> {
|
|
||||||
return annotationsWithMetaAnnotationCache.getValue(metaAnnotation)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun collectAnnotationsWithMetaAnnotation(metaAnnotation: AnnotationFqn): Set<FqName> {
|
private fun collectAnnotationsWithMetaAnnotation(metaAnnotation: AnnotationFqn): Set<FqName> {
|
||||||
val annotatedDeclarations = annotationsResolver.declarationsByAnnotation(ClassId.topLevel(metaAnnotation))
|
val annotatedDeclarations = annotationsResolver.declarationsByAnnotation(ClassId.topLevel(metaAnnotation))
|
||||||
|
|
||||||
@@ -59,8 +47,4 @@ internal class LLFirIdeRegisteredPluginAnnotations(
|
|||||||
override fun saveAnnotationsFromPlugin(annotations: Collection<AnnotationFqn>) {
|
override fun saveAnnotationsFromPlugin(annotations: Collection<AnnotationFqn>) {
|
||||||
annotationsFromPlugins += annotations
|
annotationsFromPlugins += annotations
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun registerUserDefinedAnnotation(metaAnnotation: AnnotationFqn, annotationClasses: Collection<FirRegularClass>) {
|
|
||||||
error("This method should never be called in IDE mode")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -214,7 +214,7 @@ internal object LLFirSessionFactory {
|
|||||||
// We need FirRegisteredPluginAnnotations during extensions' registration process
|
// We need FirRegisteredPluginAnnotations during extensions' registration process
|
||||||
val annotationsResolver = project.createAnnotationResolver(contentScope)
|
val annotationsResolver = project.createAnnotationResolver(contentScope)
|
||||||
register(FirRegisteredPluginAnnotations::class, LLFirIdeRegisteredPluginAnnotations(this@session, annotationsResolver))
|
register(FirRegisteredPluginAnnotations::class, LLFirIdeRegisteredPluginAnnotations(this@session, annotationsResolver))
|
||||||
register(FirPredicateBasedProvider::class, FirEmptyPredicateBasedProvider())
|
register(FirPredicateBasedProvider::class, FirEmptyPredicateBasedProvider)
|
||||||
|
|
||||||
val dependencyProvider = LLFirDependentModuleProvidersByProviders(this) {
|
val dependencyProvider = LLFirDependentModuleProvidersByProviders(this) {
|
||||||
// <all libraries scope> - <current library scope>
|
// <all libraries scope> - <current library scope>
|
||||||
|
|||||||
+1
-2
@@ -24,7 +24,7 @@ internal class LLFirDesignatedAnnotationsResolveTransformed(
|
|||||||
if (!designationIterator.hasNext()) {
|
if (!designationIterator.hasNext()) {
|
||||||
val declaration = designation.declaration
|
val declaration = designation.declaration
|
||||||
if (declaration is FirRegularClass || declaration is FirTypeAlias) {
|
if (declaration is FirRegularClass || declaration is FirTypeAlias) {
|
||||||
declaration.transform<FirDeclaration, Mode>(this, Mode.RegularAnnotations)
|
declaration.transform<FirDeclaration, Nothing?>(this, null)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -63,5 +63,4 @@ internal class LLFirDesignatedAnnotationsResolveTransformed(
|
|||||||
// todo add proper check that COMPILER_REQUIRED_ANNOTATIONS are resolved
|
// todo add proper check that COMPILER_REQUIRED_ANNOTATIONS are resolved
|
||||||
// checkNestedDeclarationsAreResolved(declaration)
|
// checkNestedDeclarationsAreResolved(declaration)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+45
-30
@@ -12,17 +12,23 @@ import org.jetbrains.kotlin.fir.FirSession
|
|||||||
import org.jetbrains.kotlin.fir.NoMutableState
|
import org.jetbrains.kotlin.fir.NoMutableState
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.*
|
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||||
|
import org.jetbrains.kotlin.fir.extensions.predicate.AbstractPredicate
|
||||||
|
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
|
||||||
|
import org.jetbrains.kotlin.fir.extensions.predicate.LookupPredicate
|
||||||
|
import org.jetbrains.kotlin.fir.extensions.predicate.PredicateVisitor
|
||||||
import org.jetbrains.kotlin.fir.resolve.fqName
|
import org.jetbrains.kotlin.fir.resolve.fqName
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.getCorrespondingClassSymbolOrNull
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||||
|
|
||||||
@NoMutableState
|
@NoMutableState
|
||||||
class FirPredicateBasedProviderImpl(private val session: FirSession) : FirPredicateBasedProvider() {
|
class FirPredicateBasedProviderImpl(private val session: FirSession) : FirPredicateBasedProvider() {
|
||||||
private val registeredPluginAnnotations = session.registeredPluginAnnotations
|
private val registeredPluginAnnotations = session.registeredPluginAnnotations
|
||||||
private val cache = Cache()
|
private val cache = Cache()
|
||||||
|
|
||||||
override fun getSymbolsByPredicate(predicate: DeclarationPredicate): List<FirBasedSymbol<*>> {
|
override fun getSymbolsByPredicate(predicate: LookupPredicate): List<FirBasedSymbol<*>> {
|
||||||
val annotations = registeredPluginAnnotations.getAnnotationsForPredicate(predicate)
|
val annotations = predicate.annotations
|
||||||
if (annotations.isEmpty()) return emptyList()
|
if (annotations.isEmpty()) return emptyList()
|
||||||
val declarations = annotations.flatMapTo(mutableSetOf()) {
|
val declarations = annotations.flatMapTo(mutableSetOf()) {
|
||||||
cache.declarationByAnnotation[it] + cache.declarationsUnderAnnotated[it]
|
cache.declarationByAnnotation[it] + cache.declarationsUnderAnnotated[it]
|
||||||
@@ -76,66 +82,75 @@ class FirPredicateBasedProviderImpl(private val session: FirSession) : FirPredic
|
|||||||
|
|
||||||
// ---------------------------------- Matching ----------------------------------
|
// ---------------------------------- Matching ----------------------------------
|
||||||
|
|
||||||
override fun matches(predicate: DeclarationPredicate, declaration: FirDeclaration): Boolean {
|
override fun matches(predicate: AbstractPredicate<*>, declaration: FirDeclaration): Boolean {
|
||||||
return predicate.accept(matcher, declaration)
|
return when (predicate) {
|
||||||
|
is DeclarationPredicate -> predicate.accept(declarationPredicateMatcher, declaration)
|
||||||
|
is LookupPredicate -> predicate.accept(lookupPredicateMatcher, declaration)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val matcher = Matcher()
|
private val declarationPredicateMatcher = Matcher<DeclarationPredicate>()
|
||||||
|
private val lookupPredicateMatcher = Matcher<LookupPredicate>()
|
||||||
|
|
||||||
private inner class Matcher : DeclarationPredicateVisitor<Boolean, FirDeclaration>() {
|
private inner class Matcher<P : AbstractPredicate<P>> : PredicateVisitor<P, Boolean, FirDeclaration>() {
|
||||||
override fun visitPredicate(predicate: DeclarationPredicate, data: FirDeclaration): Boolean {
|
override fun visitPredicate(predicate: AbstractPredicate<P>, data: FirDeclaration): Boolean {
|
||||||
throw IllegalStateException("Should not be there")
|
throw IllegalStateException("Should not be there")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitAnd(predicate: DeclarationPredicate.And, data: FirDeclaration): Boolean {
|
override fun visitAnd(predicate: AbstractPredicate.And<P>, data: FirDeclaration): Boolean {
|
||||||
return predicate.a.accept(this, data) && predicate.b.accept(this, data)
|
return predicate.a.accept(this, data) && predicate.b.accept(this, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitOr(predicate: DeclarationPredicate.Or, data: FirDeclaration): Boolean {
|
override fun visitOr(predicate: AbstractPredicate.Or<P>, data: FirDeclaration): Boolean {
|
||||||
return predicate.a.accept(this, data) || predicate.b.accept(this, data)
|
return predicate.a.accept(this, data) || predicate.b.accept(this, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------ Annotated ------------------------------------
|
// ------------------------------------ Annotated ------------------------------------
|
||||||
|
|
||||||
override fun visitAnnotatedWith(predicate: AnnotatedWith, data: FirDeclaration): Boolean {
|
override fun visitAnnotatedWith(predicate: AbstractPredicate.AnnotatedWith<P>, data: FirDeclaration): Boolean {
|
||||||
return matchWith(data, predicate.annotations)
|
return matchWith(data, predicate.annotations)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitAncestorAnnotatedWith(predicate: AncestorAnnotatedWith, data: FirDeclaration): Boolean {
|
override fun visitAncestorAnnotatedWith(
|
||||||
|
predicate: AbstractPredicate.AncestorAnnotatedWith<P>,
|
||||||
|
data: FirDeclaration
|
||||||
|
): Boolean {
|
||||||
return matchUnder(data, predicate.annotations)
|
return matchUnder(data, predicate.annotations)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitParentAnnotatedWith(predicate: ParentAnnotatedWith, data: FirDeclaration): Boolean {
|
override fun visitParentAnnotatedWith(
|
||||||
|
predicate: AbstractPredicate.ParentAnnotatedWith<P>,
|
||||||
|
data: FirDeclaration
|
||||||
|
): Boolean {
|
||||||
return matchParentWith(data, predicate.annotations)
|
return matchParentWith(data, predicate.annotations)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitHasAnnotatedWith(predicate: HasAnnotatedWith, data: FirDeclaration): Boolean {
|
override fun visitHasAnnotatedWith(predicate: AbstractPredicate.HasAnnotatedWith<P>, data: FirDeclaration): Boolean {
|
||||||
return matchHasAnnotatedWith(data, predicate.annotations)
|
return matchHasAnnotatedWith(data, predicate.annotations)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------ Meta Annotated ------------------------------------
|
// ------------------------------------ Meta-annotated ------------------------------------
|
||||||
|
|
||||||
override fun visitMetaAnnotatedWith(predicate: MetaAnnotatedWith, data: FirDeclaration): Boolean {
|
override fun visitMetaAnnotatedWith(predicate: AbstractPredicate.MetaAnnotatedWith<P>, data: FirDeclaration): Boolean {
|
||||||
return matchWith(data, predicate.userDefinedAnnotations)
|
val visited = mutableSetOf<FirRegularClassSymbol>()
|
||||||
|
return data.annotations.any { annotation ->
|
||||||
|
annotation.markedWithMetaAnnotation(predicate.metaAnnotations, visited)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitAncestorMetaAnnotatedWith(predicate: AncestorMetaAnnotatedWith, data: FirDeclaration): Boolean {
|
private fun FirAnnotation.markedWithMetaAnnotation(
|
||||||
return matchUnder(data, predicate.userDefinedAnnotations)
|
metaAnnotations: Set<AnnotationFqn>,
|
||||||
}
|
visited: MutableSet<FirRegularClassSymbol>
|
||||||
|
): Boolean {
|
||||||
override fun visitParentMetaAnnotatedWith(predicate: ParentMetaAnnotatedWith, data: FirDeclaration): Boolean {
|
val symbol = this.getCorrespondingClassSymbolOrNull(session) ?: return false
|
||||||
return matchParentWith(data, predicate.userDefinedAnnotations)
|
if (!visited.add(symbol)) return false
|
||||||
}
|
if (symbol.classId.asSingleFqName() in metaAnnotations) return true
|
||||||
|
if (symbol.resolvedAnnotationsWithClassIds.any { it.markedWithMetaAnnotation(metaAnnotations, visited) }) return true
|
||||||
override fun visitHasMetaAnnotatedWith(predicate: HasMetaAnnotatedWith, data: FirDeclaration): Boolean {
|
return false
|
||||||
return matchHasAnnotatedWith(data, predicate.userDefinedAnnotations)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------ Utilities ------------------------------------
|
// ------------------------------------ Utilities ------------------------------------
|
||||||
|
|
||||||
private val MetaAnnotated.userDefinedAnnotations: Set<AnnotationFqn>
|
|
||||||
get() = metaAnnotations.flatMapTo(mutableSetOf()) { registeredPluginAnnotations.getAnnotationsWithMetaAnnotation(it) }
|
|
||||||
|
|
||||||
private fun matchWith(declaration: FirDeclaration, annotations: Set<AnnotationFqn>): Boolean {
|
private fun matchWith(declaration: FirDeclaration, annotations: Set<AnnotationFqn>): Boolean {
|
||||||
return cache.annotationsOfDeclaration[declaration].any { it in annotations }
|
return cache.annotationsOfDeclaration[declaration].any { it in annotations }
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-58
@@ -5,39 +5,21 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.extensions
|
package org.jetbrains.kotlin.fir.extensions
|
||||||
|
|
||||||
import com.google.common.collect.LinkedHashMultimap
|
|
||||||
import com.google.common.collect.Multimap
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.FirSessionComponent
|
import org.jetbrains.kotlin.fir.FirSessionComponent
|
||||||
import org.jetbrains.kotlin.fir.NoMutableState
|
import org.jetbrains.kotlin.fir.NoMutableState
|
||||||
import org.jetbrains.kotlin.fir.caches.FirCache
|
import org.jetbrains.kotlin.fir.extensions.predicate.AbstractPredicate
|
||||||
import org.jetbrains.kotlin.fir.caches.createCache
|
|
||||||
import org.jetbrains.kotlin.fir.caches.firCachesFactory
|
|
||||||
import org.jetbrains.kotlin.fir.caches.getValue
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
|
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
|
||||||
|
import org.jetbrains.kotlin.fir.extensions.predicate.LookupPredicate
|
||||||
|
|
||||||
abstract class FirRegisteredPluginAnnotations(protected val session: FirSession) : FirSessionComponent {
|
abstract class FirRegisteredPluginAnnotations(protected val session: FirSession) : FirSessionComponent {
|
||||||
/**
|
/**
|
||||||
* Contains all annotations that can be targeted by the plugins. It includes the annotations directly mentioned by the plugin,
|
* Contains all annotations that can be targeted by lookup predicates from plugins
|
||||||
* and all the user-defined annotations which are meta-annotated by the annotations from the [metaAnnotations] list.
|
|
||||||
*/
|
*/
|
||||||
abstract val annotations: Set<AnnotationFqn>
|
abstract val annotations: Set<AnnotationFqn>
|
||||||
|
|
||||||
/**
|
|
||||||
* Contains meta-annotations that can be targeted by the plugins.
|
|
||||||
*/
|
|
||||||
abstract val metaAnnotations: Set<AnnotationFqn>
|
|
||||||
|
|
||||||
val hasRegisteredAnnotations: Boolean
|
val hasRegisteredAnnotations: Boolean
|
||||||
get() = annotations.isNotEmpty() || metaAnnotations.isNotEmpty()
|
get() = annotations.isNotEmpty()
|
||||||
|
|
||||||
abstract fun getAnnotationsWithMetaAnnotation(metaAnnotation: AnnotationFqn): Collection<AnnotationFqn>
|
|
||||||
|
|
||||||
abstract fun registerUserDefinedAnnotation(metaAnnotation: AnnotationFqn, annotationClasses: Collection<FirRegularClass>)
|
|
||||||
|
|
||||||
abstract fun getAnnotationsForPredicate(predicate: DeclarationPredicate): Set<AnnotationFqn>
|
|
||||||
|
|
||||||
@PluginServicesInitialization
|
@PluginServicesInitialization
|
||||||
abstract fun initialize()
|
abstract fun initialize()
|
||||||
@@ -50,33 +32,16 @@ abstract class FirRegisteredPluginAnnotations(protected val session: FirSession)
|
|||||||
* It also has some common code in it.
|
* It also has some common code in it.
|
||||||
*/
|
*/
|
||||||
abstract class AbstractFirRegisteredPluginAnnotations(session: FirSession) : FirRegisteredPluginAnnotations(session) {
|
abstract class AbstractFirRegisteredPluginAnnotations(session: FirSession) : FirRegisteredPluginAnnotations(session) {
|
||||||
final override val metaAnnotations: MutableSet<AnnotationFqn> = mutableSetOf()
|
|
||||||
|
|
||||||
private val annotationsForPredicateCache: FirCache<DeclarationPredicate, Set<AnnotationFqn>, Nothing?> =
|
|
||||||
session.firCachesFactory.createCache { predicate ->
|
|
||||||
collectAnnotations(predicate)
|
|
||||||
}
|
|
||||||
|
|
||||||
final override fun getAnnotationsForPredicate(predicate: DeclarationPredicate): Set<AnnotationFqn> {
|
|
||||||
return annotationsForPredicateCache.getValue(predicate)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun collectAnnotations(predicate: DeclarationPredicate): Set<AnnotationFqn> {
|
|
||||||
val result = predicate.metaAnnotations.flatMapTo(mutableSetOf()) { getAnnotationsWithMetaAnnotation(it) }
|
|
||||||
if (result.isEmpty()) return predicate.annotations
|
|
||||||
result += predicate.annotations
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
@PluginServicesInitialization
|
@PluginServicesInitialization
|
||||||
final override fun initialize() {
|
final override fun initialize() {
|
||||||
val registrar = object : FirDeclarationPredicateRegistrar() {
|
val registrar = object : FirDeclarationPredicateRegistrar() {
|
||||||
val predicates = mutableListOf<DeclarationPredicate>()
|
val predicates = mutableListOf<AbstractPredicate<*>>()
|
||||||
override fun register(vararg predicates: DeclarationPredicate) {
|
|
||||||
|
override fun register(vararg predicates: AbstractPredicate<*>) {
|
||||||
this.predicates += predicates
|
this.predicates += predicates
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun register(predicates: Collection<DeclarationPredicate>) {
|
override fun register(predicates: Collection<AbstractPredicate<*>>) {
|
||||||
this.predicates += predicates
|
this.predicates += predicates
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -89,7 +54,6 @@ abstract class AbstractFirRegisteredPluginAnnotations(session: FirSession) : Fir
|
|||||||
|
|
||||||
for (predicate in registrar.predicates) {
|
for (predicate in registrar.predicates) {
|
||||||
saveAnnotationsFromPlugin(predicate.annotations)
|
saveAnnotationsFromPlugin(predicate.annotations)
|
||||||
metaAnnotations += predicate.metaAnnotations
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,23 +64,9 @@ abstract class AbstractFirRegisteredPluginAnnotations(session: FirSession) : Fir
|
|||||||
class FirRegisteredPluginAnnotationsImpl(session: FirSession) : AbstractFirRegisteredPluginAnnotations(session) {
|
class FirRegisteredPluginAnnotationsImpl(session: FirSession) : AbstractFirRegisteredPluginAnnotations(session) {
|
||||||
override val annotations: MutableSet<AnnotationFqn> = mutableSetOf()
|
override val annotations: MutableSet<AnnotationFqn> = mutableSetOf()
|
||||||
|
|
||||||
// MetaAnnotation -> Annotations
|
|
||||||
private val userDefinedAnnotations: Multimap<AnnotationFqn, AnnotationFqn> = LinkedHashMultimap.create()
|
|
||||||
|
|
||||||
override fun getAnnotationsWithMetaAnnotation(metaAnnotation: AnnotationFqn): Collection<AnnotationFqn> {
|
|
||||||
return userDefinedAnnotations[metaAnnotation]
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun saveAnnotationsFromPlugin(annotations: Collection<AnnotationFqn>) {
|
override fun saveAnnotationsFromPlugin(annotations: Collection<AnnotationFqn>) {
|
||||||
this.annotations += annotations
|
this.annotations += annotations
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun registerUserDefinedAnnotation(metaAnnotation: AnnotationFqn, annotationClasses: Collection<FirRegularClass>) {
|
|
||||||
require(annotationClasses.all { it.classKind == ClassKind.ANNOTATION_CLASS })
|
|
||||||
val annotations = annotationClasses.map { it.symbol.classId.asSingleFqName() }
|
|
||||||
this.annotations += annotations
|
|
||||||
userDefinedAnnotations.putAll(metaAnnotation, annotations)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val FirSession.registeredPluginAnnotations: FirRegisteredPluginAnnotations by FirSession.sessionComponentAccessor()
|
val FirSession.registeredPluginAnnotations: FirRegisteredPluginAnnotations by FirSession.sessionComponentAccessor()
|
||||||
|
|||||||
+21
-84
@@ -5,11 +5,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.transformers.plugin
|
package org.jetbrains.kotlin.fir.resolve.transformers.plugin
|
||||||
|
|
||||||
import com.google.common.collect.LinkedHashMultimap
|
|
||||||
import com.google.common.collect.Multimap
|
|
||||||
import kotlinx.collections.immutable.PersistentList
|
import kotlinx.collections.immutable.PersistentList
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.caches.firCachesFactory
|
import org.jetbrains.kotlin.fir.caches.firCachesFactory
|
||||||
@@ -21,10 +18,8 @@ import org.jetbrains.kotlin.fir.expressions.FirStatement
|
|||||||
import org.jetbrains.kotlin.fir.extensions.*
|
import org.jetbrains.kotlin.fir.extensions.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
|
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
|
||||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
import org.jetbrains.kotlin.fir.resolve.fqName
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.*
|
import org.jetbrains.kotlin.fir.resolve.transformers.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.plugin.FirCompilerRequiredAnnotationsResolveTransformer.Mode
|
|
||||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||||
import org.jetbrains.kotlin.fir.types.FirUserTypeRef
|
import org.jetbrains.kotlin.fir.types.FirUserTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||||
@@ -33,7 +28,6 @@ import org.jetbrains.kotlin.fir.withFileAnalysisExceptionWrapping
|
|||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.name.StandardClassIds
|
|
||||||
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.Deprecated
|
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.Deprecated
|
||||||
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.DeprecatedSinceKotlin
|
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.DeprecatedSinceKotlin
|
||||||
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.JvmRecord
|
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.JvmRecord
|
||||||
@@ -46,25 +40,9 @@ class FirCompilerRequiredAnnotationsResolveProcessor(
|
|||||||
|
|
||||||
override fun process(files: Collection<FirFile>) {
|
override fun process(files: Collection<FirFile>) {
|
||||||
val transformer = FirCompilerRequiredAnnotationsResolveTransformer(session, scopeSession)
|
val transformer = FirCompilerRequiredAnnotationsResolveTransformer(session, scopeSession)
|
||||||
val registeredPluginAnnotations = session.registeredPluginAnnotations
|
|
||||||
if (!registeredPluginAnnotations.hasRegisteredAnnotations) {
|
|
||||||
files.forEach {
|
|
||||||
withFileAnalysisExceptionWrapping(it) {
|
|
||||||
it.transformSingle(transformer, Mode.RegularAnnotations)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (registeredPluginAnnotations.metaAnnotations.isNotEmpty()) {
|
|
||||||
files.forEach {
|
|
||||||
withFileAnalysisExceptionWrapping(it) {
|
|
||||||
it.transformSingle(transformer, Mode.MetaAnnotations)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
files.forEach {
|
files.forEach {
|
||||||
withFileAnalysisExceptionWrapping(it) {
|
withFileAnalysisExceptionWrapping(it) {
|
||||||
it.transformSingle(transformer, Mode.RegularAnnotations)
|
it.transformSingle(transformer, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,42 +61,21 @@ class FirCompilerRequiredAnnotationsResolveProcessor(
|
|||||||
open class FirCompilerRequiredAnnotationsResolveTransformer(
|
open class FirCompilerRequiredAnnotationsResolveTransformer(
|
||||||
final override val session: FirSession,
|
final override val session: FirSession,
|
||||||
scopeSession: ScopeSession
|
scopeSession: ScopeSession
|
||||||
) : FirAbstractPhaseTransformer<Mode>(COMPILER_REQUIRED_ANNOTATIONS) {
|
) : FirAbstractPhaseTransformer<Nothing?>(COMPILER_REQUIRED_ANNOTATIONS) {
|
||||||
enum class Mode {
|
|
||||||
MetaAnnotations,
|
|
||||||
RegularAnnotations
|
|
||||||
}
|
|
||||||
|
|
||||||
private val annotationTransformer = FirAnnotationResolveTransformer(session, scopeSession)
|
private val annotationTransformer = FirAnnotationResolveTransformer(session, scopeSession)
|
||||||
private val importTransformer = FirPartialImportResolveTransformer(session)
|
private val importTransformer = FirPartialImportResolveTransformer(session)
|
||||||
|
|
||||||
val extensionService = session.extensionService
|
val extensionService = session.extensionService
|
||||||
override fun <E : FirElement> transformElement(element: E, data: Mode): E {
|
override fun <E : FirElement> transformElement(element: E, data: Nothing?): E {
|
||||||
throw IllegalStateException("Should not be here")
|
throw IllegalStateException("Should not be here")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transformFile(file: FirFile, data: Mode): FirFile {
|
override fun transformFile(file: FirFile, data: Nothing?): FirFile {
|
||||||
checkSessionConsistency(file)
|
checkSessionConsistency(file)
|
||||||
val registeredPluginAnnotations = session.registeredPluginAnnotations
|
val registeredPluginAnnotations = session.registeredPluginAnnotations
|
||||||
val regularAnnotations: Set<AnnotationFqn>
|
val regularAnnotations = registeredPluginAnnotations.annotations
|
||||||
val metaAnnotations: Set<AnnotationFqn>
|
|
||||||
when (data) {
|
|
||||||
Mode.MetaAnnotations -> {
|
|
||||||
regularAnnotations = emptySet()
|
|
||||||
metaAnnotations = registeredPluginAnnotations.metaAnnotations
|
|
||||||
}
|
|
||||||
Mode.RegularAnnotations -> {
|
|
||||||
regularAnnotations = registeredPluginAnnotations.annotations
|
|
||||||
metaAnnotations = emptySet()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val newAnnotations = file.resolveAnnotations(regularAnnotations, metaAnnotations)
|
file.resolveAnnotations(regularAnnotations)
|
||||||
if (!newAnnotations.isEmpty) {
|
|
||||||
for (metaAnnotation in newAnnotations.keySet()) {
|
|
||||||
registeredPluginAnnotations.registerUserDefinedAnnotation(metaAnnotation, newAnnotations[metaAnnotation])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return file
|
return file
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,27 +85,21 @@ open class FirCompilerRequiredAnnotationsResolveTransformer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transformRegularClass(regularClass: FirRegularClass, data: Mode): FirStatement {
|
override fun transformRegularClass(regularClass: FirRegularClass, data: Nothing?): FirStatement {
|
||||||
return annotationTransformer.transformRegularClass(regularClass, LinkedHashMultimap.create())
|
return annotationTransformer.transformRegularClass(regularClass, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transformTypeAlias(typeAlias: FirTypeAlias, data: Mode): FirStatement {
|
override fun transformTypeAlias(typeAlias: FirTypeAlias, data: Nothing?): FirStatement {
|
||||||
return annotationTransformer.transformTypeAlias(typeAlias, LinkedHashMultimap.create())
|
return annotationTransformer.transformTypeAlias(typeAlias, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirFile.resolveAnnotations(
|
private fun FirFile.resolveAnnotations(annotations: Set<AnnotationFqn>) {
|
||||||
annotations: Set<AnnotationFqn>,
|
val acceptableNames = annotations
|
||||||
metaAnnotations: Set<AnnotationFqn>
|
|
||||||
): Multimap<AnnotationFqn, FirRegularClass> {
|
|
||||||
val acceptableNames = annotations + metaAnnotations
|
|
||||||
importTransformer.acceptableFqNames = acceptableNames
|
importTransformer.acceptableFqNames = acceptableNames
|
||||||
this.transformImports(importTransformer, null)
|
this.transformImports(importTransformer, null)
|
||||||
|
|
||||||
annotationTransformer.acceptableFqNames = acceptableNames
|
annotationTransformer.acceptableFqNames = acceptableNames
|
||||||
annotationTransformer.metaAnnotations = metaAnnotations
|
this.transform<FirFile, Nothing?>(annotationTransformer, null)
|
||||||
val newAnnotations = LinkedHashMultimap.create<AnnotationFqn, FirRegularClass>()
|
|
||||||
this.transform<FirFile, Multimap<AnnotationFqn, FirRegularClass>>(annotationTransformer, newAnnotations)
|
|
||||||
return newAnnotations
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,9 +115,7 @@ private class FirPartialImportResolveTransformer(
|
|||||||
private class FirAnnotationResolveTransformer(
|
private class FirAnnotationResolveTransformer(
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
scopeSession: ScopeSession
|
scopeSession: ScopeSession
|
||||||
) : FirAbstractAnnotationResolveTransformer<Multimap<AnnotationFqn, FirRegularClass>, PersistentList<FirDeclaration>>(
|
) : FirAbstractAnnotationResolveTransformer<Nothing?, PersistentList<FirDeclaration>>(session, scopeSession) {
|
||||||
session, scopeSession
|
|
||||||
) {
|
|
||||||
companion object {
|
companion object {
|
||||||
private val REQUIRED_ANNOTATIONS: Set<ClassId> = setOf(
|
private val REQUIRED_ANNOTATIONS: Set<ClassId> = setOf(
|
||||||
Deprecated, DeprecatedSinceKotlin, WasExperimental, JvmRecord
|
Deprecated, DeprecatedSinceKotlin, WasExperimental, JvmRecord
|
||||||
@@ -178,7 +127,7 @@ private class FirAnnotationResolveTransformer(
|
|||||||
private val predicateBasedProvider = session.predicateBasedProvider
|
private val predicateBasedProvider = session.predicateBasedProvider
|
||||||
|
|
||||||
var acceptableFqNames: Set<AnnotationFqn> = emptySet()
|
var acceptableFqNames: Set<AnnotationFqn> = emptySet()
|
||||||
var metaAnnotations: Set<AnnotationFqn> = emptySet()
|
|
||||||
private val typeResolverTransformer: FirSpecificTypeResolverTransformer = FirSpecificTypeResolverTransformer(
|
private val typeResolverTransformer: FirSpecificTypeResolverTransformer = FirSpecificTypeResolverTransformer(
|
||||||
session,
|
session,
|
||||||
errorTypeAsResolved = false
|
errorTypeAsResolved = false
|
||||||
@@ -200,14 +149,11 @@ private class FirAnnotationResolveTransformer(
|
|||||||
owners = state
|
owners = state
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transformAnnotationCall(annotationCall: FirAnnotationCall, data: Multimap<AnnotationFqn, FirRegularClass>): FirStatement {
|
override fun transformAnnotationCall(annotationCall: FirAnnotationCall, data: Nothing?): FirStatement {
|
||||||
return transformAnnotation(annotationCall, data)
|
return transformAnnotation(annotationCall, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transformAnnotation(
|
override fun transformAnnotation(annotation: FirAnnotation, data: Nothing?): FirStatement {
|
||||||
annotation: FirAnnotation,
|
|
||||||
data: Multimap<AnnotationFqn, FirRegularClass>
|
|
||||||
): FirStatement {
|
|
||||||
val annotationTypeRef = annotation.annotationTypeRef
|
val annotationTypeRef = annotation.annotationTypeRef
|
||||||
if (annotationTypeRef !is FirUserTypeRef) return annotation
|
if (annotationTypeRef !is FirUserTypeRef) return annotation
|
||||||
val name = annotationTypeRef.qualifier.last().name
|
val name = annotationTypeRef.qualifier.last().name
|
||||||
@@ -224,36 +170,27 @@ private class FirAnnotationResolveTransformer(
|
|||||||
return transformedAnnotation
|
return transformedAnnotation
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transformRegularClass(
|
override fun transformRegularClass(regularClass: FirRegularClass, data: Nothing?): FirStatement {
|
||||||
regularClass: FirRegularClass,
|
|
||||||
data: Multimap<AnnotationFqn, FirRegularClass>
|
|
||||||
): FirStatement {
|
|
||||||
withClassDeclarationCleanup(classDeclarationsStack, regularClass) {
|
withClassDeclarationCleanup(classDeclarationsStack, regularClass) {
|
||||||
return super.transformRegularClass(regularClass, data).also {
|
return super.transformRegularClass(regularClass, data).also {
|
||||||
if (regularClass.classKind == ClassKind.ANNOTATION_CLASS && metaAnnotations.isNotEmpty()) {
|
|
||||||
val annotations = regularClass.annotations.mapNotNull { it.fqName(session) }
|
|
||||||
for (annotation in annotations.filter { it in metaAnnotations }) {
|
|
||||||
data.put(annotation, regularClass)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
calculateDeprecations(regularClass)
|
calculateDeprecations(regularClass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transformTypeAlias(typeAlias: FirTypeAlias, data: Multimap<AnnotationFqn, FirRegularClass>): FirTypeAlias {
|
override fun transformTypeAlias(typeAlias: FirTypeAlias, data: Nothing?): FirTypeAlias {
|
||||||
return super.transformTypeAlias(typeAlias, data).also {
|
return super.transformTypeAlias(typeAlias, data).also {
|
||||||
calculateDeprecations(typeAlias)
|
calculateDeprecations(typeAlias)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transformDeclaration(declaration: FirDeclaration, data: Multimap<AnnotationFqn, FirRegularClass>): FirDeclaration {
|
override fun transformDeclaration(declaration: FirDeclaration, data: Nothing?): FirDeclaration {
|
||||||
return super.transformDeclaration(declaration, data).also {
|
return super.transformDeclaration(declaration, data).also {
|
||||||
predicateBasedProvider.registerAnnotatedDeclaration(declaration, owners)
|
predicateBasedProvider.registerAnnotatedDeclaration(declaration, owners)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transformFile(file: FirFile, data: Multimap<AnnotationFqn, FirRegularClass>): FirFile {
|
override fun transformFile(file: FirFile, data: Nothing?): FirFile {
|
||||||
withFile(file) {
|
withFile(file) {
|
||||||
return super.transformFile(file, data)
|
return super.transformFile(file, data)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,9 @@
|
|||||||
package org.jetbrains.kotlin.fir.extensions
|
package org.jetbrains.kotlin.fir.extensions
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.extensions.predicate.AbstractPredicate
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
|
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
|
||||||
|
import org.jetbrains.kotlin.fir.extensions.predicate.LookupPredicate
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
@@ -38,8 +40,8 @@ data class FirExtensionPointName(val name: Name) {
|
|||||||
|
|
||||||
// todo: KDOC
|
// todo: KDOC
|
||||||
abstract class FirDeclarationPredicateRegistrar {
|
abstract class FirDeclarationPredicateRegistrar {
|
||||||
abstract fun register(vararg predicates: DeclarationPredicate)
|
abstract fun register(vararg predicates: AbstractPredicate<*>)
|
||||||
abstract fun register(predicates: Collection<DeclarationPredicate>)
|
abstract fun register(predicates: Collection<AbstractPredicate<*>>)
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresOptIn
|
@RequiresOptIn
|
||||||
|
|||||||
+10
-8
@@ -11,11 +11,13 @@ import org.jetbrains.kotlin.fir.FirSessionComponent
|
|||||||
import org.jetbrains.kotlin.fir.NoMutableState
|
import org.jetbrains.kotlin.fir.NoMutableState
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
|
import org.jetbrains.kotlin.fir.extensions.predicate.AbstractPredicate
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
|
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
|
||||||
|
import org.jetbrains.kotlin.fir.extensions.predicate.LookupPredicate
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
|
|
||||||
abstract class FirPredicateBasedProvider : FirSessionComponent {
|
abstract class FirPredicateBasedProvider : FirSessionComponent {
|
||||||
abstract fun getSymbolsByPredicate(predicate: DeclarationPredicate): List<FirBasedSymbol<*>>
|
abstract fun getSymbolsByPredicate(predicate: LookupPredicate): List<FirBasedSymbol<*>>
|
||||||
abstract fun getOwnersOfDeclaration(declaration: FirDeclaration): List<FirBasedSymbol<*>>?
|
abstract fun getOwnersOfDeclaration(declaration: FirDeclaration): List<FirBasedSymbol<*>>?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -23,17 +25,17 @@ abstract class FirPredicateBasedProvider : FirSessionComponent {
|
|||||||
* @see FirRegisteredPluginAnnotations.annotations
|
* @see FirRegisteredPluginAnnotations.annotations
|
||||||
*/
|
*/
|
||||||
abstract fun fileHasPluginAnnotations(file: FirFile): Boolean
|
abstract fun fileHasPluginAnnotations(file: FirFile): Boolean
|
||||||
abstract fun matches(predicate: DeclarationPredicate, declaration: FirDeclaration): Boolean
|
abstract fun matches(predicate: AbstractPredicate<*>, declaration: FirDeclaration): Boolean
|
||||||
|
|
||||||
fun matches(predicate: DeclarationPredicate, declaration: FirBasedSymbol<*>): Boolean {
|
fun matches(predicate: AbstractPredicate<*>, declaration: FirBasedSymbol<*>): Boolean {
|
||||||
return matches(predicate, declaration.fir)
|
return matches(predicate, declaration.fir)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun matches(predicates: List<DeclarationPredicate>, declaration: FirDeclaration): Boolean {
|
fun matches(predicates: List<AbstractPredicate<*>>, declaration: FirDeclaration): Boolean {
|
||||||
return predicates.any { matches(it, declaration) }
|
return predicates.any { matches(it, declaration) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun matches(predicates: List<DeclarationPredicate>, declaration: FirBasedSymbol<*>): Boolean {
|
fun matches(predicates: List<AbstractPredicate<*>>, declaration: FirBasedSymbol<*>): Boolean {
|
||||||
return matches(predicates, declaration.fir)
|
return matches(predicates, declaration.fir)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,14 +43,14 @@ abstract class FirPredicateBasedProvider : FirSessionComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NoMutableState
|
@NoMutableState
|
||||||
class FirEmptyPredicateBasedProvider(): FirPredicateBasedProvider() {
|
object FirEmptyPredicateBasedProvider : FirPredicateBasedProvider() {
|
||||||
override fun getSymbolsByPredicate(predicate: DeclarationPredicate): List<FirBasedSymbol<*>> = emptyList()
|
override fun getSymbolsByPredicate(predicate: LookupPredicate): List<FirBasedSymbol<*>> = emptyList()
|
||||||
|
|
||||||
override fun getOwnersOfDeclaration(declaration: FirDeclaration): List<FirBasedSymbol<*>>? = null
|
override fun getOwnersOfDeclaration(declaration: FirDeclaration): List<FirBasedSymbol<*>>? = null
|
||||||
|
|
||||||
override fun fileHasPluginAnnotations(file: FirFile): Boolean = false
|
override fun fileHasPluginAnnotations(file: FirFile): Boolean = false
|
||||||
|
|
||||||
override fun matches(predicate: DeclarationPredicate, declaration: FirDeclaration): Boolean = false
|
override fun matches(predicate: AbstractPredicate<*>, declaration: FirDeclaration): Boolean = false
|
||||||
}
|
}
|
||||||
|
|
||||||
val FirSession.predicateBasedProvider: FirPredicateBasedProvider by FirSession.sessionComponentAccessor()
|
val FirSession.predicateBasedProvider: FirPredicateBasedProvider by FirSession.sessionComponentAccessor()
|
||||||
|
|||||||
+97
@@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 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.extensions.predicate
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.extensions.AnnotationFqn
|
||||||
|
|
||||||
|
sealed interface AbstractPredicate<P : AbstractPredicate<P>> {
|
||||||
|
val annotations: Set<AnnotationFqn>
|
||||||
|
val metaAnnotations: Set<AnnotationFqn>
|
||||||
|
|
||||||
|
fun <R, D> accept(visitor: PredicateVisitor<P, R, D>, data: D): R
|
||||||
|
|
||||||
|
sealed interface Or<P : AbstractPredicate<P>> : AbstractPredicate<P> {
|
||||||
|
val a: P
|
||||||
|
val b: P
|
||||||
|
|
||||||
|
override fun <R, D> accept(visitor: PredicateVisitor<P, R, D>, data: D): R {
|
||||||
|
return visitor.visitOr(this, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed interface And<P : AbstractPredicate<P>> : AbstractPredicate<P> {
|
||||||
|
val a: P
|
||||||
|
val b: P
|
||||||
|
|
||||||
|
override fun <R, D> accept(visitor: PredicateVisitor<P, R, D>, data: D): R {
|
||||||
|
return visitor.visitAnd(this, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------ Annotated ------------------------------------
|
||||||
|
|
||||||
|
sealed interface Annotated<P : AbstractPredicate<P>> : AbstractPredicate<P> {
|
||||||
|
override fun <R, D> accept(visitor: PredicateVisitor<P, R, D>, data: D): R {
|
||||||
|
return visitor.visitAnnotated(this, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed interface AnnotatedWith<P : AbstractPredicate<P>> : Annotated<P> {
|
||||||
|
override fun <R, D> accept(visitor: PredicateVisitor<P, R, D>, data: D): R {
|
||||||
|
return visitor.visitAnnotatedWith(this, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed interface AncestorAnnotatedWith<P : AbstractPredicate<P>> : Annotated<P> {
|
||||||
|
override fun <R, D> accept(visitor: PredicateVisitor<P, R, D>, data: D): R {
|
||||||
|
return visitor.visitAncestorAnnotatedWith(this, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sealed interface ParentAnnotatedWith<P : AbstractPredicate<P>> : Annotated<P> {
|
||||||
|
override fun <R, D> accept(visitor: PredicateVisitor<P, R, D>, data: D): R {
|
||||||
|
return visitor.visitParentAnnotatedWith(this, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed interface HasAnnotatedWith<P : AbstractPredicate<P>> : Annotated<P> {
|
||||||
|
override fun <R, D> accept(visitor: PredicateVisitor<P, R, D>, data: D): R {
|
||||||
|
return visitor.visitHasAnnotatedWith(this, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------ MetaAnnotated ------------------------------------
|
||||||
|
|
||||||
|
sealed interface MetaAnnotatedWith<P : AbstractPredicate<P>> : AbstractPredicate<P> {
|
||||||
|
override fun <R, D> accept(visitor: PredicateVisitor<P, R, D>, data: D): R {
|
||||||
|
return visitor.visitMetaAnnotatedWith(this, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- DSL --------------------------------------------
|
||||||
|
|
||||||
|
abstract class BuilderContext<P : AbstractPredicate<P>> {
|
||||||
|
abstract infix fun P.or(other: P): P
|
||||||
|
abstract infix fun P.and(other: P): P
|
||||||
|
|
||||||
|
// ------------------- varargs -------------------
|
||||||
|
abstract fun annotated(vararg annotations: AnnotationFqn): P
|
||||||
|
abstract fun ancestorAnnotated(vararg annotations: AnnotationFqn): P
|
||||||
|
abstract fun parentAnnotated(vararg annotations: AnnotationFqn): P
|
||||||
|
abstract fun hasAnnotated(vararg annotations: AnnotationFqn): P
|
||||||
|
|
||||||
|
abstract fun annotatedOrUnder(vararg annotations: AnnotationFqn): P
|
||||||
|
|
||||||
|
// ------------------- collections -------------------
|
||||||
|
abstract fun annotated(annotations: Collection<AnnotationFqn>): P
|
||||||
|
abstract fun ancestorAnnotated(annotations: Collection<AnnotationFqn>): P
|
||||||
|
abstract fun parentAnnotated(annotations: Collection<AnnotationFqn>): P
|
||||||
|
abstract fun hasAnnotated(annotations: Collection<AnnotationFqn>): P
|
||||||
|
|
||||||
|
abstract fun annotatedOrUnder(annotations: Collection<AnnotationFqn>): P
|
||||||
|
}
|
||||||
|
}
|
||||||
+186
-197
@@ -10,226 +10,215 @@ import org.jetbrains.kotlin.fir.extensions.AnnotationFqn
|
|||||||
// -------------------------------------------- Predicates --------------------------------------------
|
// -------------------------------------------- Predicates --------------------------------------------
|
||||||
|
|
||||||
// todo: Missing KDOC
|
// todo: Missing KDOC
|
||||||
sealed class DeclarationPredicate {
|
sealed class DeclarationPredicate : AbstractPredicate<DeclarationPredicate> {
|
||||||
abstract val annotations: Set<AnnotationFqn>
|
abstract override val annotations: Set<AnnotationFqn>
|
||||||
abstract val metaAnnotations: Set<AnnotationFqn>
|
abstract override val metaAnnotations: Set<AnnotationFqn>
|
||||||
|
|
||||||
abstract fun <R, D> accept(visitor: DeclarationPredicateVisitor<R, D>, data: D): R
|
abstract override fun <R, D> accept(visitor: PredicateVisitor<DeclarationPredicate, R, D>, data: D): R
|
||||||
|
|
||||||
class Or(val a: DeclarationPredicate, val b: DeclarationPredicate) : DeclarationPredicate() {
|
class Or(
|
||||||
|
override val a: DeclarationPredicate,
|
||||||
|
override val b: DeclarationPredicate
|
||||||
|
) : DeclarationPredicate(), AbstractPredicate.Or<DeclarationPredicate> {
|
||||||
override val annotations: Set<AnnotationFqn> = a.annotations + b.annotations
|
override val annotations: Set<AnnotationFqn> = a.annotations + b.annotations
|
||||||
override val metaAnnotations: Set<AnnotationFqn> = a.metaAnnotations + b.metaAnnotations
|
override val metaAnnotations: Set<AnnotationFqn> = a.metaAnnotations + b.metaAnnotations
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: DeclarationPredicateVisitor<R, D>, data: D): R {
|
override fun <R, D> accept(visitor: PredicateVisitor<DeclarationPredicate, R, D>, data: D): R {
|
||||||
return visitor.visitOr(this, data)
|
return visitor.visitOr(this, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class And(val a: DeclarationPredicate, val b: DeclarationPredicate) : DeclarationPredicate() {
|
class And(
|
||||||
|
override val a: DeclarationPredicate,
|
||||||
|
override val b: DeclarationPredicate
|
||||||
|
) : DeclarationPredicate(), AbstractPredicate.And<DeclarationPredicate> {
|
||||||
override val annotations: Set<AnnotationFqn> = a.annotations + b.annotations
|
override val annotations: Set<AnnotationFqn> = a.annotations + b.annotations
|
||||||
override val metaAnnotations: Set<AnnotationFqn> = a.metaAnnotations + b.metaAnnotations
|
override val metaAnnotations: Set<AnnotationFqn> = a.metaAnnotations + b.metaAnnotations
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: DeclarationPredicateVisitor<R, D>, data: D): R {
|
override fun <R, D> accept(visitor: PredicateVisitor<DeclarationPredicate, R, D>, data: D): R {
|
||||||
return visitor.visitAnd(this, data)
|
return visitor.visitAnd(this, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------ Annotated ------------------------------------
|
// ------------------------------------ Annotated ------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for all predicates with specific annotations
|
* Base class for all predicates with specific annotations
|
||||||
* Declaration will be matched if at least one of [annotations] is found
|
* Declaration will be matched if at least one of [annotations] is found
|
||||||
*/
|
*/
|
||||||
sealed class Annotated(final override val annotations: Set<AnnotationFqn>) : DeclarationPredicate() {
|
sealed class Annotated(final override val annotations: Set<AnnotationFqn>) : DeclarationPredicate(),
|
||||||
init {
|
AbstractPredicate.Annotated<DeclarationPredicate> {
|
||||||
require(annotations.isNotEmpty()) {
|
init {
|
||||||
"Annotations should be not empty"
|
require(annotations.isNotEmpty()) {
|
||||||
|
"Annotations should be not empty"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final override val metaAnnotations: Set<AnnotationFqn>
|
||||||
|
get() = emptySet()
|
||||||
|
|
||||||
|
override fun <R, D> accept(visitor: PredicateVisitor<DeclarationPredicate, R, D>, data: D): R {
|
||||||
|
return visitor.visitAnnotated(this, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final override val metaAnnotations: Set<AnnotationFqn>
|
/**
|
||||||
get() = emptySet()
|
* Matches declarations, which are annotated with [annotations]
|
||||||
|
*
|
||||||
override fun <R, D> accept(visitor: DeclarationPredicateVisitor<R, D>, data: D): R {
|
* @Ann
|
||||||
return visitor.visitAnnotated(this, data)
|
* fun foo() {}
|
||||||
}
|
*
|
||||||
}
|
* fun bar(@Ann param: Int) {}
|
||||||
|
*
|
||||||
/**
|
* @Ann
|
||||||
* Matches declarations, which are annotated with [annotations]
|
* class A {
|
||||||
*
|
* fun baz() {}
|
||||||
* @Ann
|
*
|
||||||
* fun foo() {}
|
* class Nested {
|
||||||
*
|
* fun foobar() {}
|
||||||
* fun bar(@Ann param: Int) {}
|
* }
|
||||||
*
|
* }
|
||||||
* @Ann
|
*
|
||||||
* class A {
|
* Matched symbols: [fun foo, parameter `param` from fun bar, class A]
|
||||||
* fun baz() {}
|
*/
|
||||||
*
|
class AnnotatedWith(annotations: Set<AnnotationFqn>) : Annotated(annotations), AbstractPredicate.AnnotatedWith<DeclarationPredicate> {
|
||||||
* class Nested {
|
override fun <R, D> accept(visitor: PredicateVisitor<DeclarationPredicate, R, D>, data: D): R {
|
||||||
* fun foobar() {}
|
return visitor.visitAnnotatedWith(this, data)
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* 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 AncestorAnnotatedWith(annotations: Set<AnnotationFqn>) : Annotated(annotations) {
|
|
||||||
override fun <R, D> accept(visitor: DeclarationPredicateVisitor<R, D>, data: D): R {
|
|
||||||
return visitor.visitAncestorAnnotatedWith(this, data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 {
|
|
||||||
require(metaAnnotations.isNotEmpty()) {
|
|
||||||
"Annotations should be not empty"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final override val annotations: Set<AnnotationFqn>
|
/**
|
||||||
get() = emptySet()
|
* 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 AncestorAnnotatedWith(annotations: Set<AnnotationFqn>) : Annotated(annotations),
|
||||||
|
AbstractPredicate.AncestorAnnotatedWith<DeclarationPredicate> {
|
||||||
|
override fun <R, D> accept(visitor: PredicateVisitor<DeclarationPredicate, R, D>, data: D): R {
|
||||||
|
return visitor.visitAncestorAnnotatedWith(this, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: DeclarationPredicateVisitor<R, D>, data: D): R {
|
/**
|
||||||
return visitor.visitMetaAnnotated(this, data)
|
* 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),
|
||||||
|
AbstractPredicate.ParentAnnotatedWith<DeclarationPredicate> {
|
||||||
|
override fun <R, D> accept(visitor: PredicateVisitor<DeclarationPredicate, 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),
|
||||||
|
AbstractPredicate.HasAnnotatedWith<DeclarationPredicate> {
|
||||||
|
override fun <R, D> accept(visitor: PredicateVisitor<DeclarationPredicate, R, D>, data: D): R {
|
||||||
|
return visitor.visitHasAnnotatedWith(this, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------ MetaAnnotated ------------------------------------
|
||||||
|
|
||||||
|
class MetaAnnotatedWith(
|
||||||
|
override val metaAnnotations: Set<AnnotationFqn>
|
||||||
|
) : DeclarationPredicate(), AbstractPredicate.MetaAnnotatedWith<DeclarationPredicate> {
|
||||||
|
init {
|
||||||
|
require(metaAnnotations.isNotEmpty()) {
|
||||||
|
"Annotations should be not empty"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val annotations: Set<AnnotationFqn>
|
||||||
|
get() = emptySet()
|
||||||
|
|
||||||
|
override fun <R, D> accept(visitor: PredicateVisitor<DeclarationPredicate, R, D>, data: D): R {
|
||||||
|
return visitor.visitMetaAnnotatedWith(this, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- DSL --------------------------------------------
|
||||||
|
|
||||||
|
object BuilderContext : AbstractPredicate.BuilderContext<DeclarationPredicate>() {
|
||||||
|
override infix fun DeclarationPredicate.or(other: DeclarationPredicate): DeclarationPredicate = Or(this, other)
|
||||||
|
override infix fun DeclarationPredicate.and(other: DeclarationPredicate): DeclarationPredicate = And(this, other)
|
||||||
|
|
||||||
|
// ------------------- varargs -------------------
|
||||||
|
override fun annotated(vararg annotations: AnnotationFqn): DeclarationPredicate = annotated(annotations.toList())
|
||||||
|
override fun ancestorAnnotated(vararg annotations: AnnotationFqn): DeclarationPredicate = ancestorAnnotated(annotations.toList())
|
||||||
|
override fun parentAnnotated(vararg annotations: AnnotationFqn): DeclarationPredicate = parentAnnotated(annotations.toList())
|
||||||
|
override fun hasAnnotated(vararg annotations: AnnotationFqn): DeclarationPredicate = hasAnnotated(annotations.toList())
|
||||||
|
|
||||||
|
override fun annotatedOrUnder(vararg annotations: AnnotationFqn): DeclarationPredicate =
|
||||||
|
annotated(*annotations) or ancestorAnnotated(*annotations)
|
||||||
|
|
||||||
|
fun metaAnnotated(vararg metaAnnotations: AnnotationFqn): DeclarationPredicate = MetaAnnotatedWith(metaAnnotations.toSet())
|
||||||
|
|
||||||
|
// ------------------- collections -------------------
|
||||||
|
override fun annotated(annotations: Collection<AnnotationFqn>): DeclarationPredicate = AnnotatedWith(annotations.toSet())
|
||||||
|
override fun ancestorAnnotated(annotations: Collection<AnnotationFqn>): DeclarationPredicate =
|
||||||
|
AncestorAnnotatedWith(annotations.toSet())
|
||||||
|
|
||||||
|
override fun parentAnnotated(annotations: Collection<AnnotationFqn>): DeclarationPredicate =
|
||||||
|
ParentAnnotatedWith(annotations.toSet())
|
||||||
|
|
||||||
|
override fun hasAnnotated(annotations: Collection<AnnotationFqn>): DeclarationPredicate = HasAnnotatedWith(annotations.toSet())
|
||||||
|
|
||||||
|
override fun annotatedOrUnder(annotations: Collection<AnnotationFqn>): DeclarationPredicate =
|
||||||
|
annotated(annotations) or ancestorAnnotated(annotations)
|
||||||
|
|
||||||
|
fun metaAnnotated(metaAnnotations: Collection<AnnotationFqn>): DeclarationPredicate = MetaAnnotatedWith(metaAnnotations.toSet())
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
inline fun create(init: BuilderContext.() -> DeclarationPredicate): DeclarationPredicate = BuilderContext.init()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MetaAnnotatedWith(metaAnnotations: Set<AnnotationFqn>) : MetaAnnotated(metaAnnotations) {
|
|
||||||
override fun <R, D> accept(visitor: DeclarationPredicateVisitor<R, D>, data: D): R {
|
|
||||||
return visitor.visitMetaAnnotatedWith(this, data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class AncestorMetaAnnotatedWith(metaAnnotations: Set<AnnotationFqn>) : MetaAnnotated(metaAnnotations) {
|
|
||||||
override fun <R, D> accept(visitor: DeclarationPredicateVisitor<R, D>, data: D): R {
|
|
||||||
return visitor.visitAncestorMetaAnnotatedWith(this, data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
infix fun DeclarationPredicate.and(other: DeclarationPredicate): DeclarationPredicate = DeclarationPredicate.And(this, other)
|
|
||||||
|
|
||||||
// ------------------- varargs -------------------
|
|
||||||
fun annotated(vararg annotations: AnnotationFqn): DeclarationPredicate = AnnotatedWith(annotations.toSet())
|
|
||||||
fun ancestorAnnotated(vararg annotations: AnnotationFqn): DeclarationPredicate = AncestorAnnotatedWith(annotations.toSet())
|
|
||||||
fun parentAnnotated(vararg annotations: AnnotationFqn): DeclarationPredicate = ParentAnnotatedWith(annotations.toSet())
|
|
||||||
fun hasAnnotated(vararg annotations: AnnotationFqn): DeclarationPredicate = HasAnnotatedWith(annotations.toSet())
|
|
||||||
|
|
||||||
fun metaAnnotated(vararg metaAnnotations: AnnotationFqn): DeclarationPredicate = MetaAnnotatedWith(metaAnnotations.toSet())
|
|
||||||
fun metaAncestorAnnotated(vararg metaAnnotations: AnnotationFqn): DeclarationPredicate = AncestorMetaAnnotatedWith(metaAnnotations.toSet())
|
|
||||||
fun parentMetaAnnotated(vararg metaAnnotations: AnnotationFqn): DeclarationPredicate = ParentMetaAnnotatedWith(metaAnnotations.toSet())
|
|
||||||
fun hasMetaAnnotated(vararg metaAnnotations: AnnotationFqn): DeclarationPredicate = HasMetaAnnotatedWith(metaAnnotations.toSet())
|
|
||||||
|
|
||||||
fun annotatedOrUnder(vararg annotations: AnnotationFqn): DeclarationPredicate = annotated(*annotations) or ancestorAnnotated(*annotations)
|
|
||||||
fun metaAnnotatedOrUnder(vararg metaAnnotations: AnnotationFqn): DeclarationPredicate =
|
|
||||||
metaAnnotated(*metaAnnotations) or metaAncestorAnnotated(*metaAnnotations)
|
|
||||||
|
|
||||||
// ------------------- collections -------------------
|
|
||||||
fun annotated(annotations: Collection<AnnotationFqn>): DeclarationPredicate = AnnotatedWith(annotations.toSet())
|
|
||||||
fun ancestorAnnotated(annotations: Collection<AnnotationFqn>): DeclarationPredicate = AncestorAnnotatedWith(annotations.toSet())
|
|
||||||
fun parentAnnotated(annotations: Collection<AnnotationFqn>): DeclarationPredicate = ParentAnnotatedWith(annotations.toSet())
|
|
||||||
fun hasAnnotated(annotations: Collection<AnnotationFqn>): DeclarationPredicate = HasAnnotatedWith(annotations.toSet())
|
|
||||||
|
|
||||||
fun metaAnnotated(metaAnnotations: Collection<AnnotationFqn>): DeclarationPredicate = MetaAnnotatedWith(metaAnnotations.toSet())
|
|
||||||
fun metaAncestorAnnotated(metaAnnotations: Collection<AnnotationFqn>): DeclarationPredicate = AncestorMetaAnnotatedWith(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 ancestorAnnotated(annotations)
|
|
||||||
fun metaAnnotatedOrUnder(metaAnnotations: Collection<AnnotationFqn>): DeclarationPredicate =
|
|
||||||
metaAnnotated(metaAnnotations) or metaAncestorAnnotated(metaAnnotations)
|
|
||||||
|
|||||||
-58
@@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2021 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.extensions.predicate
|
|
||||||
|
|
||||||
abstract class DeclarationPredicateVisitor<R, D> {
|
|
||||||
abstract fun visitPredicate(predicate: DeclarationPredicate, data: D): R
|
|
||||||
|
|
||||||
open fun visitAnd(predicate: DeclarationPredicate.And, data: D): R {
|
|
||||||
return visitPredicate(predicate, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun visitOr(predicate: DeclarationPredicate.Or, data: D): R {
|
|
||||||
return visitPredicate(predicate, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun visitAnnotated(predicate: Annotated, data: D): R {
|
|
||||||
return visitPredicate(predicate, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun visitAnnotatedWith(predicate: AnnotatedWith, data: D): R {
|
|
||||||
return visitAnnotated(predicate, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun visitAncestorAnnotatedWith(predicate: AncestorAnnotatedWith, data: D): R {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun visitMetaAnnotatedWith(predicate: MetaAnnotatedWith, data: D): R {
|
|
||||||
return visitMetaAnnotated(predicate, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun visitAncestorMetaAnnotatedWith(predicate: AncestorMetaAnnotatedWith, 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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+183
@@ -0,0 +1,183 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 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.extensions.predicate
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.extensions.AnnotationFqn
|
||||||
|
|
||||||
|
sealed class LookupPredicate : AbstractPredicate<LookupPredicate> {
|
||||||
|
abstract override val annotations: Set<AnnotationFqn>
|
||||||
|
final override val metaAnnotations: Set<AnnotationFqn>
|
||||||
|
get() = error("Should not be called")
|
||||||
|
|
||||||
|
abstract override fun <R, D> accept(visitor: PredicateVisitor<LookupPredicate, R, D>, data: D): R
|
||||||
|
|
||||||
|
class Or(
|
||||||
|
override val a: LookupPredicate,
|
||||||
|
override val b: LookupPredicate
|
||||||
|
) : LookupPredicate(), AbstractPredicate.Or<LookupPredicate> {
|
||||||
|
override val annotations: Set<AnnotationFqn> = a.annotations + b.annotations
|
||||||
|
|
||||||
|
override fun <R, D> accept(visitor: PredicateVisitor<LookupPredicate, R, D>, data: D): R {
|
||||||
|
return visitor.visitOr(this, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class And(
|
||||||
|
override val a: LookupPredicate,
|
||||||
|
override val b: LookupPredicate
|
||||||
|
) : LookupPredicate(), AbstractPredicate.And<LookupPredicate> {
|
||||||
|
override val annotations: Set<AnnotationFqn> = a.annotations + b.annotations
|
||||||
|
|
||||||
|
override fun <R, D> accept(visitor: PredicateVisitor<LookupPredicate, R, D>, data: D): R {
|
||||||
|
return visitor.visitAnd(this, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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>) : LookupPredicate(), AbstractPredicate.Annotated<LookupPredicate> {
|
||||||
|
init {
|
||||||
|
require(annotations.isNotEmpty()) {
|
||||||
|
"Annotations should be not empty"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <R, D> accept(visitor: PredicateVisitor<LookupPredicate, R, D>, data: D): R {
|
||||||
|
return visitor.visitAnnotated(this, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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), AbstractPredicate.AnnotatedWith<LookupPredicate> {
|
||||||
|
override fun <R, D> accept(visitor: PredicateVisitor<LookupPredicate, 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 AncestorAnnotatedWith(annotations: Set<AnnotationFqn>) : Annotated(annotations), AbstractPredicate.AncestorAnnotatedWith<LookupPredicate> {
|
||||||
|
override fun <R, D> accept(visitor: PredicateVisitor<LookupPredicate, R, D>, data: D): R {
|
||||||
|
return visitor.visitAncestorAnnotatedWith(this, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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), AbstractPredicate.ParentAnnotatedWith<LookupPredicate> {
|
||||||
|
override fun <R, D> accept(visitor: PredicateVisitor<LookupPredicate, 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), AbstractPredicate.HasAnnotatedWith<LookupPredicate> {
|
||||||
|
override fun <R, D> accept(visitor: PredicateVisitor<LookupPredicate, R, D>, data: D): R {
|
||||||
|
return visitor.visitHasAnnotatedWith(this, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- DSL --------------------------------------------
|
||||||
|
|
||||||
|
object BuilderContext : AbstractPredicate.BuilderContext<LookupPredicate>() {
|
||||||
|
override infix fun LookupPredicate.or(other: LookupPredicate): LookupPredicate = Or(this, other)
|
||||||
|
override infix fun LookupPredicate.and(other: LookupPredicate): LookupPredicate = And(this, other)
|
||||||
|
|
||||||
|
// ------------------- varargs -------------------
|
||||||
|
override fun annotated(vararg annotations: AnnotationFqn): LookupPredicate = annotated(annotations.toList())
|
||||||
|
override fun ancestorAnnotated(vararg annotations: AnnotationFqn): LookupPredicate = ancestorAnnotated(annotations.toList())
|
||||||
|
override fun parentAnnotated(vararg annotations: AnnotationFqn): LookupPredicate = parentAnnotated(annotations.toList())
|
||||||
|
override fun hasAnnotated(vararg annotations: AnnotationFqn): LookupPredicate = hasAnnotated(annotations.toList())
|
||||||
|
|
||||||
|
override fun annotatedOrUnder(vararg annotations: AnnotationFqn): LookupPredicate =
|
||||||
|
annotated(*annotations) or ancestorAnnotated(*annotations)
|
||||||
|
|
||||||
|
// ------------------- collections -------------------
|
||||||
|
override fun annotated(annotations: Collection<AnnotationFqn>): LookupPredicate = AnnotatedWith(annotations.toSet())
|
||||||
|
override fun ancestorAnnotated(annotations: Collection<AnnotationFqn>): LookupPredicate = AncestorAnnotatedWith(annotations.toSet())
|
||||||
|
override fun parentAnnotated(annotations: Collection<AnnotationFqn>): LookupPredicate = ParentAnnotatedWith(annotations.toSet())
|
||||||
|
override fun hasAnnotated(annotations: Collection<AnnotationFqn>): LookupPredicate = HasAnnotatedWith(annotations.toSet())
|
||||||
|
override fun annotatedOrUnder(annotations: Collection<AnnotationFqn>): LookupPredicate =
|
||||||
|
annotated(annotations) or ancestorAnnotated(annotations)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
inline fun create(init: BuilderContext.() -> LookupPredicate): LookupPredicate = BuilderContext.init()
|
||||||
|
}
|
||||||
|
}
|
||||||
+45
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 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.extensions.predicate
|
||||||
|
|
||||||
|
abstract class PredicateVisitor<P : AbstractPredicate<P>, R, D> {
|
||||||
|
abstract fun visitPredicate(predicate: AbstractPredicate<P>, data: D): R
|
||||||
|
|
||||||
|
open fun visitAnd(predicate: AbstractPredicate.And<P>, data: D): R {
|
||||||
|
return visitPredicate(predicate, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun visitOr(predicate: AbstractPredicate.Or<P>, data: D): R {
|
||||||
|
return visitPredicate(predicate, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun visitAnnotated(predicate: AbstractPredicate.Annotated<P>, data: D): R {
|
||||||
|
return visitPredicate(predicate, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun visitAnnotatedWith(predicate: AbstractPredicate.AnnotatedWith<P>, data: D): R {
|
||||||
|
return visitAnnotated(predicate, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun visitAncestorAnnotatedWith(predicate: AbstractPredicate.AncestorAnnotatedWith<P>, data: D): R {
|
||||||
|
return visitAnnotated(predicate, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun visitParentAnnotatedWith(predicate: AbstractPredicate.ParentAnnotatedWith<P>, data: D): R {
|
||||||
|
return visitAnnotated(predicate, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun visitHasAnnotatedWith(predicate: AbstractPredicate.HasAnnotatedWith<P>, data: D): R {
|
||||||
|
return visitAnnotated(predicate, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun visitMetaAnnotatedWith(predicate: AbstractPredicate.MetaAnnotatedWith<P>, data: D): R {
|
||||||
|
return visitPredicate(predicate, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typealias DeclarationPredicateVisitor<R, D> = PredicateVisitor<DeclarationPredicate, R, D>
|
||||||
|
typealias LookupPredicateVisitor<R, D> = PredicateVisitor<LookupPredicate, R, D>
|
||||||
+2
-4
@@ -15,9 +15,7 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirExtensionSessionComponent.Factory
|
import org.jetbrains.kotlin.fir.extensions.FirExtensionSessionComponent.Factory
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirStatusTransformerExtension
|
import org.jetbrains.kotlin.fir.extensions.FirStatusTransformerExtension
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.annotated
|
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.metaAnnotated
|
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.or
|
|
||||||
import org.jetbrains.kotlin.fir.extensions.utils.AbstractSimpleClassPredicateMatchingService
|
import org.jetbrains.kotlin.fir.extensions.utils.AbstractSimpleClassPredicateMatchingService
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||||
@@ -57,7 +55,7 @@ class FirAllOpenPredicateMatcher(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val predicate = run {
|
override val predicate = DeclarationPredicate.create {
|
||||||
val annotationFqNames = allOpenAnnotationFqNames.map { FqName(it) }
|
val annotationFqNames = allOpenAnnotationFqNames.map { FqName(it) }
|
||||||
annotated(annotationFqNames) or metaAnnotated(annotationFqNames)
|
annotated(annotationFqNames) or metaAnnotated(annotationFqNames)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
@java.lang.annotation.Retention(value=RUNTIME)
|
||||||
|
@kotlin.Metadata
|
||||||
|
public annotation class AllOpen {
|
||||||
|
// source: 'anonymousObject.kt'
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
public final class Test$a$1 {
|
||||||
|
// source: 'anonymousObject.kt'
|
||||||
|
enclosing method Test.<init>()V
|
||||||
|
inner (anonymous) class Test$a$1
|
||||||
|
method <init>(): void
|
||||||
|
public final method run(): void
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
public final class Test$b$1 {
|
||||||
|
// source: 'anonymousObject.kt'
|
||||||
|
enclosing method Test.b()V
|
||||||
|
inner (anonymous) class Test$b$1
|
||||||
|
method <init>(): void
|
||||||
|
public final method run(): void
|
||||||
|
}
|
||||||
|
|
||||||
|
@AllOpen
|
||||||
|
@kotlin.Metadata
|
||||||
|
public class Test {
|
||||||
|
// source: 'anonymousObject.kt'
|
||||||
|
private final @org.jetbrains.annotations.NotNull field a: java.lang.Runnable
|
||||||
|
inner (anonymous) class Test$a$1
|
||||||
|
inner (anonymous) class Test$b$1
|
||||||
|
public method <init>(): void
|
||||||
|
private final static method b$lambda$0(): void
|
||||||
|
public method b(): void
|
||||||
|
public @org.jetbrains.annotations.NotNull method getA(): java.lang.Runnable
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
// IGNORE_BACKEND_K2: JVM_IR
|
|
||||||
// FIR version does not go inside bodies
|
// FIR version does not go inside bodies
|
||||||
// Also it's quiestionable do we even need to transform local classes and anonymous objects
|
// Also it's quiestionable do we even need to transform local classes and anonymous objects
|
||||||
|
|
||||||
annotation class AllOpen
|
annotation class AllOpen
|
||||||
|
|
||||||
@AllOpen
|
@AllOpen
|
||||||
|
|||||||
+3
-2
@@ -1,5 +1,4 @@
|
|||||||
// IGNORE_BACKEND_K2: JVM_IR
|
// MODULE: lib
|
||||||
// FIR version does not support double-transitive annotations by design
|
|
||||||
annotation class AllOpen
|
annotation class AllOpen
|
||||||
|
|
||||||
@AllOpen
|
@AllOpen
|
||||||
@@ -14,6 +13,8 @@ annotation class AnotherComponent
|
|||||||
@java.lang.annotation.Documented
|
@java.lang.annotation.Documented
|
||||||
annotation class Documented
|
annotation class Documented
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
|
||||||
class TestWithoutAnnotations_ShouldBeFinal
|
class TestWithoutAnnotations_ShouldBeFinal
|
||||||
|
|
||||||
@Documented
|
@Documented
|
||||||
+103
@@ -0,0 +1,103 @@
|
|||||||
|
Module: lib
|
||||||
|
@java.lang.annotation.Retention(value=RUNTIME)
|
||||||
|
@kotlin.Metadata
|
||||||
|
public annotation class AllOpen {
|
||||||
|
// source: 'module_lib_metaAnnotation_differentModules.kt'
|
||||||
|
}
|
||||||
|
|
||||||
|
@OtherComponent
|
||||||
|
@java.lang.annotation.Retention(value=RUNTIME)
|
||||||
|
@kotlin.Metadata
|
||||||
|
public annotation class AnotherComponent {
|
||||||
|
// source: 'module_lib_metaAnnotation_differentModules.kt'
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.annotation.Documented
|
||||||
|
@java.lang.annotation.Retention(value=RUNTIME)
|
||||||
|
@kotlin.Metadata
|
||||||
|
public annotation class Documented {
|
||||||
|
// source: 'module_lib_metaAnnotation_differentModules.kt'
|
||||||
|
}
|
||||||
|
|
||||||
|
@AllOpen
|
||||||
|
@java.lang.annotation.Retention(value=RUNTIME)
|
||||||
|
@kotlin.Metadata
|
||||||
|
public annotation class MyComponent {
|
||||||
|
// source: 'module_lib_metaAnnotation_differentModules.kt'
|
||||||
|
}
|
||||||
|
|
||||||
|
@MyComponent
|
||||||
|
@java.lang.annotation.Retention(value=RUNTIME)
|
||||||
|
@kotlin.Metadata
|
||||||
|
public annotation class OtherComponent {
|
||||||
|
// source: 'module_lib_metaAnnotation_differentModules.kt'
|
||||||
|
}
|
||||||
|
Module: main
|
||||||
|
@Documented
|
||||||
|
@kotlin.Metadata
|
||||||
|
public final class ClassWithDocumented {
|
||||||
|
// source: 'module_main_metaAnnotation_differentModules.kt'
|
||||||
|
public method <init>(): void
|
||||||
|
}
|
||||||
|
|
||||||
|
@MyComponent
|
||||||
|
@kotlin.Metadata
|
||||||
|
public abstract class MyComponentBase {
|
||||||
|
// source: 'module_main_metaAnnotation_differentModules.kt'
|
||||||
|
public method <init>(): void
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
public final class MyComponentImpl2_ShouldBeFinal {
|
||||||
|
// source: 'module_main_metaAnnotation_differentModules.kt'
|
||||||
|
public method <init>(): void
|
||||||
|
public method method(): void
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
public class MyComponentImpl3_ShouldBeOpen {
|
||||||
|
// source: 'module_main_metaAnnotation_differentModules.kt'
|
||||||
|
public method <init>(): void
|
||||||
|
public final method method_ShouldBeFinal(): void
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
public class MyComponentImpl_ShouldBeOpen {
|
||||||
|
// source: 'module_main_metaAnnotation_differentModules.kt'
|
||||||
|
public method <init>(): void
|
||||||
|
public method method(): void
|
||||||
|
}
|
||||||
|
|
||||||
|
@AllOpen
|
||||||
|
@kotlin.Metadata
|
||||||
|
public class TestAllOpen_ShouldBeOpen {
|
||||||
|
// source: 'module_main_metaAnnotation_differentModules.kt'
|
||||||
|
public method <init>(): void
|
||||||
|
}
|
||||||
|
|
||||||
|
@AnotherComponent
|
||||||
|
@kotlin.Metadata
|
||||||
|
public class TestAnotherComponent_ShouldBeOpen {
|
||||||
|
// source: 'module_main_metaAnnotation_differentModules.kt'
|
||||||
|
public method <init>(): void
|
||||||
|
}
|
||||||
|
|
||||||
|
@MyComponent
|
||||||
|
@kotlin.Metadata
|
||||||
|
public class TestMyComponent_ShouldBeOpen {
|
||||||
|
// source: 'module_main_metaAnnotation_differentModules.kt'
|
||||||
|
public method <init>(): void
|
||||||
|
}
|
||||||
|
|
||||||
|
@OtherComponent
|
||||||
|
@kotlin.Metadata
|
||||||
|
public class TestOtherComponent_ShouldBeOpen {
|
||||||
|
// source: 'module_main_metaAnnotation_differentModules.kt'
|
||||||
|
public method <init>(): void
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
public final class TestWithoutAnnotations_ShouldBeFinal {
|
||||||
|
// source: 'module_main_metaAnnotation_differentModules.kt'
|
||||||
|
public method <init>(): void
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
annotation class AllOpen
|
||||||
|
|
||||||
|
@AllOpen
|
||||||
|
annotation class MyComponent
|
||||||
|
|
||||||
|
@MyComponent // Double-transitive annotations is supported
|
||||||
|
annotation class OtherComponent
|
||||||
|
|
||||||
|
@OtherComponent
|
||||||
|
annotation class AnotherComponent
|
||||||
|
|
||||||
|
@java.lang.annotation.Documented
|
||||||
|
annotation class Documented
|
||||||
|
|
||||||
|
class TestWithoutAnnotations_ShouldBeFinal
|
||||||
|
|
||||||
|
@Documented
|
||||||
|
class ClassWithDocumented
|
||||||
|
|
||||||
|
@AllOpen
|
||||||
|
class TestAllOpen_ShouldBeOpen
|
||||||
|
|
||||||
|
@MyComponent
|
||||||
|
class TestMyComponent_ShouldBeOpen
|
||||||
|
|
||||||
|
@OtherComponent
|
||||||
|
class TestOtherComponent_ShouldBeOpen
|
||||||
|
|
||||||
|
@AnotherComponent
|
||||||
|
class TestAnotherComponent_ShouldBeOpen
|
||||||
|
|
||||||
|
@MyComponent
|
||||||
|
abstract class MyComponentBase
|
||||||
|
|
||||||
|
class MyComponentImpl_ShouldBeOpen : MyComponentBase() {
|
||||||
|
fun method() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class MyComponentImpl2_ShouldBeFinal : MyComponentBase() {
|
||||||
|
fun method() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyComponentImpl3_ShouldBeOpen : MyComponentBase() {
|
||||||
|
final fun method_ShouldBeFinal() {}
|
||||||
|
}
|
||||||
+15
-15
@@ -1,20 +1,20 @@
|
|||||||
@java.lang.annotation.Retention(value=RUNTIME)
|
@java.lang.annotation.Retention(value=RUNTIME)
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public annotation class AllOpen {
|
public annotation class AllOpen {
|
||||||
// source: 'metaAnnotation.kt'
|
// source: 'metaAnnotation_sameModule.kt'
|
||||||
}
|
}
|
||||||
|
|
||||||
@OtherComponent
|
@OtherComponent
|
||||||
@java.lang.annotation.Retention(value=RUNTIME)
|
@java.lang.annotation.Retention(value=RUNTIME)
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public annotation class AnotherComponent {
|
public annotation class AnotherComponent {
|
||||||
// source: 'metaAnnotation.kt'
|
// source: 'metaAnnotation_sameModule.kt'
|
||||||
}
|
}
|
||||||
|
|
||||||
@Documented
|
@Documented
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class ClassWithDocumented {
|
public final class ClassWithDocumented {
|
||||||
// source: 'metaAnnotation.kt'
|
// source: 'metaAnnotation_sameModule.kt'
|
||||||
public method <init>(): void
|
public method <init>(): void
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,40 +22,40 @@ public final class ClassWithDocumented {
|
|||||||
@java.lang.annotation.Retention(value=RUNTIME)
|
@java.lang.annotation.Retention(value=RUNTIME)
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public annotation class Documented {
|
public annotation class Documented {
|
||||||
// source: 'metaAnnotation.kt'
|
// source: 'metaAnnotation_sameModule.kt'
|
||||||
}
|
}
|
||||||
|
|
||||||
@AllOpen
|
@AllOpen
|
||||||
@java.lang.annotation.Retention(value=RUNTIME)
|
@java.lang.annotation.Retention(value=RUNTIME)
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public annotation class MyComponent {
|
public annotation class MyComponent {
|
||||||
// source: 'metaAnnotation.kt'
|
// source: 'metaAnnotation_sameModule.kt'
|
||||||
}
|
}
|
||||||
|
|
||||||
@MyComponent
|
@MyComponent
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public abstract class MyComponentBase {
|
public abstract class MyComponentBase {
|
||||||
// source: 'metaAnnotation.kt'
|
// source: 'metaAnnotation_sameModule.kt'
|
||||||
public method <init>(): void
|
public method <init>(): void
|
||||||
}
|
}
|
||||||
|
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class MyComponentImpl2_ShouldBeFinal {
|
public final class MyComponentImpl2_ShouldBeFinal {
|
||||||
// source: 'metaAnnotation.kt'
|
// source: 'metaAnnotation_sameModule.kt'
|
||||||
public method <init>(): void
|
public method <init>(): void
|
||||||
public method method(): void
|
public method method(): void
|
||||||
}
|
}
|
||||||
|
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public class MyComponentImpl3_ShouldBeOpen {
|
public class MyComponentImpl3_ShouldBeOpen {
|
||||||
// source: 'metaAnnotation.kt'
|
// source: 'metaAnnotation_sameModule.kt'
|
||||||
public method <init>(): void
|
public method <init>(): void
|
||||||
public final method method_ShouldBeFinal(): void
|
public final method method_ShouldBeFinal(): void
|
||||||
}
|
}
|
||||||
|
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public class MyComponentImpl_ShouldBeOpen {
|
public class MyComponentImpl_ShouldBeOpen {
|
||||||
// source: 'metaAnnotation.kt'
|
// source: 'metaAnnotation_sameModule.kt'
|
||||||
public method <init>(): void
|
public method <init>(): void
|
||||||
public method method(): void
|
public method method(): void
|
||||||
}
|
}
|
||||||
@@ -64,39 +64,39 @@ public class MyComponentImpl_ShouldBeOpen {
|
|||||||
@java.lang.annotation.Retention(value=RUNTIME)
|
@java.lang.annotation.Retention(value=RUNTIME)
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public annotation class OtherComponent {
|
public annotation class OtherComponent {
|
||||||
// source: 'metaAnnotation.kt'
|
// source: 'metaAnnotation_sameModule.kt'
|
||||||
}
|
}
|
||||||
|
|
||||||
@AllOpen
|
@AllOpen
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public class TestAllOpen_ShouldBeOpen {
|
public class TestAllOpen_ShouldBeOpen {
|
||||||
// source: 'metaAnnotation.kt'
|
// source: 'metaAnnotation_sameModule.kt'
|
||||||
public method <init>(): void
|
public method <init>(): void
|
||||||
}
|
}
|
||||||
|
|
||||||
@AnotherComponent
|
@AnotherComponent
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public class TestAnotherComponent_ShouldBeOpen {
|
public class TestAnotherComponent_ShouldBeOpen {
|
||||||
// source: 'metaAnnotation.kt'
|
// source: 'metaAnnotation_sameModule.kt'
|
||||||
public method <init>(): void
|
public method <init>(): void
|
||||||
}
|
}
|
||||||
|
|
||||||
@MyComponent
|
@MyComponent
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public class TestMyComponent_ShouldBeOpen {
|
public class TestMyComponent_ShouldBeOpen {
|
||||||
// source: 'metaAnnotation.kt'
|
// source: 'metaAnnotation_sameModule.kt'
|
||||||
public method <init>(): void
|
public method <init>(): void
|
||||||
}
|
}
|
||||||
|
|
||||||
@OtherComponent
|
@OtherComponent
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public class TestOtherComponent_ShouldBeOpen {
|
public class TestOtherComponent_ShouldBeOpen {
|
||||||
// source: 'metaAnnotation.kt'
|
// source: 'metaAnnotation_sameModule.kt'
|
||||||
public method <init>(): void
|
public method <init>(): void
|
||||||
}
|
}
|
||||||
|
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class TestWithoutAnnotations_ShouldBeFinal {
|
public final class TestWithoutAnnotations_ShouldBeFinal {
|
||||||
// source: 'metaAnnotation.kt'
|
// source: 'metaAnnotation_sameModule.kt'
|
||||||
public method <init>(): void
|
public method <init>(): void
|
||||||
}
|
}
|
||||||
Generated
+9
-3
@@ -56,9 +56,15 @@ public class BytecodeListingTestForAllOpenGenerated extends AbstractBytecodeList
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("metaAnnotation.kt")
|
@TestMetadata("metaAnnotation_differentModules.kt")
|
||||||
public void testMetaAnnotation() throws Exception {
|
public void testMetaAnnotation_differentModules() throws Exception {
|
||||||
runTest("plugins/allopen/testData/bytecodeListing/metaAnnotation.kt");
|
runTest("plugins/allopen/testData/bytecodeListing/metaAnnotation_differentModules.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("metaAnnotation_sameModule.kt")
|
||||||
|
public void testMetaAnnotation_sameModule() throws Exception {
|
||||||
|
runTest("plugins/allopen/testData/bytecodeListing/metaAnnotation_sameModule.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
+9
-3
@@ -56,9 +56,15 @@ public class FirBytecodeListingTestForAllOpenGenerated extends AbstractFirByteco
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("metaAnnotation.kt")
|
@TestMetadata("metaAnnotation_differentModules.kt")
|
||||||
public void testMetaAnnotation() throws Exception {
|
public void testMetaAnnotation_differentModules() throws Exception {
|
||||||
runTest("plugins/allopen/testData/bytecodeListing/metaAnnotation.kt");
|
runTest("plugins/allopen/testData/bytecodeListing/metaAnnotation_differentModules.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("metaAnnotation_sameModule.kt")
|
||||||
|
public void testMetaAnnotation_sameModule() throws Exception {
|
||||||
|
runTest("plugins/allopen/testData/bytecodeListing/metaAnnotation_sameModule.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
plugins/allopen/tests-gen/org/jetbrains/kotlin/allopen/IrBytecodeListingTestForAllOpenGenerated.java
Generated
+9
-3
@@ -56,9 +56,15 @@ public class IrBytecodeListingTestForAllOpenGenerated extends AbstractIrBytecode
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("metaAnnotation.kt")
|
@TestMetadata("metaAnnotation_differentModules.kt")
|
||||||
public void testMetaAnnotation() throws Exception {
|
public void testMetaAnnotation_differentModules() throws Exception {
|
||||||
runTest("plugins/allopen/testData/bytecodeListing/metaAnnotation.kt");
|
runTest("plugins/allopen/testData/bytecodeListing/metaAnnotation_differentModules.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("metaAnnotation_sameModule.kt")
|
||||||
|
public void testMetaAnnotation_sameModule() throws Exception {
|
||||||
|
runTest("plugins/allopen/testData/bytecodeListing/metaAnnotation_sameModule.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
+3
-4
@@ -12,9 +12,6 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus
|
|||||||
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
|
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirStatusTransformerExtension
|
import org.jetbrains.kotlin.fir.extensions.FirStatusTransformerExtension
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
|
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.annotatedOrUnder
|
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.metaAnnotatedOrUnder
|
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.or
|
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
|
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
|
||||||
import org.jetbrains.kotlin.fir.extensions.transform
|
import org.jetbrains.kotlin.fir.extensions.transform
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -22,7 +19,9 @@ import org.jetbrains.kotlin.name.FqName
|
|||||||
class AllOpenStatusTransformer(session: FirSession) : FirStatusTransformerExtension(session) {
|
class AllOpenStatusTransformer(session: FirSession) : FirStatusTransformerExtension(session) {
|
||||||
companion object {
|
companion object {
|
||||||
private val ALL_OPEN = FqName("org.jetbrains.kotlin.fir.plugin.AllOpen")
|
private val ALL_OPEN = FqName("org.jetbrains.kotlin.fir.plugin.AllOpen")
|
||||||
private val PREDICATE: DeclarationPredicate = annotatedOrUnder(ALL_OPEN) or metaAnnotatedOrUnder(ALL_OPEN)
|
private val PREDICATE = DeclarationPredicate.create {
|
||||||
|
annotatedOrUnder(ALL_OPEN) or metaAnnotated(ALL_OPEN)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transformStatus(status: FirDeclarationStatus, declaration: FirDeclaration): FirDeclarationStatus {
|
override fun transformStatus(status: FirDeclarationStatus, declaration: FirDeclaration): FirDeclarationStatus {
|
||||||
|
|||||||
+1
-2
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.fir.expressions.arguments
|
|||||||
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
|
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirStatusTransformerExtension
|
import org.jetbrains.kotlin.fir.extensions.FirStatusTransformerExtension
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
|
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.annotatedOrUnder
|
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
|
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
|
||||||
import org.jetbrains.kotlin.fir.extensions.transform
|
import org.jetbrains.kotlin.fir.extensions.transform
|
||||||
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||||
@@ -37,7 +36,7 @@ class AllPublicVisibilityTransformer(session: FirSession) : FirStatusTransformer
|
|||||||
private val PrivateName = Name.identifier("Private")
|
private val PrivateName = Name.identifier("Private")
|
||||||
private val ProtectedName = Name.identifier("Protected")
|
private val ProtectedName = Name.identifier("Protected")
|
||||||
|
|
||||||
private val PREDICATE: DeclarationPredicate = annotatedOrUnder(AllPublicClassId.asSingleFqName())
|
private val PREDICATE = DeclarationPredicate.create { annotatedOrUnder(AllPublicClassId.asSingleFqName()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transformStatus(status: FirDeclarationStatus, declaration: FirDeclaration): FirDeclarationStatus {
|
override fun transformStatus(status: FirDeclarationStatus, declaration: FirDeclaration): FirDeclarationStatus {
|
||||||
|
|||||||
+1
-2
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
|
|||||||
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
|
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirSupertypeGenerationExtension
|
import org.jetbrains.kotlin.fir.extensions.FirSupertypeGenerationExtension
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
|
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.annotated
|
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
|
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
|
||||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||||
@@ -26,7 +25,7 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
class SomeAdditionalSupertypeGenerator(session: FirSession) : FirSupertypeGenerationExtension(session) {
|
class SomeAdditionalSupertypeGenerator(session: FirSession) : FirSupertypeGenerationExtension(session) {
|
||||||
companion object {
|
companion object {
|
||||||
private val myInterfaceClassId = ClassId(FqName("foo"), Name.identifier("MyInterface"))
|
private val myInterfaceClassId = ClassId(FqName("foo"), Name.identifier("MyInterface"))
|
||||||
private val PREDICATE: DeclarationPredicate = annotated("MyInterfaceSupertype".fqn())
|
private val PREDICATE = DeclarationPredicate.create { annotated("MyInterfaceSupertype".fqn()) }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-3
@@ -13,13 +13,11 @@ import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
|
|||||||
import org.jetbrains.kotlin.fir.extensions.FirSupertypeGenerationExtension
|
import org.jetbrains.kotlin.fir.extensions.FirSupertypeGenerationExtension
|
||||||
import org.jetbrains.kotlin.fir.extensions.buildUserTypeFromQualifierParts
|
import org.jetbrains.kotlin.fir.extensions.buildUserTypeFromQualifierParts
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
|
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.annotated
|
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
|
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
|
||||||
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
|
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
|
||||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.classId
|
import org.jetbrains.kotlin.fir.types.classId
|
||||||
import org.jetbrains.kotlin.fir.types.coneType
|
|
||||||
import org.jetbrains.kotlin.fir.types.constructClassLikeType
|
import org.jetbrains.kotlin.fir.types.constructClassLikeType
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -32,7 +30,7 @@ class SupertypeWithArgumentGenerator(session: FirSession) : FirSupertypeGenerati
|
|||||||
companion object {
|
companion object {
|
||||||
private val supertypeClassId = ClassId(FqName("foo"), Name.identifier("InterfaceWithArgument"))
|
private val supertypeClassId = ClassId(FqName("foo"), Name.identifier("InterfaceWithArgument"))
|
||||||
private val annotationClassId = ClassId.topLevel("SupertypeWithTypeArgument".fqn())
|
private val annotationClassId = ClassId.topLevel("SupertypeWithTypeArgument".fqn())
|
||||||
private val PREDICATE: DeclarationPredicate = annotated(annotationClassId.asSingleFqName())
|
private val PREDICATE = DeclarationPredicate.create { annotated(annotationClassId.asSingleFqName()) }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-4
@@ -5,12 +5,12 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.plugin.generators
|
package org.jetbrains.kotlin.fir.plugin.generators
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.GeneratedDeclarationKey
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
|
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.GeneratedDeclarationKey
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildRegularClass
|
import org.jetbrains.kotlin.fir.declarations.builder.buildRegularClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
|
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
|
||||||
@@ -18,8 +18,7 @@ import org.jetbrains.kotlin.fir.declarations.origin
|
|||||||
import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension
|
import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
|
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
|
||||||
import org.jetbrains.kotlin.fir.extensions.MemberGenerationContext
|
import org.jetbrains.kotlin.fir.extensions.MemberGenerationContext
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
|
import org.jetbrains.kotlin.fir.extensions.predicate.LookupPredicate
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.annotated
|
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
|
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
|
||||||
import org.jetbrains.kotlin.fir.moduleData
|
import org.jetbrains.kotlin.fir.moduleData
|
||||||
import org.jetbrains.kotlin.fir.plugin.fqn
|
import org.jetbrains.kotlin.fir.plugin.fqn
|
||||||
@@ -40,7 +39,7 @@ class AdditionalMembersGenerator(session: FirSession) : FirDeclarationGeneration
|
|||||||
private val MATERIALIZE_NAME = Name.identifier("materialize")
|
private val MATERIALIZE_NAME = Name.identifier("materialize")
|
||||||
private val NESTED_NAME = Name.identifier("Nested")
|
private val NESTED_NAME = Name.identifier("Nested")
|
||||||
|
|
||||||
private val PREDICATE: DeclarationPredicate = annotated("NestedClassAndMaterializeMember".fqn())
|
private val PREDICATE = LookupPredicate.create { annotated("NestedClassAndMaterializeMember".fqn()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private val predicateBasedProvider = session.predicateBasedProvider
|
private val predicateBasedProvider = session.predicateBasedProvider
|
||||||
|
|||||||
+2
-2
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.fir.declarations.origin
|
|||||||
import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension
|
import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
|
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
|
||||||
import org.jetbrains.kotlin.fir.extensions.MemberGenerationContext
|
import org.jetbrains.kotlin.fir.extensions.MemberGenerationContext
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.annotated
|
import org.jetbrains.kotlin.fir.extensions.predicate.LookupPredicate
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
|
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
|
||||||
import org.jetbrains.kotlin.fir.moduleData
|
import org.jetbrains.kotlin.fir.moduleData
|
||||||
import org.jetbrains.kotlin.fir.plugin.fqn
|
import org.jetbrains.kotlin.fir.plugin.fqn
|
||||||
@@ -38,7 +38,7 @@ import org.jetbrains.kotlin.name.SpecialNames
|
|||||||
*/
|
*/
|
||||||
class CompanionGenerator(session: FirSession) : FirDeclarationGenerationExtension(session) {
|
class CompanionGenerator(session: FirSession) : FirDeclarationGenerationExtension(session) {
|
||||||
companion object {
|
companion object {
|
||||||
private val PREDICATE = annotated("CompanionWithFoo".fqn())
|
private val PREDICATE = LookupPredicate.create { annotated("CompanionWithFoo".fqn()) }
|
||||||
private val FOO_NAME = Name.identifier("foo")
|
private val FOO_NAME = Name.identifier("foo")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-3
@@ -17,8 +17,7 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusIm
|
|||||||
import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension
|
import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
|
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
|
||||||
import org.jetbrains.kotlin.fir.extensions.MemberGenerationContext
|
import org.jetbrains.kotlin.fir.extensions.MemberGenerationContext
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
|
import org.jetbrains.kotlin.fir.extensions.predicate.LookupPredicate
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.annotated
|
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
|
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
|
||||||
import org.jetbrains.kotlin.fir.moduleData
|
import org.jetbrains.kotlin.fir.moduleData
|
||||||
import org.jetbrains.kotlin.fir.plugin.fqn
|
import org.jetbrains.kotlin.fir.plugin.fqn
|
||||||
@@ -43,7 +42,7 @@ class ExternalClassGenerator(session: FirSession) : FirDeclarationGenerationExte
|
|||||||
private val GENERATED_CLASS_ID = ClassId(FOO_PACKAGE, Name.identifier("AllOpenGenerated"))
|
private val GENERATED_CLASS_ID = ClassId(FOO_PACKAGE, Name.identifier("AllOpenGenerated"))
|
||||||
private val MATERIALIZE_NAME = Name.identifier("materialize")
|
private val MATERIALIZE_NAME = Name.identifier("materialize")
|
||||||
|
|
||||||
private val PREDICATE: DeclarationPredicate = annotated("ExternalClassWithNested".fqn())
|
private val PREDICATE = LookupPredicate.create { annotated("ExternalClassWithNested".fqn()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
object Key : GeneratedDeclarationKey() {
|
object Key : GeneratedDeclarationKey() {
|
||||||
|
|||||||
+3
-3
@@ -19,7 +19,7 @@ import org.jetbrains.kotlin.fir.expressions.builder.buildBlock
|
|||||||
import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension
|
import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
|
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
|
||||||
import org.jetbrains.kotlin.fir.extensions.MemberGenerationContext
|
import org.jetbrains.kotlin.fir.extensions.MemberGenerationContext
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.annotated
|
import org.jetbrains.kotlin.fir.extensions.predicate.LookupPredicate
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
|
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
|
||||||
import org.jetbrains.kotlin.fir.moduleData
|
import org.jetbrains.kotlin.fir.moduleData
|
||||||
import org.jetbrains.kotlin.fir.plugin.fqn
|
import org.jetbrains.kotlin.fir.plugin.fqn
|
||||||
@@ -37,8 +37,8 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
*/
|
*/
|
||||||
class MembersOfSerializerGenerator(session: FirSession) : FirDeclarationGenerationExtension(session) {
|
class MembersOfSerializerGenerator(session: FirSession) : FirDeclarationGenerationExtension(session) {
|
||||||
companion object {
|
companion object {
|
||||||
private val SERIALIZABLE_PREDICATE = annotated("MySerializable".fqn())
|
private val SERIALIZABLE_PREDICATE = LookupPredicate.create { annotated("MySerializable".fqn()) }
|
||||||
private val CORE_SERIALIZER_PREDICATE = annotated("CoreSerializer".fqn())
|
private val CORE_SERIALIZER_PREDICATE = LookupPredicate.create { annotated("CoreSerializer".fqn()) }
|
||||||
|
|
||||||
private val X_NAME = Name.identifier("x")
|
private val X_NAME = Name.identifier("x")
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-3
@@ -18,8 +18,7 @@ import org.jetbrains.kotlin.fir.declarations.origin
|
|||||||
import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension
|
import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
|
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
|
||||||
import org.jetbrains.kotlin.fir.extensions.MemberGenerationContext
|
import org.jetbrains.kotlin.fir.extensions.MemberGenerationContext
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
|
import org.jetbrains.kotlin.fir.extensions.predicate.LookupPredicate
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.annotated
|
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
|
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
|
||||||
import org.jetbrains.kotlin.fir.moduleData
|
import org.jetbrains.kotlin.fir.moduleData
|
||||||
import org.jetbrains.kotlin.fir.plugin.fqn
|
import org.jetbrains.kotlin.fir.plugin.fqn
|
||||||
@@ -35,7 +34,7 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
*/
|
*/
|
||||||
class TopLevelDeclarationsGenerator(session: FirSession) : FirDeclarationGenerationExtension(session) {
|
class TopLevelDeclarationsGenerator(session: FirSession) : FirDeclarationGenerationExtension(session) {
|
||||||
companion object {
|
companion object {
|
||||||
private val PREDICATE: DeclarationPredicate = annotated("DummyFunction".fqn())
|
private val PREDICATE = LookupPredicate.create { annotated("DummyFunction".fqn()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private val predicateBasedProvider = session.predicateBasedProvider
|
private val predicateBasedProvider = session.predicateBasedProvider
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ FILE: first.kt
|
|||||||
super<R|kotlin/Any|>()
|
super<R|kotlin/Any|>()
|
||||||
}
|
}
|
||||||
|
|
||||||
public open fun foo(): R|kotlin/Unit| {
|
public final fun foo(): R|kotlin/Unit| {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ class A {
|
|||||||
|
|
||||||
@Open
|
@Open
|
||||||
class B : A() {
|
class B : A() {
|
||||||
override fun foo() {
|
<!OVERRIDING_FINAL_MEMBER!>override<!> fun foo() {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-7
@@ -9,11 +9,13 @@ import org.jetbrains.kotlin.fir.extensions.predicate.*
|
|||||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationAnnotations
|
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationAnnotations
|
||||||
|
|
||||||
object FirSerializationPredicates {
|
object FirSerializationPredicates {
|
||||||
internal val serializerFor: DeclarationPredicate =
|
internal val serializerFor = DeclarationPredicate.create {
|
||||||
AnnotatedWith(setOf(SerializationAnnotations.serializerAnnotationFqName)) // @Serializer(for=...)
|
annotated(setOf(SerializationAnnotations.serializerAnnotationFqName)) // @Serializer(for=...)
|
||||||
internal val generatedSerializer: DeclarationPredicate =
|
}
|
||||||
ancestorAnnotated(SerializationAnnotations.serializableAnnotationFqName) // @Serializable X.$serializer
|
internal val hasMetaAnnotation = DeclarationPredicate.create {
|
||||||
internal val hasMetaAnnotation = metaAnnotated(SerializationAnnotations.metaSerializableAnnotationFqName)
|
metaAnnotated(SerializationAnnotations.metaSerializableAnnotationFqName)
|
||||||
internal val annotatedWithSerializableOrMeta =
|
}
|
||||||
AnnotatedWith(setOf(SerializationAnnotations.serializableAnnotationFqName)) or metaAnnotated(SerializationAnnotations.metaSerializableAnnotationFqName)
|
internal val annotatedWithSerializableOrMeta = DeclarationPredicate.create {
|
||||||
|
annotated(setOf(SerializationAnnotations.serializableAnnotationFqName)) or metaAnnotated(SerializationAnnotations.metaSerializableAnnotationFqName)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-11
@@ -250,12 +250,6 @@ class SerializationFirResolveExtension(session: FirSession) : FirDeclarationGene
|
|||||||
return listOf(copy.symbol)
|
return listOf(copy.symbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: it seems that this list will always be used, why not provide it automatically?
|
|
||||||
private val matchedClasses by lazy {
|
|
||||||
session.predicateBasedProvider.getSymbolsByPredicate(FirSerializationPredicates.annotatedWithSerializableOrMeta)
|
|
||||||
.filterIsInstance<FirRegularClassSymbol>()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun generateConstructors(context: MemberGenerationContext): List<FirConstructorSymbol> {
|
override fun generateConstructors(context: MemberGenerationContext): List<FirConstructorSymbol> {
|
||||||
val owner = context.owner
|
val owner = context.owner
|
||||||
val defaultObjectConstructor = buildPrimaryConstructor(
|
val defaultObjectConstructor = buildPrimaryConstructor(
|
||||||
@@ -291,10 +285,15 @@ class SerializationFirResolveExtension(session: FirSession) : FirDeclarationGene
|
|||||||
return listOf(defaultObjectConstructor.symbol)
|
return listOf(defaultObjectConstructor.symbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addSerializerImplClass(
|
private fun getClassWithAnnotatedWithSerializableOrMeta(classId: ClassId?): FirRegularClassSymbol? {
|
||||||
classId: ClassId
|
if (classId == null) return null
|
||||||
): FirClassLikeSymbol<*>? {
|
return (session.symbolProvider.getClassLikeSymbolByClassId(classId) as? FirRegularClassSymbol)?.takeIf {
|
||||||
val owner = matchedClasses.firstOrNull { it.classId == classId.outerClassId } ?: return null
|
session.predicateBasedProvider.matches(FirSerializationPredicates.annotatedWithSerializableOrMeta, it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addSerializerImplClass(classId: ClassId): FirClassLikeSymbol<*>? {
|
||||||
|
val owner = getClassWithAnnotatedWithSerializableOrMeta(classId.outerClassId) ?: return null
|
||||||
val hasTypeParams = owner.typeParameterSymbols.isNotEmpty()
|
val hasTypeParams = owner.typeParameterSymbols.isNotEmpty()
|
||||||
val serializerKind = if (hasTypeParams) ClassKind.CLASS else ClassKind.OBJECT
|
val serializerKind = if (hasTypeParams) ClassKind.CLASS else ClassKind.OBJECT
|
||||||
val serializerFirClass = buildRegularClass {
|
val serializerFirClass = buildRegularClass {
|
||||||
@@ -332,7 +331,7 @@ class SerializationFirResolveExtension(session: FirSession) : FirDeclarationGene
|
|||||||
|
|
||||||
fun generateCompanionDeclaration(classId: ClassId): FirClassLikeSymbol<*>? {
|
fun generateCompanionDeclaration(classId: ClassId): FirClassLikeSymbol<*>? {
|
||||||
if (classId.shortClassName != SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT) return null
|
if (classId.shortClassName != SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT) return null
|
||||||
val owner = matchedClasses.firstOrNull { it.classId == classId.outerClassId } ?: return null
|
val owner = getClassWithAnnotatedWithSerializableOrMeta(classId.outerClassId) ?: return null
|
||||||
if (owner.companionObjectSymbol != null) return null
|
if (owner.companionObjectSymbol != null) return null
|
||||||
val regularClass = buildRegularClass {
|
val regularClass = buildRegularClass {
|
||||||
moduleData = session.moduleData
|
moduleData = session.moduleData
|
||||||
|
|||||||
+2
-4
@@ -6,9 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.noarg.fir
|
package org.jetbrains.kotlin.noarg.fir
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.annotated
|
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.metaAnnotated
|
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.or
|
|
||||||
import org.jetbrains.kotlin.fir.extensions.utils.AbstractSimpleClassPredicateMatchingService
|
import org.jetbrains.kotlin.fir.extensions.utils.AbstractSimpleClassPredicateMatchingService
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
@@ -22,7 +20,7 @@ class FirNoArgPredicateMatcher(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val predicate = run {
|
override val predicate = DeclarationPredicate.create {
|
||||||
val annotationFqNames = noArgAnnotationFqNames.map { FqName(it) }
|
val annotationFqNames = noArgAnnotationFqNames.map { FqName(it) }
|
||||||
annotated(annotationFqNames) or metaAnnotated(annotationFqNames)
|
annotated(annotationFqNames) or metaAnnotated(annotationFqNames)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -7,8 +7,8 @@ class Outer {
|
|||||||
|
|
||||||
fun local() {
|
fun local() {
|
||||||
@NoArg
|
@NoArg
|
||||||
class Local(val l: Any) {
|
class <!NOARG_ON_LOCAL_CLASS_ERROR!>Local<!>(val l: Any) {
|
||||||
@NoArg
|
@NoArg
|
||||||
inner class InnerLocal(val x: Any)
|
inner class <!NOARG_ON_INNER_CLASS_ERROR!>InnerLocal<!>(val x: Any)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -19,7 +19,7 @@ import org.jetbrains.kotlin.fir.declarations.utils.modality
|
|||||||
import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension
|
import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
|
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
|
||||||
import org.jetbrains.kotlin.fir.extensions.MemberGenerationContext
|
import org.jetbrains.kotlin.fir.extensions.MemberGenerationContext
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.annotated
|
import org.jetbrains.kotlin.fir.extensions.predicate.LookupPredicate
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
|
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
|
||||||
import org.jetbrains.kotlin.fir.moduleData
|
import org.jetbrains.kotlin.fir.moduleData
|
||||||
import org.jetbrains.kotlin.fir.resolve.defaultType
|
import org.jetbrains.kotlin.fir.resolve.defaultType
|
||||||
@@ -46,7 +46,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
|||||||
|
|
||||||
class FirParcelizeDeclarationGenerator(session: FirSession) : FirDeclarationGenerationExtension(session) {
|
class FirParcelizeDeclarationGenerator(session: FirSession) : FirDeclarationGenerationExtension(session) {
|
||||||
companion object {
|
companion object {
|
||||||
private val PREDICATE = annotated(PARCELIZE_FQN, OLD_PARCELIZE_FQN)
|
private val PREDICATE = LookupPredicate.create { annotated(PARCELIZE_FQN, OLD_PARCELIZE_FQN) }
|
||||||
private val parcelizeMethodsNames = setOf(DESCRIBE_CONTENTS_NAME, WRITE_TO_PARCEL_NAME)
|
private val parcelizeMethodsNames = setOf(DESCRIBE_CONTENTS_NAME, WRITE_TO_PARCEL_NAME)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user