[FIR] Fix collecting annotations with meta annotations
This commit is contained in:
+17
-15
@@ -88,22 +88,24 @@ class FirExtensionPointService(
|
||||
)
|
||||
}
|
||||
|
||||
fun registerUserDefinedAnnotation(annotation: FirRegularClass) {
|
||||
require(annotation.classKind == ClassKind.ANNOTATION_CLASS)
|
||||
val fqName = annotation.symbol.classId.asSingleFqName()
|
||||
_annotations += fqName
|
||||
val extensions = extensionsWithMetaAnnotations[fqName]
|
||||
if (extensions.isEmpty()) return
|
||||
for (extension in extensions) {
|
||||
val registeredExtensions = this[extension::class]
|
||||
fun registerUserDefinedAnnotation(metaAnnotation: AnnotationFqn, annotations: Collection<FirRegularClass>) {
|
||||
for (annotation in annotations) {
|
||||
require(annotation.classKind == ClassKind.ANNOTATION_CLASS)
|
||||
val fqName = annotation.symbol.classId.asSingleFqName()
|
||||
_annotations += fqName
|
||||
val extensions = extensionsWithMetaAnnotations[metaAnnotation]
|
||||
if (extensions.isEmpty()) return
|
||||
for (extension in extensions) {
|
||||
val registeredExtensions = this[extension::class]
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val map = when (extension.mode) {
|
||||
FirExtensionPoint.Mode.ANNOTATED_ELEMENT -> registeredExtensions.extensionsWithAnnotatedMode
|
||||
FirExtensionPoint.Mode.ALL_IN_ANNOTATED_ELEMENT -> registeredExtensions.extensionsWithAllInAnnotatedMode
|
||||
FirExtensionPoint.Mode.ALL -> throw IllegalStateException("Extension with mode ALL can't be subscribed to meta annotation")
|
||||
} as Multimap<AnnotationFqn, FirExtensionPoint>
|
||||
map.put(fqName, extension)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val map = when (extension.mode) {
|
||||
FirExtensionPoint.Mode.ANNOTATED_ELEMENT -> registeredExtensions.extensionsWithAnnotatedMode
|
||||
FirExtensionPoint.Mode.ALL_IN_ANNOTATED_ELEMENT -> registeredExtensions.extensionsWithAllInAnnotatedMode
|
||||
FirExtensionPoint.Mode.ALL -> throw IllegalStateException("Extension with mode ALL can't be subscribed to meta annotation")
|
||||
} as Multimap<AnnotationFqn, FirExtensionPoint>
|
||||
map.put(fqName, extension)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+19
-13
@@ -5,6 +5,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.resolve.transformers.plugin
|
||||
|
||||
import com.google.common.collect.LinkedHashMultimap
|
||||
import com.google.common.collect.Multimap
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
@@ -33,11 +35,11 @@ class FirPluginAnnotationsResolveTransformer(private val scopeSession: ScopeSess
|
||||
if (!extensionPointService.hasExtensions) return file.compose()
|
||||
file.replaceResolvePhase(FirResolvePhase.ANNOTATIONS_FOR_PLUGINS)
|
||||
val newAnnotations = file.resolveAnnotations(extensionPointService.annotations, extensionPointService.metaAnnotations)
|
||||
if (newAnnotations.isNotEmpty()) {
|
||||
for (annotationClass in newAnnotations) {
|
||||
extensionPointService.registerUserDefinedAnnotation(annotationClass)
|
||||
if (!newAnnotations.isEmpty) {
|
||||
for (metaAnnotation in newAnnotations.keySet()) {
|
||||
extensionPointService.registerUserDefinedAnnotation(metaAnnotation, newAnnotations[metaAnnotation])
|
||||
}
|
||||
val newAnnotationsFqns = newAnnotations.mapTo(mutableSetOf()) { it.symbol.classId.asSingleFqName() }
|
||||
val newAnnotationsFqns = newAnnotations.values().mapTo(mutableSetOf()) { it.symbol.classId.asSingleFqName() }
|
||||
file.resolveAnnotations(newAnnotationsFqns, emptySet())
|
||||
}
|
||||
return file.compose()
|
||||
@@ -46,13 +48,13 @@ class FirPluginAnnotationsResolveTransformer(private val scopeSession: ScopeSess
|
||||
private fun FirFile.resolveAnnotations(
|
||||
annotations: Set<AnnotationFqn>,
|
||||
metaAnnotations: Set<AnnotationFqn>
|
||||
): Set<FirRegularClass> {
|
||||
): Multimap<AnnotationFqn, FirRegularClass> {
|
||||
val importTransformer = FirPartialImportResolveTransformer(annotations)
|
||||
this.transform<FirFile, Nothing?>(importTransformer, null)
|
||||
|
||||
val annotationTransformer = FirAnnotationResolveTransformer(metaAnnotations, session, scopeSession)
|
||||
val newAnnotations = mutableSetOf<FirRegularClass>()
|
||||
this.transform<FirFile, MutableSet<FirRegularClass>>(annotationTransformer, newAnnotations)
|
||||
val newAnnotations = LinkedHashMultimap.create<AnnotationFqn, FirRegularClass>()
|
||||
this.transform<FirFile, Multimap<AnnotationFqn, FirRegularClass>>(annotationTransformer, newAnnotations)
|
||||
return newAnnotations
|
||||
}
|
||||
}
|
||||
@@ -68,25 +70,29 @@ private class FirAnnotationResolveTransformer(
|
||||
private val metaAnnotations: Set<AnnotationFqn>,
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession
|
||||
) : FirAbstractAnnotationResolveTransformer<MutableSet<FirRegularClass>>(session, scopeSession) {
|
||||
private val typeResolverTransformer: FirSpecificTypeResolverTransformer = FirSpecificTypeResolverTransformer(towerScope, session)
|
||||
) : FirAbstractAnnotationResolveTransformer<Multimap<AnnotationFqn, FirRegularClass>>(session, scopeSession) {
|
||||
private val typeResolverTransformer: FirSpecificTypeResolverTransformer = FirSpecificTypeResolverTransformer(
|
||||
towerScope,
|
||||
session,
|
||||
errorTypeAsResolved = false
|
||||
)
|
||||
|
||||
override fun transformAnnotationCall(
|
||||
annotationCall: FirAnnotationCall,
|
||||
data: MutableSet<FirRegularClass>
|
||||
data: Multimap<AnnotationFqn, FirRegularClass>
|
||||
): CompositeTransformResult<FirStatement> {
|
||||
return annotationCall.transformAnnotationTypeRef(typeResolverTransformer, null).compose()
|
||||
}
|
||||
|
||||
override fun transformRegularClass(
|
||||
regularClass: FirRegularClass,
|
||||
data: MutableSet<FirRegularClass>
|
||||
data: Multimap<AnnotationFqn, FirRegularClass>
|
||||
): CompositeTransformResult<FirStatement> {
|
||||
return super.transformRegularClass(regularClass, data).also {
|
||||
if (regularClass.classKind == ClassKind.ANNOTATION_CLASS && metaAnnotations.isNotEmpty()) {
|
||||
val annotations = regularClass.annotations.mapNotNull { it.fqName(session) }
|
||||
if (annotations.any { it in metaAnnotations }) {
|
||||
data += regularClass
|
||||
for (annotation in annotations.filter { it in metaAnnotations }) {
|
||||
data.put(annotation, regularClass)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user