diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirExtensionPoint.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirExtensionPoint.kt index 7cc652976f8..20441288af4 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirExtensionPoint.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirExtensionPoint.kt @@ -15,8 +15,9 @@ typealias AnnotationFqn = FqName abstract class FirExtensionPoint(val session: FirSession) { abstract val name: FirExtensionPointName - abstract val annotations: Set - abstract val metaAnnotations: Set + abstract val directlyApplicableAnnotations: Set + abstract val childrenApplicableAnnotations: Set + abstract val metaAnnotations: Map abstract val mode: Mode @@ -28,9 +29,14 @@ abstract class FirExtensionPoint(val session: FirSession) { enum class Mode { ANNOTATED_ELEMENT, - ALL_IN_ANNOTATED_ELEMENT, ALL } + + enum class MetaAnnotationMode(val directed: Boolean, val children: Boolean) { + ANNOTATED_DECLARATION(directed = true, children = false), + CHILDREN_DECLARATION(directed = false, children = true), + ANNOTATED_AND_CHILDREN(directed = true, children = true) + } } data class FirExtensionPointName(val name: Name) { 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 c699eda165b..2c58e7e7869 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 @@ -59,19 +59,18 @@ class FirExtensionPointService( val extensionsWithAnnotatedMode = createMultimap() val extensionsWithAllInAnnotatedMode = createMultimap() for (extension in extensions) { - _metaAnnotations += extension.metaAnnotations - for (metaAnnotation in extension.metaAnnotations) { + _metaAnnotations += extension.metaAnnotations.keys + for (metaAnnotation in extension.metaAnnotations.keys) { extensionsWithMetaAnnotations.put(metaAnnotation, extension) } - _annotations += extension.annotations + _annotations += extension.directlyApplicableAnnotations + _annotations += extension.childrenApplicableAnnotations when (extension.mode) { FirExtensionPoint.Mode.ANNOTATED_ELEMENT -> { - for (annotation in extension.annotations) { + for (annotation in extension.directlyApplicableAnnotations) { extensionsWithAnnotatedMode.put(annotation, extension) } - } - FirExtensionPoint.Mode.ALL_IN_ANNOTATED_ELEMENT -> { - for (annotation in extension.annotations) { + for (annotation in extension.childrenApplicableAnnotations) { extensionsWithAllInAnnotatedMode.put(annotation, extension) } } @@ -98,13 +97,17 @@ class FirExtensionPointService( for (extension in extensions) { val registeredExtensions = this[extension.extensionType] - @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) + val metaAnnotationMode = extension.metaAnnotations.getValue(metaAnnotation) + + if (metaAnnotationMode.directed) { + @Suppress("UNCHECKED_CAST") + (registeredExtensions.extensionsWithAnnotatedMode as Multimap).put(fqName, extension) + } + + if (metaAnnotationMode.children) { + @Suppress("UNCHECKED_CAST") + (registeredExtensions.extensionsWithAllInAnnotatedMode as Multimap).put(fqName, extension) + } } } }