diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirExtensionPointService.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirExtensionPointService.kt index 5eb027694f8..50e823e7a24 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirExtensionPointService.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirExtensionPointService.kt @@ -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) { + 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 - 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 + map.put(fqName, extension) + } } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirPluginAnnotationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirPluginAnnotationsResolveTransformer.kt index a3dfa57bcd9..7240316f68c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirPluginAnnotationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirPluginAnnotationsResolveTransformer.kt @@ -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, metaAnnotations: Set - ): Set { + ): Multimap { val importTransformer = FirPartialImportResolveTransformer(annotations) this.transform(importTransformer, null) val annotationTransformer = FirAnnotationResolveTransformer(metaAnnotations, session, scopeSession) - val newAnnotations = mutableSetOf() - this.transform>(annotationTransformer, newAnnotations) + val newAnnotations = LinkedHashMultimap.create() + this.transform>(annotationTransformer, newAnnotations) return newAnnotations } } @@ -68,25 +70,29 @@ private class FirAnnotationResolveTransformer( private val metaAnnotations: Set, session: FirSession, scopeSession: ScopeSession -) : FirAbstractAnnotationResolveTransformer>(session, scopeSession) { - private val typeResolverTransformer: FirSpecificTypeResolverTransformer = FirSpecificTypeResolverTransformer(towerScope, session) +) : FirAbstractAnnotationResolveTransformer>(session, scopeSession) { + private val typeResolverTransformer: FirSpecificTypeResolverTransformer = FirSpecificTypeResolverTransformer( + towerScope, + session, + errorTypeAsResolved = false + ) override fun transformAnnotationCall( annotationCall: FirAnnotationCall, - data: MutableSet + data: Multimap ): CompositeTransformResult { return annotationCall.transformAnnotationTypeRef(typeResolverTransformer, null).compose() } override fun transformRegularClass( regularClass: FirRegularClass, - data: MutableSet + data: Multimap ): CompositeTransformResult { 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) } } }