diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/LLFirNonUnderContentRootSessionFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/LLFirNonUnderContentRootSessionFactory.kt index 6933dbdec41..f6267fc4138 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/LLFirNonUnderContentRootSessionFactory.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/LLFirNonUnderContentRootSessionFactory.kt @@ -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(FirJvmTypeMapper::class, FirJvmTypeMapper(this)) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirIdePredicateBasedProvider.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirIdePredicateBasedProvider.kt index c3bd72e847d..ef2a5adfeb1 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirIdePredicateBasedProvider.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirIdePredicateBasedProvider.kt @@ -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.KotlinDeclarationProvider 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.createCache 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.FirDeclaration 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.FirPredicateBasedProvider 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.psi +import org.jetbrains.kotlin.fir.resolve.getCorrespondingClassSymbolOrNull import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol -import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef -import org.jetbrains.kotlin.fir.types.classId +import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol +import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitorVoid import org.jetbrains.kotlin.fir.visitors.FirVisitor import org.jetbrains.kotlin.name.ClassId @@ -52,8 +56,8 @@ internal class LLFirIdePredicateBasedProvider( private val declarationOwnersCache: FirCache = session.firCachesFactory.createCache { firFile -> FirOwnersStorage.collectOwners(firFile) } - override fun getSymbolsByPredicate(predicate: DeclarationPredicate): List> { - val annotations = registeredPluginAnnotations.getAnnotationsForPredicate(predicate) + override fun getSymbolsByPredicate(predicate: LookupPredicate): List> { + val annotations = predicate.annotations val annotatedDeclarations = annotations .asSequence() .flatMap { annotationsResolver.declarationsByAnnotation(ClassId.topLevel(it)) } @@ -99,80 +103,83 @@ internal class LLFirIdePredicateBasedProvider( } } - override fun matches(predicate: DeclarationPredicate, declaration: FirDeclaration): Boolean { - return predicate.accept(matcher, declaration) + override fun matches(predicate: AbstractPredicate<*>, declaration: FirDeclaration): Boolean { + return when (predicate) { + is DeclarationPredicate -> predicate.accept(declarationPredicateMatcher, declaration) + is LookupPredicate -> predicate.accept(lookupPredicateMatcher, declaration) + } } - private val matcher: Matcher = Matcher() + private val declarationPredicateMatcher = Matcher() + private val lookupPredicateMatcher = Matcher() - private inner class Matcher : DeclarationPredicateVisitor() { - override fun visitPredicate(predicate: DeclarationPredicate, data: FirDeclaration): Boolean { - error("When overrides for all possible DeclarationPredicate subtypes are implemented, " + - "this method should never be called, but it was called with $predicate") + private inner class Matcher

> : PredicateVisitor() { + override fun visitPredicate(predicate: AbstractPredicate

, data: FirDeclaration): Boolean { + error( + "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

, data: FirDeclaration): Boolean { 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

, data: FirDeclaration): Boolean { 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

, data: FirDeclaration): Boolean { return annotationsOnDeclaration(data).any { it in predicate.annotations } } - override fun visitAncestorAnnotatedWith(predicate: AncestorAnnotatedWith, data: FirDeclaration): Boolean { + override fun visitAncestorAnnotatedWith(predicate: AbstractPredicate.AncestorAnnotatedWith

, data: FirDeclaration): Boolean { return annotationsOnOuterDeclarations(data).any { it in predicate.annotations } } - override fun visitMetaAnnotatedWith(predicate: MetaAnnotatedWith, data: FirDeclaration): Boolean { - return metaAnnotationsOnDeclaration(data).any { it in predicate.metaAnnotations } + override fun visitMetaAnnotatedWith(predicate: AbstractPredicate.MetaAnnotatedWith

, data: FirDeclaration): Boolean { + val visited = mutableSetOf() + return data.annotations.any { annotation -> + annotation.markedWithMetaAnnotation(predicate.metaAnnotations, visited) + } } - override fun visitAncestorMetaAnnotatedWith(predicate: AncestorMetaAnnotatedWith, data: FirDeclaration): Boolean { - return metaAnnotationsOnOuterDeclarations(data).any { it in predicate.metaAnnotations } + private fun FirAnnotation.markedWithMetaAnnotation( + metaAnnotations: Set, + visited: MutableSet + ): 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

, data: FirDeclaration): Boolean { 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 { - val childPredicate = 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) + override fun visitHasAnnotatedWith(predicate: AbstractPredicate.HasAnnotatedWith

, data: FirDeclaration): Boolean { + val childPredicate = DeclarationPredicate.AnnotatedWith(predicate.annotations) return data.anyDirectChildDeclarationMatches(childPredicate) } private val FirDeclaration.directParentDeclaration: FirDeclaration? get() = getOwnersOfDeclaration(this)?.lastOrNull()?.fir + } - private fun FirDeclaration.anyDirectChildDeclarationMatches(childPredicate: DeclarationPredicate): Boolean { - var result = false + private fun FirDeclaration.anyDirectChildDeclarationMatches(childPredicate: DeclarationPredicate): Boolean { + var result = false - this.forEachDirectChildDeclaration { - result = result || childPredicate.accept(this@Matcher, it) - } - - return result + this.forEachDirectChildDeclaration { + result = result || childPredicate.accept(declarationPredicateMatcher, it) } + + return result } private fun annotationsOnDeclaration(declaration: FirDeclaration): Set { @@ -193,24 +200,9 @@ internal class LLFirIdePredicateBasedProvider( return psiAnnotations.map { it.asSingleFqName() }.toSet() } - private fun metaAnnotationsOnDeclaration(declaration: FirDeclaration): Set { - 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 { return getOwnersOfDeclaration(declaration)?.flatMap { annotationsOnDeclaration(it.fir) }.orEmpty().toSet() } - - private fun metaAnnotationsOnOuterDeclarations(declaration: FirDeclaration): Set { - return getOwnersOfDeclaration(declaration)?.flatMap { metaAnnotationsOnDeclaration(it.fir) }.orEmpty().toSet() - } } private class FirOwnersStorage(private val declarationToOwner: Map>>) { diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirIdeRegisteredPluginAnnotations.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirIdeRegisteredPluginAnnotations.kt index 5b19cf4d4cd..c8cfee4d644 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirIdeRegisteredPluginAnnotations.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirIdeRegisteredPluginAnnotations.kt @@ -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.fir.FirSession 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.AnnotationFqn import org.jetbrains.kotlin.name.ClassId @@ -26,25 +25,14 @@ internal class LLFirIdeRegisteredPluginAnnotations( get() = allAnnotationsCache.getValue() private val allAnnotationsCache: FirLazyValue, Nothing?> = session.firCachesFactory.createLazyValue { - // at this point, both metaAnnotations and annotationsFromPlugins should be collected - val result = metaAnnotations.flatMapTo(mutableSetOf()) { getAnnotationsWithMetaAnnotation(it) } - - if (result.isEmpty()) { - annotationsFromPlugins - } else { - result += annotationsFromPlugins - result - } + // at this point, annotationsFromPlugins should be collected + annotationsFromPlugins } // MetaAnnotation -> Annotations private val annotationsWithMetaAnnotationCache: FirCache, Nothing?> = session.firCachesFactory.createCache { metaAnnotation -> collectAnnotationsWithMetaAnnotation(metaAnnotation) } - override fun getAnnotationsWithMetaAnnotation(metaAnnotation: AnnotationFqn): Collection { - return annotationsWithMetaAnnotationCache.getValue(metaAnnotation) - } - private fun collectAnnotationsWithMetaAnnotation(metaAnnotation: AnnotationFqn): Set { val annotatedDeclarations = annotationsResolver.declarationsByAnnotation(ClassId.topLevel(metaAnnotation)) @@ -59,8 +47,4 @@ internal class LLFirIdeRegisteredPluginAnnotations( override fun saveAnnotationsFromPlugin(annotations: Collection) { annotationsFromPlugins += annotations } - - override fun registerUserDefinedAnnotation(metaAnnotation: AnnotationFqn, annotationClasses: Collection) { - error("This method should never be called in IDE mode") - } } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionFactory.kt index 84be618660b..2a285652dcf 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionFactory.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionFactory.kt @@ -214,7 +214,7 @@ internal object LLFirSessionFactory { // We need FirRegisteredPluginAnnotations during extensions' registration process val annotationsResolver = project.createAnnotationResolver(contentScope) register(FirRegisteredPluginAnnotations::class, LLFirIdeRegisteredPluginAnnotations(this@session, annotationsResolver)) - register(FirPredicateBasedProvider::class, FirEmptyPredicateBasedProvider()) + register(FirPredicateBasedProvider::class, FirEmptyPredicateBasedProvider) val dependencyProvider = LLFirDependentModuleProvidersByProviders(this) { // - diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirDesignatedAnnotationsResolveTransformed.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirDesignatedAnnotationsResolveTransformed.kt index 94d450fb2a9..d8042905bfc 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirDesignatedAnnotationsResolveTransformed.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirDesignatedAnnotationsResolveTransformed.kt @@ -24,7 +24,7 @@ internal class LLFirDesignatedAnnotationsResolveTransformed( if (!designationIterator.hasNext()) { val declaration = designation.declaration if (declaration is FirRegularClass || declaration is FirTypeAlias) { - declaration.transform(this, Mode.RegularAnnotations) + declaration.transform(this, null) } return } @@ -63,5 +63,4 @@ internal class LLFirDesignatedAnnotationsResolveTransformed( // todo add proper check that COMPILER_REQUIRED_ANNOTATIONS are resolved // checkNestedDeclarationsAreResolved(declaration) } - } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirPredicateBasedProviderImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirPredicateBasedProviderImpl.kt index 6ce69988b02..268bfc6f3b0 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirPredicateBasedProviderImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirPredicateBasedProviderImpl.kt @@ -12,17 +12,23 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.NoMutableState import org.jetbrains.kotlin.fir.declarations.FirDeclaration 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.getCorrespondingClassSymbolOrNull import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol @NoMutableState class FirPredicateBasedProviderImpl(private val session: FirSession) : FirPredicateBasedProvider() { private val registeredPluginAnnotations = session.registeredPluginAnnotations private val cache = Cache() - override fun getSymbolsByPredicate(predicate: DeclarationPredicate): List> { - val annotations = registeredPluginAnnotations.getAnnotationsForPredicate(predicate) + override fun getSymbolsByPredicate(predicate: LookupPredicate): List> { + val annotations = predicate.annotations if (annotations.isEmpty()) return emptyList() val declarations = annotations.flatMapTo(mutableSetOf()) { cache.declarationByAnnotation[it] + cache.declarationsUnderAnnotated[it] @@ -76,66 +82,75 @@ class FirPredicateBasedProviderImpl(private val session: FirSession) : FirPredic // ---------------------------------- Matching ---------------------------------- - override fun matches(predicate: DeclarationPredicate, declaration: FirDeclaration): Boolean { - return predicate.accept(matcher, declaration) + override fun matches(predicate: AbstractPredicate<*>, declaration: FirDeclaration): Boolean { + return when (predicate) { + is DeclarationPredicate -> predicate.accept(declarationPredicateMatcher, declaration) + is LookupPredicate -> predicate.accept(lookupPredicateMatcher, declaration) + } } - private val matcher = Matcher() + private val declarationPredicateMatcher = Matcher() + private val lookupPredicateMatcher = Matcher() - private inner class Matcher : DeclarationPredicateVisitor() { - override fun visitPredicate(predicate: DeclarationPredicate, data: FirDeclaration): Boolean { + private inner class Matcher

> : PredicateVisitor() { + override fun visitPredicate(predicate: AbstractPredicate

, data: FirDeclaration): Boolean { throw IllegalStateException("Should not be there") } - override fun visitAnd(predicate: DeclarationPredicate.And, data: FirDeclaration): Boolean { + override fun visitAnd(predicate: AbstractPredicate.And

, data: FirDeclaration): Boolean { 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

, data: FirDeclaration): Boolean { return predicate.a.accept(this, data) || predicate.b.accept(this, data) } // ------------------------------------ Annotated ------------------------------------ - override fun visitAnnotatedWith(predicate: AnnotatedWith, data: FirDeclaration): Boolean { + override fun visitAnnotatedWith(predicate: AbstractPredicate.AnnotatedWith

, data: FirDeclaration): Boolean { return matchWith(data, predicate.annotations) } - override fun visitAncestorAnnotatedWith(predicate: AncestorAnnotatedWith, data: FirDeclaration): Boolean { + override fun visitAncestorAnnotatedWith( + predicate: AbstractPredicate.AncestorAnnotatedWith

, + data: FirDeclaration + ): Boolean { return matchUnder(data, predicate.annotations) } - override fun visitParentAnnotatedWith(predicate: ParentAnnotatedWith, data: FirDeclaration): Boolean { + override fun visitParentAnnotatedWith( + predicate: AbstractPredicate.ParentAnnotatedWith

, + data: FirDeclaration + ): Boolean { return matchParentWith(data, predicate.annotations) } - override fun visitHasAnnotatedWith(predicate: HasAnnotatedWith, data: FirDeclaration): Boolean { + override fun visitHasAnnotatedWith(predicate: AbstractPredicate.HasAnnotatedWith

, data: FirDeclaration): Boolean { return matchHasAnnotatedWith(data, predicate.annotations) } - // ------------------------------------ Meta Annotated ------------------------------------ + // ------------------------------------ Meta-annotated ------------------------------------ - override fun visitMetaAnnotatedWith(predicate: MetaAnnotatedWith, data: FirDeclaration): Boolean { - return matchWith(data, predicate.userDefinedAnnotations) + override fun visitMetaAnnotatedWith(predicate: AbstractPredicate.MetaAnnotatedWith

, data: FirDeclaration): Boolean { + val visited = mutableSetOf() + return data.annotations.any { annotation -> + annotation.markedWithMetaAnnotation(predicate.metaAnnotations, visited) + } } - override fun visitAncestorMetaAnnotatedWith(predicate: AncestorMetaAnnotatedWith, data: FirDeclaration): Boolean { - return matchUnder(data, predicate.userDefinedAnnotations) - } - - override fun visitParentMetaAnnotatedWith(predicate: ParentMetaAnnotatedWith, data: FirDeclaration): Boolean { - return matchParentWith(data, predicate.userDefinedAnnotations) - } - - override fun visitHasMetaAnnotatedWith(predicate: HasMetaAnnotatedWith, data: FirDeclaration): Boolean { - return matchHasAnnotatedWith(data, predicate.userDefinedAnnotations) + private fun FirAnnotation.markedWithMetaAnnotation( + metaAnnotations: Set, + visited: MutableSet + ): 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 } // ------------------------------------ Utilities ------------------------------------ - private val MetaAnnotated.userDefinedAnnotations: Set - get() = metaAnnotations.flatMapTo(mutableSetOf()) { registeredPluginAnnotations.getAnnotationsWithMetaAnnotation(it) } - private fun matchWith(declaration: FirDeclaration, annotations: Set): Boolean { return cache.annotationsOfDeclaration[declaration].any { it in annotations } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirRegisteredPluginAnnotations.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirRegisteredPluginAnnotations.kt index 74a847f2142..4719bdb9d8b 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirRegisteredPluginAnnotations.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirRegisteredPluginAnnotations.kt @@ -5,39 +5,21 @@ 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.FirSessionComponent import org.jetbrains.kotlin.fir.NoMutableState -import org.jetbrains.kotlin.fir.caches.FirCache -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.AbstractPredicate import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate +import org.jetbrains.kotlin.fir.extensions.predicate.LookupPredicate 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, - * and all the user-defined annotations which are meta-annotated by the annotations from the [metaAnnotations] list. + * Contains all annotations that can be targeted by lookup predicates from plugins */ abstract val annotations: Set - /** - * Contains meta-annotations that can be targeted by the plugins. - */ - abstract val metaAnnotations: Set - val hasRegisteredAnnotations: Boolean - get() = annotations.isNotEmpty() || metaAnnotations.isNotEmpty() - - abstract fun getAnnotationsWithMetaAnnotation(metaAnnotation: AnnotationFqn): Collection - - abstract fun registerUserDefinedAnnotation(metaAnnotation: AnnotationFqn, annotationClasses: Collection) - - abstract fun getAnnotationsForPredicate(predicate: DeclarationPredicate): Set + get() = annotations.isNotEmpty() @PluginServicesInitialization abstract fun initialize() @@ -50,33 +32,16 @@ abstract class FirRegisteredPluginAnnotations(protected val session: FirSession) * It also has some common code in it. */ abstract class AbstractFirRegisteredPluginAnnotations(session: FirSession) : FirRegisteredPluginAnnotations(session) { - final override val metaAnnotations: MutableSet = mutableSetOf() - - private val annotationsForPredicateCache: FirCache, Nothing?> = - session.firCachesFactory.createCache { predicate -> - collectAnnotations(predicate) - } - - final override fun getAnnotationsForPredicate(predicate: DeclarationPredicate): Set { - return annotationsForPredicateCache.getValue(predicate) - } - - private fun collectAnnotations(predicate: DeclarationPredicate): Set { - val result = predicate.metaAnnotations.flatMapTo(mutableSetOf()) { getAnnotationsWithMetaAnnotation(it) } - if (result.isEmpty()) return predicate.annotations - result += predicate.annotations - return result - } - @PluginServicesInitialization final override fun initialize() { val registrar = object : FirDeclarationPredicateRegistrar() { - val predicates = mutableListOf() - override fun register(vararg predicates: DeclarationPredicate) { + val predicates = mutableListOf>() + + override fun register(vararg predicates: AbstractPredicate<*>) { this.predicates += predicates } - override fun register(predicates: Collection) { + override fun register(predicates: Collection>) { this.predicates += predicates } } @@ -89,7 +54,6 @@ abstract class AbstractFirRegisteredPluginAnnotations(session: FirSession) : Fir for (predicate in registrar.predicates) { saveAnnotationsFromPlugin(predicate.annotations) - metaAnnotations += predicate.metaAnnotations } } @@ -100,23 +64,9 @@ abstract class AbstractFirRegisteredPluginAnnotations(session: FirSession) : Fir class FirRegisteredPluginAnnotationsImpl(session: FirSession) : AbstractFirRegisteredPluginAnnotations(session) { override val annotations: MutableSet = mutableSetOf() - // MetaAnnotation -> Annotations - private val userDefinedAnnotations: Multimap = LinkedHashMultimap.create() - - override fun getAnnotationsWithMetaAnnotation(metaAnnotation: AnnotationFqn): Collection { - return userDefinedAnnotations[metaAnnotation] - } - override fun saveAnnotationsFromPlugin(annotations: Collection) { this.annotations += annotations } - - override fun registerUserDefinedAnnotation(metaAnnotation: AnnotationFqn, annotationClasses: Collection) { - 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() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirCompilerRequiredAnnotationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirCompilerRequiredAnnotationsResolveTransformer.kt index 9eb146167a4..035290561e2 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirCompilerRequiredAnnotationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirCompilerRequiredAnnotationsResolveTransformer.kt @@ -5,11 +5,8 @@ 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.persistentListOf -import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirSession 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.resolve.ResolutionMode 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.transformers.* -import org.jetbrains.kotlin.fir.resolve.transformers.plugin.FirCompilerRequiredAnnotationsResolveTransformer.Mode import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.FirUserTypeRef 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.FqName 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.DeprecatedSinceKotlin import org.jetbrains.kotlin.name.StandardClassIds.Annotations.JvmRecord @@ -46,25 +40,9 @@ class FirCompilerRequiredAnnotationsResolveProcessor( override fun process(files: Collection) { 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 { withFileAnalysisExceptionWrapping(it) { - it.transformSingle(transformer, Mode.RegularAnnotations) + it.transformSingle(transformer, null) } } } @@ -83,42 +61,21 @@ class FirCompilerRequiredAnnotationsResolveProcessor( open class FirCompilerRequiredAnnotationsResolveTransformer( final override val session: FirSession, scopeSession: ScopeSession -) : FirAbstractPhaseTransformer(COMPILER_REQUIRED_ANNOTATIONS) { - enum class Mode { - MetaAnnotations, - RegularAnnotations - } - +) : FirAbstractPhaseTransformer(COMPILER_REQUIRED_ANNOTATIONS) { private val annotationTransformer = FirAnnotationResolveTransformer(session, scopeSession) private val importTransformer = FirPartialImportResolveTransformer(session) val extensionService = session.extensionService - override fun transformElement(element: E, data: Mode): E { + override fun transformElement(element: E, data: Nothing?): E { throw IllegalStateException("Should not be here") } - override fun transformFile(file: FirFile, data: Mode): FirFile { + override fun transformFile(file: FirFile, data: Nothing?): FirFile { checkSessionConsistency(file) val registeredPluginAnnotations = session.registeredPluginAnnotations - val regularAnnotations: Set - val metaAnnotations: Set - when (data) { - Mode.MetaAnnotations -> { - regularAnnotations = emptySet() - metaAnnotations = registeredPluginAnnotations.metaAnnotations - } - Mode.RegularAnnotations -> { - regularAnnotations = registeredPluginAnnotations.annotations - metaAnnotations = emptySet() - } - } + val regularAnnotations = registeredPluginAnnotations.annotations - val newAnnotations = file.resolveAnnotations(regularAnnotations, metaAnnotations) - if (!newAnnotations.isEmpty) { - for (metaAnnotation in newAnnotations.keySet()) { - registeredPluginAnnotations.registerUserDefinedAnnotation(metaAnnotation, newAnnotations[metaAnnotation]) - } - } + file.resolveAnnotations(regularAnnotations) return file } @@ -128,27 +85,21 @@ open class FirCompilerRequiredAnnotationsResolveTransformer( } } - override fun transformRegularClass(regularClass: FirRegularClass, data: Mode): FirStatement { - return annotationTransformer.transformRegularClass(regularClass, LinkedHashMultimap.create()) + override fun transformRegularClass(regularClass: FirRegularClass, data: Nothing?): FirStatement { + return annotationTransformer.transformRegularClass(regularClass, null) } - override fun transformTypeAlias(typeAlias: FirTypeAlias, data: Mode): FirStatement { - return annotationTransformer.transformTypeAlias(typeAlias, LinkedHashMultimap.create()) + override fun transformTypeAlias(typeAlias: FirTypeAlias, data: Nothing?): FirStatement { + return annotationTransformer.transformTypeAlias(typeAlias, null) } - private fun FirFile.resolveAnnotations( - annotations: Set, - metaAnnotations: Set - ): Multimap { - val acceptableNames = annotations + metaAnnotations + private fun FirFile.resolveAnnotations(annotations: Set) { + val acceptableNames = annotations importTransformer.acceptableFqNames = acceptableNames this.transformImports(importTransformer, null) annotationTransformer.acceptableFqNames = acceptableNames - annotationTransformer.metaAnnotations = metaAnnotations - val newAnnotations = LinkedHashMultimap.create() - this.transform>(annotationTransformer, newAnnotations) - return newAnnotations + this.transform(annotationTransformer, null) } } @@ -164,9 +115,7 @@ private class FirPartialImportResolveTransformer( private class FirAnnotationResolveTransformer( session: FirSession, scopeSession: ScopeSession -) : FirAbstractAnnotationResolveTransformer, PersistentList>( - session, scopeSession -) { +) : FirAbstractAnnotationResolveTransformer>(session, scopeSession) { companion object { private val REQUIRED_ANNOTATIONS: Set = setOf( Deprecated, DeprecatedSinceKotlin, WasExperimental, JvmRecord @@ -178,7 +127,7 @@ private class FirAnnotationResolveTransformer( private val predicateBasedProvider = session.predicateBasedProvider var acceptableFqNames: Set = emptySet() - var metaAnnotations: Set = emptySet() + private val typeResolverTransformer: FirSpecificTypeResolverTransformer = FirSpecificTypeResolverTransformer( session, errorTypeAsResolved = false @@ -200,14 +149,11 @@ private class FirAnnotationResolveTransformer( owners = state } - override fun transformAnnotationCall(annotationCall: FirAnnotationCall, data: Multimap): FirStatement { + override fun transformAnnotationCall(annotationCall: FirAnnotationCall, data: Nothing?): FirStatement { return transformAnnotation(annotationCall, data) } - override fun transformAnnotation( - annotation: FirAnnotation, - data: Multimap - ): FirStatement { + override fun transformAnnotation(annotation: FirAnnotation, data: Nothing?): FirStatement { val annotationTypeRef = annotation.annotationTypeRef if (annotationTypeRef !is FirUserTypeRef) return annotation val name = annotationTypeRef.qualifier.last().name @@ -224,36 +170,27 @@ private class FirAnnotationResolveTransformer( return transformedAnnotation } - override fun transformRegularClass( - regularClass: FirRegularClass, - data: Multimap - ): FirStatement { + override fun transformRegularClass(regularClass: FirRegularClass, data: Nothing?): FirStatement { withClassDeclarationCleanup(classDeclarationsStack, regularClass) { 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) } } } - override fun transformTypeAlias(typeAlias: FirTypeAlias, data: Multimap): FirTypeAlias { + override fun transformTypeAlias(typeAlias: FirTypeAlias, data: Nothing?): FirTypeAlias { return super.transformTypeAlias(typeAlias, data).also { calculateDeprecations(typeAlias) } } - override fun transformDeclaration(declaration: FirDeclaration, data: Multimap): FirDeclaration { + override fun transformDeclaration(declaration: FirDeclaration, data: Nothing?): FirDeclaration { return super.transformDeclaration(declaration, data).also { predicateBasedProvider.registerAnnotatedDeclaration(declaration, owners) } } - override fun transformFile(file: FirFile, data: Multimap): FirFile { + override fun transformFile(file: FirFile, data: Nothing?): FirFile { withFile(file) { return super.transformFile(file, data) } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/extensions/FirExtension.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/extensions/FirExtension.kt index b547562b23f..4662989131d 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/extensions/FirExtension.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/extensions/FirExtension.kt @@ -6,7 +6,9 @@ package org.jetbrains.kotlin.fir.extensions 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.LookupPredicate import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import kotlin.reflect.KClass @@ -38,8 +40,8 @@ data class FirExtensionPointName(val name: Name) { // todo: KDOC abstract class FirDeclarationPredicateRegistrar { - abstract fun register(vararg predicates: DeclarationPredicate) - abstract fun register(predicates: Collection) + abstract fun register(vararg predicates: AbstractPredicate<*>) + abstract fun register(predicates: Collection>) } @RequiresOptIn diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/extensions/FirPredicateBasedProvider.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/extensions/FirPredicateBasedProvider.kt index bb5604833b6..0100ff8969b 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/extensions/FirPredicateBasedProvider.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/extensions/FirPredicateBasedProvider.kt @@ -11,11 +11,13 @@ import org.jetbrains.kotlin.fir.FirSessionComponent import org.jetbrains.kotlin.fir.NoMutableState import org.jetbrains.kotlin.fir.declarations.FirDeclaration 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.LookupPredicate import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol abstract class FirPredicateBasedProvider : FirSessionComponent { - abstract fun getSymbolsByPredicate(predicate: DeclarationPredicate): List> + abstract fun getSymbolsByPredicate(predicate: LookupPredicate): List> abstract fun getOwnersOfDeclaration(declaration: FirDeclaration): List>? /** @@ -23,17 +25,17 @@ abstract class FirPredicateBasedProvider : FirSessionComponent { * @see FirRegisteredPluginAnnotations.annotations */ 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) } - fun matches(predicates: List, declaration: FirDeclaration): Boolean { + fun matches(predicates: List>, declaration: FirDeclaration): Boolean { return predicates.any { matches(it, declaration) } } - fun matches(predicates: List, declaration: FirBasedSymbol<*>): Boolean { + fun matches(predicates: List>, declaration: FirBasedSymbol<*>): Boolean { return matches(predicates, declaration.fir) } @@ -41,14 +43,14 @@ abstract class FirPredicateBasedProvider : FirSessionComponent { } @NoMutableState -class FirEmptyPredicateBasedProvider(): FirPredicateBasedProvider() { - override fun getSymbolsByPredicate(predicate: DeclarationPredicate): List> = emptyList() +object FirEmptyPredicateBasedProvider : FirPredicateBasedProvider() { + override fun getSymbolsByPredicate(predicate: LookupPredicate): List> = emptyList() override fun getOwnersOfDeclaration(declaration: FirDeclaration): List>? = null 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() diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/extensions/predicate/AbstractPredicate.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/extensions/predicate/AbstractPredicate.kt new file mode 100644 index 00000000000..8b0507d4029 --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/extensions/predicate/AbstractPredicate.kt @@ -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

> { + val annotations: Set + val metaAnnotations: Set + + fun accept(visitor: PredicateVisitor, data: D): R + + sealed interface Or

> : AbstractPredicate

{ + val a: P + val b: P + + override fun accept(visitor: PredicateVisitor, data: D): R { + return visitor.visitOr(this, data) + } + } + + sealed interface And

> : AbstractPredicate

{ + val a: P + val b: P + + override fun accept(visitor: PredicateVisitor, data: D): R { + return visitor.visitAnd(this, data) + } + } + + // ------------------------------------ Annotated ------------------------------------ + + sealed interface Annotated

> : AbstractPredicate

{ + override fun accept(visitor: PredicateVisitor, data: D): R { + return visitor.visitAnnotated(this, data) + } + } + + sealed interface AnnotatedWith

> : Annotated

{ + override fun accept(visitor: PredicateVisitor, data: D): R { + return visitor.visitAnnotatedWith(this, data) + } + } + + sealed interface AncestorAnnotatedWith

> : Annotated

{ + override fun accept(visitor: PredicateVisitor, data: D): R { + return visitor.visitAncestorAnnotatedWith(this, data) + } + } + + + sealed interface ParentAnnotatedWith

> : Annotated

{ + override fun accept(visitor: PredicateVisitor, data: D): R { + return visitor.visitParentAnnotatedWith(this, data) + } + } + + sealed interface HasAnnotatedWith

> : Annotated

{ + override fun accept(visitor: PredicateVisitor, data: D): R { + return visitor.visitHasAnnotatedWith(this, data) + } + } + + // ------------------------------------ MetaAnnotated ------------------------------------ + + sealed interface MetaAnnotatedWith

> : AbstractPredicate

{ + override fun accept(visitor: PredicateVisitor, data: D): R { + return visitor.visitMetaAnnotatedWith(this, data) + } + } + + // -------------------------------------------- DSL -------------------------------------------- + + abstract class BuilderContext

> { + 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): P + abstract fun ancestorAnnotated(annotations: Collection): P + abstract fun parentAnnotated(annotations: Collection): P + abstract fun hasAnnotated(annotations: Collection): P + + abstract fun annotatedOrUnder(annotations: Collection): P + } +} diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/extensions/predicate/DeclarationPredicate.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/extensions/predicate/DeclarationPredicate.kt index fecb725b13e..03af7461545 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/extensions/predicate/DeclarationPredicate.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/extensions/predicate/DeclarationPredicate.kt @@ -10,226 +10,215 @@ import org.jetbrains.kotlin.fir.extensions.AnnotationFqn // -------------------------------------------- Predicates -------------------------------------------- // todo: Missing KDOC -sealed class DeclarationPredicate { - abstract val annotations: Set - abstract val metaAnnotations: Set +sealed class DeclarationPredicate : AbstractPredicate { + abstract override val annotations: Set + abstract override val metaAnnotations: Set - abstract fun accept(visitor: DeclarationPredicateVisitor, data: D): R + abstract override fun accept(visitor: PredicateVisitor, 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 { override val annotations: Set = a.annotations + b.annotations override val metaAnnotations: Set = a.metaAnnotations + b.metaAnnotations - override fun accept(visitor: DeclarationPredicateVisitor, data: D): R { + override fun accept(visitor: PredicateVisitor, data: D): R { 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 { override val annotations: Set = a.annotations + b.annotations override val metaAnnotations: Set = a.metaAnnotations + b.metaAnnotations - override fun accept(visitor: DeclarationPredicateVisitor, data: D): R { + override fun accept(visitor: PredicateVisitor, data: D): R { return visitor.visitAnd(this, data) } } -} -// ------------------------------------ Annotated ------------------------------------ + // ------------------------------------ Annotated ------------------------------------ -/** - * Base class for all predicates with specific annotations - * Declaration will be matched if at least one of [annotations] is found - */ -sealed class Annotated(final override val annotations: Set) : DeclarationPredicate() { - init { - require(annotations.isNotEmpty()) { - "Annotations should be not empty" + /** + * 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) : DeclarationPredicate(), + AbstractPredicate.Annotated { + init { + require(annotations.isNotEmpty()) { + "Annotations should be not empty" + } + } + + final override val metaAnnotations: Set + get() = emptySet() + + override fun accept(visitor: PredicateVisitor, data: D): R { + return visitor.visitAnnotated(this, data) } } - final override val metaAnnotations: Set - get() = emptySet() - - override fun accept(visitor: DeclarationPredicateVisitor, 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) : Annotated(annotations) { - override fun accept(visitor: DeclarationPredicateVisitor, 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) : Annotated(annotations) { - override fun accept(visitor: DeclarationPredicateVisitor, 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) : Annotated(annotations) { - override fun accept(visitor: DeclarationPredicateVisitor, 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) : Annotated(annotations) { - override fun accept(visitor: DeclarationPredicateVisitor, data: D): R { - return visitor.visitHasAnnotatedWith(this, data) - } -} - -// ------------------------------------ MetaAnnotated ------------------------------------ - -sealed class MetaAnnotated(final override val metaAnnotations: Set) : DeclarationPredicate() { - init { - require(metaAnnotations.isNotEmpty()) { - "Annotations should be not empty" + /** + * 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) : Annotated(annotations), AbstractPredicate.AnnotatedWith { + override fun accept(visitor: PredicateVisitor, data: D): R { + return visitor.visitAnnotatedWith(this, data) } } - final override val annotations: Set - 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) : Annotated(annotations), + AbstractPredicate.AncestorAnnotatedWith { + override fun accept(visitor: PredicateVisitor, data: D): R { + return visitor.visitAncestorAnnotatedWith(this, data) + } + } - override fun accept(visitor: DeclarationPredicateVisitor, 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) : Annotated(annotations), + AbstractPredicate.ParentAnnotatedWith { + override fun accept(visitor: PredicateVisitor, 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) : Annotated(annotations), + AbstractPredicate.HasAnnotatedWith { + override fun accept(visitor: PredicateVisitor, data: D): R { + return visitor.visitHasAnnotatedWith(this, data) + } + } + + // ------------------------------------ MetaAnnotated ------------------------------------ + + class MetaAnnotatedWith( + override val metaAnnotations: Set + ) : DeclarationPredicate(), AbstractPredicate.MetaAnnotatedWith { + init { + require(metaAnnotations.isNotEmpty()) { + "Annotations should be not empty" + } + } + + override val annotations: Set + get() = emptySet() + + override fun accept(visitor: PredicateVisitor, data: D): R { + return visitor.visitMetaAnnotatedWith(this, data) + } + } + + // -------------------------------------------- DSL -------------------------------------------- + + object BuilderContext : AbstractPredicate.BuilderContext() { + 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): DeclarationPredicate = AnnotatedWith(annotations.toSet()) + override fun ancestorAnnotated(annotations: Collection): DeclarationPredicate = + AncestorAnnotatedWith(annotations.toSet()) + + override fun parentAnnotated(annotations: Collection): DeclarationPredicate = + ParentAnnotatedWith(annotations.toSet()) + + override fun hasAnnotated(annotations: Collection): DeclarationPredicate = HasAnnotatedWith(annotations.toSet()) + + override fun annotatedOrUnder(annotations: Collection): DeclarationPredicate = + annotated(annotations) or ancestorAnnotated(annotations) + + fun metaAnnotated(metaAnnotations: Collection): DeclarationPredicate = MetaAnnotatedWith(metaAnnotations.toSet()) + } + + companion object { + inline fun create(init: BuilderContext.() -> DeclarationPredicate): DeclarationPredicate = BuilderContext.init() } } - -class MetaAnnotatedWith(metaAnnotations: Set) : MetaAnnotated(metaAnnotations) { - override fun accept(visitor: DeclarationPredicateVisitor, data: D): R { - return visitor.visitMetaAnnotatedWith(this, data) - } -} - -class AncestorMetaAnnotatedWith(metaAnnotations: Set) : MetaAnnotated(metaAnnotations) { - override fun accept(visitor: DeclarationPredicateVisitor, data: D): R { - return visitor.visitAncestorMetaAnnotatedWith(this, data) - } -} - -class ParentMetaAnnotatedWith(metaAnnotations: Set) : MetaAnnotated(metaAnnotations) { - override fun accept(visitor: DeclarationPredicateVisitor, data: D): R { - return visitor.visitParentMetaAnnotatedWith(this, data) - } -} - -class HasMetaAnnotatedWith(metaAnnotations: Set) : MetaAnnotated(metaAnnotations) { - override fun accept(visitor: DeclarationPredicateVisitor, 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): DeclarationPredicate = AnnotatedWith(annotations.toSet()) -fun ancestorAnnotated(annotations: Collection): DeclarationPredicate = AncestorAnnotatedWith(annotations.toSet()) -fun parentAnnotated(annotations: Collection): DeclarationPredicate = ParentAnnotatedWith(annotations.toSet()) -fun hasAnnotated(annotations: Collection): DeclarationPredicate = HasAnnotatedWith(annotations.toSet()) - -fun metaAnnotated(metaAnnotations: Collection): DeclarationPredicate = MetaAnnotatedWith(metaAnnotations.toSet()) -fun metaAncestorAnnotated(metaAnnotations: Collection): DeclarationPredicate = AncestorMetaAnnotatedWith(metaAnnotations.toSet()) -fun parentMetaAnnotated(metaAnnotations: Collection): DeclarationPredicate = ParentMetaAnnotatedWith(metaAnnotations.toSet()) -fun hasMetaAnnotated(metaAnnotations: Collection): DeclarationPredicate = HasMetaAnnotatedWith(metaAnnotations.toSet()) - -fun annotatedOrUnder(annotations: Collection): DeclarationPredicate = annotated(annotations) or ancestorAnnotated(annotations) -fun metaAnnotatedOrUnder(metaAnnotations: Collection): DeclarationPredicate = - metaAnnotated(metaAnnotations) or metaAncestorAnnotated(metaAnnotations) diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/extensions/predicate/DeclarationPredicateVisitor.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/extensions/predicate/DeclarationPredicateVisitor.kt deleted file mode 100644 index 4686495e28f..00000000000 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/extensions/predicate/DeclarationPredicateVisitor.kt +++ /dev/null @@ -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 { - 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) - } -} diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/extensions/predicate/LookupPredicate.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/extensions/predicate/LookupPredicate.kt new file mode 100644 index 00000000000..779b3e5b67c --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/extensions/predicate/LookupPredicate.kt @@ -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 { + abstract override val annotations: Set + final override val metaAnnotations: Set + get() = error("Should not be called") + + abstract override fun accept(visitor: PredicateVisitor, data: D): R + + class Or( + override val a: LookupPredicate, + override val b: LookupPredicate + ) : LookupPredicate(), AbstractPredicate.Or { + override val annotations: Set = a.annotations + b.annotations + + override fun accept(visitor: PredicateVisitor, data: D): R { + return visitor.visitOr(this, data) + } + } + + class And( + override val a: LookupPredicate, + override val b: LookupPredicate + ) : LookupPredicate(), AbstractPredicate.And { + override val annotations: Set = a.annotations + b.annotations + + override fun accept(visitor: PredicateVisitor, 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) : LookupPredicate(), AbstractPredicate.Annotated { + init { + require(annotations.isNotEmpty()) { + "Annotations should be not empty" + } + } + + override fun accept(visitor: PredicateVisitor, 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) : Annotated(annotations), AbstractPredicate.AnnotatedWith { + override fun accept(visitor: PredicateVisitor, 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) : Annotated(annotations), AbstractPredicate.AncestorAnnotatedWith { + override fun accept(visitor: PredicateVisitor, 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) : Annotated(annotations), AbstractPredicate.ParentAnnotatedWith { + override fun accept(visitor: PredicateVisitor, 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) : Annotated(annotations), AbstractPredicate.HasAnnotatedWith { + override fun accept(visitor: PredicateVisitor, data: D): R { + return visitor.visitHasAnnotatedWith(this, data) + } + } + + // -------------------------------------------- DSL -------------------------------------------- + + object BuilderContext : AbstractPredicate.BuilderContext() { + 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): LookupPredicate = AnnotatedWith(annotations.toSet()) + override fun ancestorAnnotated(annotations: Collection): LookupPredicate = AncestorAnnotatedWith(annotations.toSet()) + override fun parentAnnotated(annotations: Collection): LookupPredicate = ParentAnnotatedWith(annotations.toSet()) + override fun hasAnnotated(annotations: Collection): LookupPredicate = HasAnnotatedWith(annotations.toSet()) + override fun annotatedOrUnder(annotations: Collection): LookupPredicate = + annotated(annotations) or ancestorAnnotated(annotations) + } + + companion object { + inline fun create(init: BuilderContext.() -> LookupPredicate): LookupPredicate = BuilderContext.init() + } +} diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/extensions/predicate/PredicateVisitor.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/extensions/predicate/PredicateVisitor.kt new file mode 100644 index 00000000000..c99b0462436 --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/extensions/predicate/PredicateVisitor.kt @@ -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

, R, D> { + abstract fun visitPredicate(predicate: AbstractPredicate

, data: D): R + + open fun visitAnd(predicate: AbstractPredicate.And

, data: D): R { + return visitPredicate(predicate, data) + } + + open fun visitOr(predicate: AbstractPredicate.Or

, data: D): R { + return visitPredicate(predicate, data) + } + + open fun visitAnnotated(predicate: AbstractPredicate.Annotated

, data: D): R { + return visitPredicate(predicate, data) + } + + open fun visitAnnotatedWith(predicate: AbstractPredicate.AnnotatedWith

, data: D): R { + return visitAnnotated(predicate, data) + } + + open fun visitAncestorAnnotatedWith(predicate: AbstractPredicate.AncestorAnnotatedWith

, data: D): R { + return visitAnnotated(predicate, data) + } + + open fun visitParentAnnotatedWith(predicate: AbstractPredicate.ParentAnnotatedWith

, data: D): R { + return visitAnnotated(predicate, data) + } + + open fun visitHasAnnotatedWith(predicate: AbstractPredicate.HasAnnotatedWith

, data: D): R { + return visitAnnotated(predicate, data) + } + + open fun visitMetaAnnotatedWith(predicate: AbstractPredicate.MetaAnnotatedWith

, data: D): R { + return visitPredicate(predicate, data) + } +} + +typealias DeclarationPredicateVisitor = PredicateVisitor +typealias LookupPredicateVisitor = PredicateVisitor diff --git a/plugins/allopen/allopen.k2/src/org/jetbrains/kotlin/allopen/fir/FirAllOpenStatusTransformer.kt b/plugins/allopen/allopen.k2/src/org/jetbrains/kotlin/allopen/fir/FirAllOpenStatusTransformer.kt index d2e97afb1fc..f5202413630 100644 --- a/plugins/allopen/allopen.k2/src/org/jetbrains/kotlin/allopen/fir/FirAllOpenStatusTransformer.kt +++ b/plugins/allopen/allopen.k2/src/org/jetbrains/kotlin/allopen/fir/FirAllOpenStatusTransformer.kt @@ -15,9 +15,7 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.extensions.FirExtensionSessionComponent.Factory import org.jetbrains.kotlin.fir.extensions.FirStatusTransformerExtension -import org.jetbrains.kotlin.fir.extensions.predicate.annotated -import org.jetbrains.kotlin.fir.extensions.predicate.metaAnnotated -import org.jetbrains.kotlin.fir.extensions.predicate.or +import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate import org.jetbrains.kotlin.fir.extensions.utils.AbstractSimpleClassPredicateMatchingService import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider 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) } annotated(annotationFqNames) or metaAnnotated(annotationFqNames) } diff --git a/plugins/allopen/testData/bytecodeListing/anonymousObject.fir.txt b/plugins/allopen/testData/bytecodeListing/anonymousObject.fir.txt new file mode 100644 index 00000000000..4d0042f1aa2 --- /dev/null +++ b/plugins/allopen/testData/bytecodeListing/anonymousObject.fir.txt @@ -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.()V + inner (anonymous) class Test$a$1 + method (): 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 (): 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 (): void + private final static method b$lambda$0(): void + public method b(): void + public @org.jetbrains.annotations.NotNull method getA(): java.lang.Runnable +} diff --git a/plugins/allopen/testData/bytecodeListing/anonymousObject.kt b/plugins/allopen/testData/bytecodeListing/anonymousObject.kt index 5fe6ea2be5b..dcb2ffa6906 100644 --- a/plugins/allopen/testData/bytecodeListing/anonymousObject.kt +++ b/plugins/allopen/testData/bytecodeListing/anonymousObject.kt @@ -1,6 +1,6 @@ -// IGNORE_BACKEND_K2: JVM_IR // FIR version does not go inside bodies // Also it's quiestionable do we even need to transform local classes and anonymous objects + annotation class AllOpen @AllOpen diff --git a/plugins/allopen/testData/bytecodeListing/metaAnnotation.kt b/plugins/allopen/testData/bytecodeListing/metaAnnotation_differentModules.kt similarity index 89% rename from plugins/allopen/testData/bytecodeListing/metaAnnotation.kt rename to plugins/allopen/testData/bytecodeListing/metaAnnotation_differentModules.kt index 98f8e6e55cc..d94e7eda78a 100644 --- a/plugins/allopen/testData/bytecodeListing/metaAnnotation.kt +++ b/plugins/allopen/testData/bytecodeListing/metaAnnotation_differentModules.kt @@ -1,5 +1,4 @@ -// IGNORE_BACKEND_K2: JVM_IR -// FIR version does not support double-transitive annotations by design +// MODULE: lib annotation class AllOpen @AllOpen @@ -14,6 +13,8 @@ annotation class AnotherComponent @java.lang.annotation.Documented annotation class Documented +// MODULE: main(lib) + class TestWithoutAnnotations_ShouldBeFinal @Documented diff --git a/plugins/allopen/testData/bytecodeListing/metaAnnotation_differentModules.txt b/plugins/allopen/testData/bytecodeListing/metaAnnotation_differentModules.txt new file mode 100644 index 00000000000..16eca422f67 --- /dev/null +++ b/plugins/allopen/testData/bytecodeListing/metaAnnotation_differentModules.txt @@ -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 (): void +} + +@MyComponent +@kotlin.Metadata +public abstract class MyComponentBase { + // source: 'module_main_metaAnnotation_differentModules.kt' + public method (): void +} + +@kotlin.Metadata +public final class MyComponentImpl2_ShouldBeFinal { + // source: 'module_main_metaAnnotation_differentModules.kt' + public method (): void + public method method(): void +} + +@kotlin.Metadata +public class MyComponentImpl3_ShouldBeOpen { + // source: 'module_main_metaAnnotation_differentModules.kt' + public method (): void + public final method method_ShouldBeFinal(): void +} + +@kotlin.Metadata +public class MyComponentImpl_ShouldBeOpen { + // source: 'module_main_metaAnnotation_differentModules.kt' + public method (): void + public method method(): void +} + +@AllOpen +@kotlin.Metadata +public class TestAllOpen_ShouldBeOpen { + // source: 'module_main_metaAnnotation_differentModules.kt' + public method (): void +} + +@AnotherComponent +@kotlin.Metadata +public class TestAnotherComponent_ShouldBeOpen { + // source: 'module_main_metaAnnotation_differentModules.kt' + public method (): void +} + +@MyComponent +@kotlin.Metadata +public class TestMyComponent_ShouldBeOpen { + // source: 'module_main_metaAnnotation_differentModules.kt' + public method (): void +} + +@OtherComponent +@kotlin.Metadata +public class TestOtherComponent_ShouldBeOpen { + // source: 'module_main_metaAnnotation_differentModules.kt' + public method (): void +} + +@kotlin.Metadata +public final class TestWithoutAnnotations_ShouldBeFinal { + // source: 'module_main_metaAnnotation_differentModules.kt' + public method (): void +} diff --git a/plugins/allopen/testData/bytecodeListing/metaAnnotation_sameModule.kt b/plugins/allopen/testData/bytecodeListing/metaAnnotation_sameModule.kt new file mode 100644 index 00000000000..33961bc7150 --- /dev/null +++ b/plugins/allopen/testData/bytecodeListing/metaAnnotation_sameModule.kt @@ -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() {} +} diff --git a/plugins/allopen/testData/bytecodeListing/metaAnnotation.txt b/plugins/allopen/testData/bytecodeListing/metaAnnotation_sameModule.txt similarity index 72% rename from plugins/allopen/testData/bytecodeListing/metaAnnotation.txt rename to plugins/allopen/testData/bytecodeListing/metaAnnotation_sameModule.txt index 59fd54829e5..a48eb42ded8 100644 --- a/plugins/allopen/testData/bytecodeListing/metaAnnotation.txt +++ b/plugins/allopen/testData/bytecodeListing/metaAnnotation_sameModule.txt @@ -1,20 +1,20 @@ @java.lang.annotation.Retention(value=RUNTIME) @kotlin.Metadata public annotation class AllOpen { - // source: 'metaAnnotation.kt' + // source: 'metaAnnotation_sameModule.kt' } @OtherComponent @java.lang.annotation.Retention(value=RUNTIME) @kotlin.Metadata public annotation class AnotherComponent { - // source: 'metaAnnotation.kt' + // source: 'metaAnnotation_sameModule.kt' } @Documented @kotlin.Metadata public final class ClassWithDocumented { - // source: 'metaAnnotation.kt' + // source: 'metaAnnotation_sameModule.kt' public method (): void } @@ -22,40 +22,40 @@ public final class ClassWithDocumented { @java.lang.annotation.Retention(value=RUNTIME) @kotlin.Metadata public annotation class Documented { - // source: 'metaAnnotation.kt' + // source: 'metaAnnotation_sameModule.kt' } @AllOpen @java.lang.annotation.Retention(value=RUNTIME) @kotlin.Metadata public annotation class MyComponent { - // source: 'metaAnnotation.kt' + // source: 'metaAnnotation_sameModule.kt' } @MyComponent @kotlin.Metadata public abstract class MyComponentBase { - // source: 'metaAnnotation.kt' + // source: 'metaAnnotation_sameModule.kt' public method (): void } @kotlin.Metadata public final class MyComponentImpl2_ShouldBeFinal { - // source: 'metaAnnotation.kt' + // source: 'metaAnnotation_sameModule.kt' public method (): void public method method(): void } @kotlin.Metadata public class MyComponentImpl3_ShouldBeOpen { - // source: 'metaAnnotation.kt' + // source: 'metaAnnotation_sameModule.kt' public method (): void public final method method_ShouldBeFinal(): void } @kotlin.Metadata public class MyComponentImpl_ShouldBeOpen { - // source: 'metaAnnotation.kt' + // source: 'metaAnnotation_sameModule.kt' public method (): void public method method(): void } @@ -64,39 +64,39 @@ public class MyComponentImpl_ShouldBeOpen { @java.lang.annotation.Retention(value=RUNTIME) @kotlin.Metadata public annotation class OtherComponent { - // source: 'metaAnnotation.kt' + // source: 'metaAnnotation_sameModule.kt' } @AllOpen @kotlin.Metadata public class TestAllOpen_ShouldBeOpen { - // source: 'metaAnnotation.kt' + // source: 'metaAnnotation_sameModule.kt' public method (): void } @AnotherComponent @kotlin.Metadata public class TestAnotherComponent_ShouldBeOpen { - // source: 'metaAnnotation.kt' + // source: 'metaAnnotation_sameModule.kt' public method (): void } @MyComponent @kotlin.Metadata public class TestMyComponent_ShouldBeOpen { - // source: 'metaAnnotation.kt' + // source: 'metaAnnotation_sameModule.kt' public method (): void } @OtherComponent @kotlin.Metadata public class TestOtherComponent_ShouldBeOpen { - // source: 'metaAnnotation.kt' + // source: 'metaAnnotation_sameModule.kt' public method (): void } @kotlin.Metadata public final class TestWithoutAnnotations_ShouldBeFinal { - // source: 'metaAnnotation.kt' + // source: 'metaAnnotation_sameModule.kt' public method (): void } diff --git a/plugins/allopen/tests-gen/org/jetbrains/kotlin/allopen/BytecodeListingTestForAllOpenGenerated.java b/plugins/allopen/tests-gen/org/jetbrains/kotlin/allopen/BytecodeListingTestForAllOpenGenerated.java index decdd10c035..49c8b2bf092 100644 --- a/plugins/allopen/tests-gen/org/jetbrains/kotlin/allopen/BytecodeListingTestForAllOpenGenerated.java +++ b/plugins/allopen/tests-gen/org/jetbrains/kotlin/allopen/BytecodeListingTestForAllOpenGenerated.java @@ -56,9 +56,15 @@ public class BytecodeListingTestForAllOpenGenerated extends AbstractBytecodeList } @Test - @TestMetadata("metaAnnotation.kt") - public void testMetaAnnotation() throws Exception { - runTest("plugins/allopen/testData/bytecodeListing/metaAnnotation.kt"); + @TestMetadata("metaAnnotation_differentModules.kt") + public void testMetaAnnotation_differentModules() throws Exception { + 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 diff --git a/plugins/allopen/tests-gen/org/jetbrains/kotlin/allopen/FirBytecodeListingTestForAllOpenGenerated.java b/plugins/allopen/tests-gen/org/jetbrains/kotlin/allopen/FirBytecodeListingTestForAllOpenGenerated.java index ab07be1a632..030dfbc9d53 100644 --- a/plugins/allopen/tests-gen/org/jetbrains/kotlin/allopen/FirBytecodeListingTestForAllOpenGenerated.java +++ b/plugins/allopen/tests-gen/org/jetbrains/kotlin/allopen/FirBytecodeListingTestForAllOpenGenerated.java @@ -56,9 +56,15 @@ public class FirBytecodeListingTestForAllOpenGenerated extends AbstractFirByteco } @Test - @TestMetadata("metaAnnotation.kt") - public void testMetaAnnotation() throws Exception { - runTest("plugins/allopen/testData/bytecodeListing/metaAnnotation.kt"); + @TestMetadata("metaAnnotation_differentModules.kt") + public void testMetaAnnotation_differentModules() throws Exception { + 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 diff --git a/plugins/allopen/tests-gen/org/jetbrains/kotlin/allopen/IrBytecodeListingTestForAllOpenGenerated.java b/plugins/allopen/tests-gen/org/jetbrains/kotlin/allopen/IrBytecodeListingTestForAllOpenGenerated.java index 084f43ee8d7..f5a56b8f187 100644 --- a/plugins/allopen/tests-gen/org/jetbrains/kotlin/allopen/IrBytecodeListingTestForAllOpenGenerated.java +++ b/plugins/allopen/tests-gen/org/jetbrains/kotlin/allopen/IrBytecodeListingTestForAllOpenGenerated.java @@ -56,9 +56,15 @@ public class IrBytecodeListingTestForAllOpenGenerated extends AbstractIrBytecode } @Test - @TestMetadata("metaAnnotation.kt") - public void testMetaAnnotation() throws Exception { - runTest("plugins/allopen/testData/bytecodeListing/metaAnnotation.kt"); + @TestMetadata("metaAnnotation_differentModules.kt") + public void testMetaAnnotation_differentModules() throws Exception { + 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 diff --git a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/AllOpenStatusTransformer.kt b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/AllOpenStatusTransformer.kt index 846e2d8beae..a2fd9e4e809 100644 --- a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/AllOpenStatusTransformer.kt +++ b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/AllOpenStatusTransformer.kt @@ -12,9 +12,6 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar import org.jetbrains.kotlin.fir.extensions.FirStatusTransformerExtension 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.transform import org.jetbrains.kotlin.name.FqName @@ -22,7 +19,9 @@ import org.jetbrains.kotlin.name.FqName class AllOpenStatusTransformer(session: FirSession) : FirStatusTransformerExtension(session) { companion object { 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 { diff --git a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/AllPublicVisibilityTransformer.kt b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/AllPublicVisibilityTransformer.kt index 9366805b95d..06bfb8c2c7d 100644 --- a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/AllPublicVisibilityTransformer.kt +++ b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/AllPublicVisibilityTransformer.kt @@ -16,7 +16,6 @@ import org.jetbrains.kotlin.fir.expressions.arguments import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar import org.jetbrains.kotlin.fir.extensions.FirStatusTransformerExtension 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.transform import org.jetbrains.kotlin.fir.references.FirNamedReference @@ -37,7 +36,7 @@ class AllPublicVisibilityTransformer(session: FirSession) : FirStatusTransformer private val PrivateName = Name.identifier("Private") 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 { diff --git a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/SomeAdditionalSupertypeGenerator.kt b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/SomeAdditionalSupertypeGenerator.kt index 532c600d64a..d7111d1443f 100644 --- a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/SomeAdditionalSupertypeGenerator.kt +++ b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/SomeAdditionalSupertypeGenerator.kt @@ -10,7 +10,6 @@ import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar import org.jetbrains.kotlin.fir.extensions.FirSupertypeGenerationExtension 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.types.FirResolvedTypeRef import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef @@ -26,7 +25,7 @@ import org.jetbrains.kotlin.name.Name class SomeAdditionalSupertypeGenerator(session: FirSession) : FirSupertypeGenerationExtension(session) { companion object { private val myInterfaceClassId = ClassId(FqName("foo"), Name.identifier("MyInterface")) - private val PREDICATE: DeclarationPredicate = annotated("MyInterfaceSupertype".fqn()) + private val PREDICATE = DeclarationPredicate.create { annotated("MyInterfaceSupertype".fqn()) } } diff --git a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/SupertypeWithArgumentGenerator.kt b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/SupertypeWithArgumentGenerator.kt index d98710f8b99..3e3b78c3d14 100644 --- a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/SupertypeWithArgumentGenerator.kt +++ b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/SupertypeWithArgumentGenerator.kt @@ -13,13 +13,11 @@ import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar import org.jetbrains.kotlin.fir.extensions.FirSupertypeGenerationExtension import org.jetbrains.kotlin.fir.extensions.buildUserTypeFromQualifierParts 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.references.impl.FirSimpleNamedReference import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef 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.name.ClassId import org.jetbrains.kotlin.name.FqName @@ -32,7 +30,7 @@ class SupertypeWithArgumentGenerator(session: FirSession) : FirSupertypeGenerati companion object { private val supertypeClassId = ClassId(FqName("foo"), Name.identifier("InterfaceWithArgument")) private val annotationClassId = ClassId.topLevel("SupertypeWithTypeArgument".fqn()) - private val PREDICATE: DeclarationPredicate = annotated(annotationClassId.asSingleFqName()) + private val PREDICATE = DeclarationPredicate.create { annotated(annotationClassId.asSingleFqName()) } } diff --git a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/generators/AdditionalMembersGenerator.kt b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/generators/AdditionalMembersGenerator.kt index c888850304a..a309b3d6b1a 100644 --- a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/generators/AdditionalMembersGenerator.kt +++ b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/generators/AdditionalMembersGenerator.kt @@ -5,12 +5,12 @@ package org.jetbrains.kotlin.fir.plugin.generators +import org.jetbrains.kotlin.GeneratedDeclarationKey import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.EffectiveVisibility import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.GeneratedDeclarationKey import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.builder.buildRegularClass 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.FirDeclarationPredicateRegistrar import org.jetbrains.kotlin.fir.extensions.MemberGenerationContext -import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate -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.moduleData 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 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 diff --git a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/generators/CompanionGenerator.kt b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/generators/CompanionGenerator.kt index 0c4a20e73ba..ab455a2da59 100644 --- a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/generators/CompanionGenerator.kt +++ b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/generators/CompanionGenerator.kt @@ -20,7 +20,7 @@ import org.jetbrains.kotlin.fir.declarations.origin import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar 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.moduleData import org.jetbrains.kotlin.fir.plugin.fqn @@ -38,7 +38,7 @@ import org.jetbrains.kotlin.name.SpecialNames */ class CompanionGenerator(session: FirSession) : FirDeclarationGenerationExtension(session) { companion object { - private val PREDICATE = annotated("CompanionWithFoo".fqn()) + private val PREDICATE = LookupPredicate.create { annotated("CompanionWithFoo".fqn()) } private val FOO_NAME = Name.identifier("foo") } diff --git a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/generators/ExternalClassGenerator.kt b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/generators/ExternalClassGenerator.kt index 7fee784900b..ffb63121e51 100644 --- a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/generators/ExternalClassGenerator.kt +++ b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/generators/ExternalClassGenerator.kt @@ -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.FirDeclarationPredicateRegistrar import org.jetbrains.kotlin.fir.extensions.MemberGenerationContext -import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate -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.moduleData 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 MATERIALIZE_NAME = Name.identifier("materialize") - private val PREDICATE: DeclarationPredicate = annotated("ExternalClassWithNested".fqn()) + private val PREDICATE = LookupPredicate.create { annotated("ExternalClassWithNested".fqn()) } } object Key : GeneratedDeclarationKey() { diff --git a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/generators/MembersOfSerializerGenerator.kt b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/generators/MembersOfSerializerGenerator.kt index e744cd625c4..8a7912d090e 100644 --- a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/generators/MembersOfSerializerGenerator.kt +++ b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/generators/MembersOfSerializerGenerator.kt @@ -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.FirDeclarationPredicateRegistrar 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.moduleData import org.jetbrains.kotlin.fir.plugin.fqn @@ -37,8 +37,8 @@ import org.jetbrains.kotlin.name.Name */ class MembersOfSerializerGenerator(session: FirSession) : FirDeclarationGenerationExtension(session) { companion object { - private val SERIALIZABLE_PREDICATE = annotated("MySerializable".fqn()) - private val CORE_SERIALIZER_PREDICATE = annotated("CoreSerializer".fqn()) + private val SERIALIZABLE_PREDICATE = LookupPredicate.create { annotated("MySerializable".fqn()) } + private val CORE_SERIALIZER_PREDICATE = LookupPredicate.create { annotated("CoreSerializer".fqn()) } private val X_NAME = Name.identifier("x") } diff --git a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/generators/TopLevelDeclarationsGenerator.kt b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/generators/TopLevelDeclarationsGenerator.kt index faeaf77fc98..361fe5700de 100644 --- a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/generators/TopLevelDeclarationsGenerator.kt +++ b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/generators/TopLevelDeclarationsGenerator.kt @@ -18,8 +18,7 @@ import org.jetbrains.kotlin.fir.declarations.origin import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar import org.jetbrains.kotlin.fir.extensions.MemberGenerationContext -import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate -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.moduleData import org.jetbrains.kotlin.fir.plugin.fqn @@ -35,7 +34,7 @@ import org.jetbrains.kotlin.name.Name */ class TopLevelDeclarationsGenerator(session: FirSession) : FirDeclarationGenerationExtension(session) { companion object { - private val PREDICATE: DeclarationPredicate = annotated("DummyFunction".fqn()) + private val PREDICATE = LookupPredicate.create { annotated("DummyFunction".fqn()) } } private val predicateBasedProvider = session.predicateBasedProvider diff --git a/plugins/fir-plugin-prototype/testData/diagnostics/status/metaAnnotation.fir.txt b/plugins/fir-plugin-prototype/testData/diagnostics/status/metaAnnotation.fir.txt index 311a322feb3..1e9ffc446dd 100644 --- a/plugins/fir-plugin-prototype/testData/diagnostics/status/metaAnnotation.fir.txt +++ b/plugins/fir-plugin-prototype/testData/diagnostics/status/metaAnnotation.fir.txt @@ -4,7 +4,7 @@ FILE: first.kt super() } - public open fun foo(): R|kotlin/Unit| { + public final fun foo(): R|kotlin/Unit| { } } diff --git a/plugins/fir-plugin-prototype/testData/diagnostics/status/metaAnnotation.kt b/plugins/fir-plugin-prototype/testData/diagnostics/status/metaAnnotation.kt index 280bcecc32a..dc1c7df4046 100644 --- a/plugins/fir-plugin-prototype/testData/diagnostics/status/metaAnnotation.kt +++ b/plugins/fir-plugin-prototype/testData/diagnostics/status/metaAnnotation.kt @@ -9,7 +9,7 @@ class A { @Open class B : A() { - override fun foo() { + override fun foo() { } } diff --git a/plugins/kotlinx-serialization/kotlinx-serialization.k2/src/org/jetbrains/kotlinx/serialization/compiler/fir/FirSerializationPredicates.kt b/plugins/kotlinx-serialization/kotlinx-serialization.k2/src/org/jetbrains/kotlinx/serialization/compiler/fir/FirSerializationPredicates.kt index ca6c87ff8ac..12472398125 100644 --- a/plugins/kotlinx-serialization/kotlinx-serialization.k2/src/org/jetbrains/kotlinx/serialization/compiler/fir/FirSerializationPredicates.kt +++ b/plugins/kotlinx-serialization/kotlinx-serialization.k2/src/org/jetbrains/kotlinx/serialization/compiler/fir/FirSerializationPredicates.kt @@ -9,11 +9,13 @@ import org.jetbrains.kotlin.fir.extensions.predicate.* import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationAnnotations object FirSerializationPredicates { - internal val serializerFor: DeclarationPredicate = - AnnotatedWith(setOf(SerializationAnnotations.serializerAnnotationFqName)) // @Serializer(for=...) - internal val generatedSerializer: DeclarationPredicate = - ancestorAnnotated(SerializationAnnotations.serializableAnnotationFqName) // @Serializable X.$serializer - internal val hasMetaAnnotation = metaAnnotated(SerializationAnnotations.metaSerializableAnnotationFqName) - internal val annotatedWithSerializableOrMeta = - AnnotatedWith(setOf(SerializationAnnotations.serializableAnnotationFqName)) or metaAnnotated(SerializationAnnotations.metaSerializableAnnotationFqName) + internal val serializerFor = DeclarationPredicate.create { + annotated(setOf(SerializationAnnotations.serializerAnnotationFqName)) // @Serializer(for=...) + } + internal val hasMetaAnnotation = DeclarationPredicate.create { + metaAnnotated(SerializationAnnotations.metaSerializableAnnotationFqName) + } + internal val annotatedWithSerializableOrMeta = DeclarationPredicate.create { + annotated(setOf(SerializationAnnotations.serializableAnnotationFqName)) or metaAnnotated(SerializationAnnotations.metaSerializableAnnotationFqName) + } } diff --git a/plugins/kotlinx-serialization/kotlinx-serialization.k2/src/org/jetbrains/kotlinx/serialization/compiler/fir/SerializationFirResolveExtension.kt b/plugins/kotlinx-serialization/kotlinx-serialization.k2/src/org/jetbrains/kotlinx/serialization/compiler/fir/SerializationFirResolveExtension.kt index 76650de1fef..464f5930b9b 100644 --- a/plugins/kotlinx-serialization/kotlinx-serialization.k2/src/org/jetbrains/kotlinx/serialization/compiler/fir/SerializationFirResolveExtension.kt +++ b/plugins/kotlinx-serialization/kotlinx-serialization.k2/src/org/jetbrains/kotlinx/serialization/compiler/fir/SerializationFirResolveExtension.kt @@ -250,12 +250,6 @@ class SerializationFirResolveExtension(session: FirSession) : FirDeclarationGene 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() - } - override fun generateConstructors(context: MemberGenerationContext): List { val owner = context.owner val defaultObjectConstructor = buildPrimaryConstructor( @@ -291,10 +285,15 @@ class SerializationFirResolveExtension(session: FirSession) : FirDeclarationGene return listOf(defaultObjectConstructor.symbol) } - fun addSerializerImplClass( - classId: ClassId - ): FirClassLikeSymbol<*>? { - val owner = matchedClasses.firstOrNull { it.classId == classId.outerClassId } ?: return null + private fun getClassWithAnnotatedWithSerializableOrMeta(classId: ClassId?): FirRegularClassSymbol? { + if (classId == null) return null + return (session.symbolProvider.getClassLikeSymbolByClassId(classId) as? FirRegularClassSymbol)?.takeIf { + session.predicateBasedProvider.matches(FirSerializationPredicates.annotatedWithSerializableOrMeta, it) + } + } + + fun addSerializerImplClass(classId: ClassId): FirClassLikeSymbol<*>? { + val owner = getClassWithAnnotatedWithSerializableOrMeta(classId.outerClassId) ?: return null val hasTypeParams = owner.typeParameterSymbols.isNotEmpty() val serializerKind = if (hasTypeParams) ClassKind.CLASS else ClassKind.OBJECT val serializerFirClass = buildRegularClass { @@ -332,7 +331,7 @@ class SerializationFirResolveExtension(session: FirSession) : FirDeclarationGene fun generateCompanionDeclaration(classId: ClassId): FirClassLikeSymbol<*>? { 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 val regularClass = buildRegularClass { moduleData = session.moduleData diff --git a/plugins/noarg/noarg.k2/src/org/jetbrains/kotlin/noarg/fir/NoArgAnnotationNameProvider.kt b/plugins/noarg/noarg.k2/src/org/jetbrains/kotlin/noarg/fir/NoArgAnnotationNameProvider.kt index ee40afd1e08..dc8c3375115 100644 --- a/plugins/noarg/noarg.k2/src/org/jetbrains/kotlin/noarg/fir/NoArgAnnotationNameProvider.kt +++ b/plugins/noarg/noarg.k2/src/org/jetbrains/kotlin/noarg/fir/NoArgAnnotationNameProvider.kt @@ -6,9 +6,7 @@ package org.jetbrains.kotlin.noarg.fir import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.extensions.predicate.annotated -import org.jetbrains.kotlin.fir.extensions.predicate.metaAnnotated -import org.jetbrains.kotlin.fir.extensions.predicate.or +import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate import org.jetbrains.kotlin.fir.extensions.utils.AbstractSimpleClassPredicateMatchingService 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) } annotated(annotationFqNames) or metaAnnotated(annotationFqNames) } diff --git a/plugins/noarg/testData/diagnostics/innerClass.fir.kt b/plugins/noarg/testData/diagnostics/innerClass.fir.kt index 3f0c80e2ed6..ad5bc3248d4 100644 --- a/plugins/noarg/testData/diagnostics/innerClass.fir.kt +++ b/plugins/noarg/testData/diagnostics/innerClass.fir.kt @@ -7,8 +7,8 @@ class Outer { fun local() { @NoArg - class Local(val l: Any) { + class Local(val l: Any) { @NoArg - inner class InnerLocal(val x: Any) + inner class InnerLocal(val x: Any) } } diff --git a/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/FirParcelizeDeclarationGenerator.kt b/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/FirParcelizeDeclarationGenerator.kt index 35054fd7d1b..ce76a939f92 100644 --- a/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/FirParcelizeDeclarationGenerator.kt +++ b/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/FirParcelizeDeclarationGenerator.kt @@ -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.FirDeclarationPredicateRegistrar 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.moduleData import org.jetbrains.kotlin.fir.resolve.defaultType @@ -46,7 +46,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.runIf class FirParcelizeDeclarationGenerator(session: FirSession) : FirDeclarationGenerationExtension(session) { 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) }