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