[FIR] Fix resolution of plugin annotations annotated with meta annotations

There was a problem, that after founding of new annotation with meta
  annotation we did not come back to previous files, which may contain
  declarations with this new annotation
This commit is contained in:
Dmitriy Novozhilov
2022-05-24 09:18:05 +03:00
committed by teamcity
parent 055865a2a1
commit f34061acc1
4 changed files with 52 additions and 20 deletions
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.ResolveTreeB
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.ensurePhase
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.transformers.plugin.FirCompilerRequiredAnnotationsResolveTransformer
@@ -25,7 +24,7 @@ internal class LLFirDesignatedAnnotationsResolveTransformed(
if (!designationIterator.hasNext()) {
val declaration = designation.declaration
if (declaration is FirRegularClass || declaration is FirTypeAlias) {
declaration.transform<FirDeclaration, ResolutionMode>(this, ResolutionMode.ContextIndependent)
declaration.transform<FirDeclaration, Mode>(this, Mode.RegularAnnotations)
}
return
}
@@ -71,4 +70,4 @@ internal class LLFirDesignatedAnnotationsResolveTransformed(
}
}
}
}
@@ -24,9 +24,11 @@ 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
import org.jetbrains.kotlin.fir.visitors.transformSingle
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
@@ -37,8 +39,20 @@ import org.jetbrains.kotlin.name.StandardClassIds.Annotations.WasExperimental
class FirCompilerRequiredAnnotationsResolveProcessor(
session: FirSession,
scopeSession: ScopeSession
) : FirTransformerBasedResolveProcessor(session, scopeSession) {
override val transformer = FirCompilerRequiredAnnotationsResolveTransformer(session, scopeSession)
) : FirGlobalResolveProcessor(session, scopeSession) {
override fun process(files: Collection<FirFile>) {
val transformer = FirCompilerRequiredAnnotationsResolveTransformer(session, scopeSession)
val registeredPluginAnnotations = session.registeredPluginAnnotations
if (!registeredPluginAnnotations.hasRegisteredAnnotations) {
files.forEach { it.transformSingle(transformer, Mode.RegularAnnotations) }
return
}
if (registeredPluginAnnotations.metaAnnotations.isNotEmpty()) {
files.forEach { it.transformSingle(transformer, Mode.MetaAnnotations) }
}
files.forEach { it.transformSingle(transformer, Mode.RegularAnnotations) }
}
@OptIn(FirSymbolProviderInternals::class)
override fun beforePhase() {
@@ -54,42 +68,56 @@ class FirCompilerRequiredAnnotationsResolveProcessor(
open class FirCompilerRequiredAnnotationsResolveTransformer(
final override val session: FirSession,
scopeSession: ScopeSession
) : FirAbstractPhaseTransformer<Any?>(COMPILER_REQUIRED_ANNOTATIONS) {
) : FirAbstractPhaseTransformer<Mode>(COMPILER_REQUIRED_ANNOTATIONS) {
enum class Mode {
MetaAnnotations,
RegularAnnotations
}
private val annotationTransformer = FirAnnotationResolveTransformer(session, scopeSession)
private val importTransformer = FirPartialImportResolveTransformer(session)
val extensionService = session.extensionService
override fun <E : FirElement> transformElement(element: E, data: Any?): E {
override fun <E : FirElement> transformElement(element: E, data: Mode): E {
throw IllegalStateException("Should not be here")
}
override fun transformFile(file: FirFile, data: Any?): FirFile {
override fun transformFile(file: FirFile, data: Mode): FirFile {
checkSessionConsistency(file)
val registeredPluginAnnotations = session.registeredPluginAnnotations
val newAnnotations = file.resolveAnnotations(registeredPluginAnnotations.annotations, registeredPluginAnnotations.metaAnnotations)
val regularAnnotations: Set<AnnotationFqn>
val metaAnnotations: Set<AnnotationFqn>
when (data) {
Mode.MetaAnnotations -> {
regularAnnotations = emptySet()
metaAnnotations = registeredPluginAnnotations.metaAnnotations
}
Mode.RegularAnnotations -> {
regularAnnotations = registeredPluginAnnotations.annotations
metaAnnotations = emptySet()
}
}
val newAnnotations = file.resolveAnnotations(regularAnnotations, metaAnnotations)
if (!newAnnotations.isEmpty) {
for (metaAnnotation in newAnnotations.keySet()) {
registeredPluginAnnotations.registerUserDefinedAnnotation(metaAnnotation, newAnnotations[metaAnnotation])
}
val newAnnotationsFqns = newAnnotations.values().mapTo(mutableSetOf()) { it.symbol.classId.asSingleFqName() }
file.resolveAnnotations(newAnnotationsFqns, emptySet())
}
return file
}
fun <T> withFile(file: FirFile, f: () -> T): T = annotationTransformer.withFile(file, f)
fun <T> withFileAndScopes(file: FirFile, f: () -> T): T {
annotationTransformer.withFile(file) {
return annotationTransformer.withFileScopes(file, f)
}
}
override fun transformRegularClass(regularClass: FirRegularClass, data: Any?): FirStatement {
override fun transformRegularClass(regularClass: FirRegularClass, data: Mode): FirStatement {
return annotationTransformer.transformRegularClass(regularClass, LinkedHashMultimap.create())
}
override fun transformTypeAlias(typeAlias: FirTypeAlias, data: Any?): FirStatement {
override fun transformTypeAlias(typeAlias: FirTypeAlias, data: Mode): FirStatement {
return annotationTransformer.transformTypeAlias(typeAlias, LinkedHashMultimap.create())
}
@@ -97,10 +125,11 @@ open class FirCompilerRequiredAnnotationsResolveTransformer(
annotations: Set<AnnotationFqn>,
metaAnnotations: Set<AnnotationFqn>
): Multimap<AnnotationFqn, FirRegularClass> {
importTransformer.acceptableFqNames = annotations
val acceptableNames = annotations + metaAnnotations
importTransformer.acceptableFqNames = acceptableNames
this.transformImports(importTransformer, null)
annotationTransformer.acceptableFqNames = annotations
annotationTransformer.acceptableFqNames = acceptableNames
annotationTransformer.metaAnnotations = metaAnnotations
val newAnnotations = LinkedHashMultimap.create<AnnotationFqn, FirRegularClass>()
this.transform<FirFile, Multimap<AnnotationFqn, FirRegularClass>>(annotationTransformer, newAnnotations)
@@ -1,4 +1,4 @@
FILE: metaAnnotation.kt
FILE: first.kt
@R|Open|() public open class A : R|kotlin/Any| {
public constructor(): R|A| {
super<R|kotlin/Any|>()
@@ -17,6 +17,7 @@ FILE: metaAnnotation.kt
}
}
FILE: second.kt
@R|org/jetbrains/kotlin/fir/plugin/AllOpen|() public open annotation class Open : R|kotlin/Annotation| {
public constructor(): R|Open| {
super<R|kotlin/Any|>()
@@ -1,4 +1,4 @@
import org.jetbrains.kotlin.fir.plugin.AllOpen
// FILE: first.kt
@Open
class A {
@@ -14,5 +14,8 @@ class B : A() {
}
}
// FILE: second.kt
import org.jetbrains.kotlin.fir.plugin.AllOpen
@AllOpen
annotation class Open
annotation class Open