[FIR] Split plugin annotations for two groups. Introduce modes for meta annotations

This commit is contained in:
Dmitriy Novozhilov
2020-05-07 10:39:37 +03:00
parent 4022a57a4b
commit fac57344a3
2 changed files with 26 additions and 17 deletions
@@ -15,8 +15,9 @@ typealias AnnotationFqn = FqName
abstract class FirExtensionPoint(val session: FirSession) { abstract class FirExtensionPoint(val session: FirSession) {
abstract val name: FirExtensionPointName abstract val name: FirExtensionPointName
abstract val annotations: Set<AnnotationFqn> abstract val directlyApplicableAnnotations: Set<AnnotationFqn>
abstract val metaAnnotations: Set<AnnotationFqn> abstract val childrenApplicableAnnotations: Set<AnnotationFqn>
abstract val metaAnnotations: Map<AnnotationFqn, MetaAnnotationMode>
abstract val mode: Mode abstract val mode: Mode
@@ -28,9 +29,14 @@ abstract class FirExtensionPoint(val session: FirSession) {
enum class Mode { enum class Mode {
ANNOTATED_ELEMENT, ANNOTATED_ELEMENT,
ALL_IN_ANNOTATED_ELEMENT,
ALL 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) { data class FirExtensionPointName(val name: Name) {
@@ -59,19 +59,18 @@ class FirExtensionPointService(
val extensionsWithAnnotatedMode = createMultimap<AnnotationFqn, P>() val extensionsWithAnnotatedMode = createMultimap<AnnotationFqn, P>()
val extensionsWithAllInAnnotatedMode = createMultimap<AnnotationFqn, P>() val extensionsWithAllInAnnotatedMode = createMultimap<AnnotationFqn, P>()
for (extension in extensions) { for (extension in extensions) {
_metaAnnotations += extension.metaAnnotations _metaAnnotations += extension.metaAnnotations.keys
for (metaAnnotation in extension.metaAnnotations) { for (metaAnnotation in extension.metaAnnotations.keys) {
extensionsWithMetaAnnotations.put(metaAnnotation, extension) extensionsWithMetaAnnotations.put(metaAnnotation, extension)
} }
_annotations += extension.annotations _annotations += extension.directlyApplicableAnnotations
_annotations += extension.childrenApplicableAnnotations
when (extension.mode) { when (extension.mode) {
FirExtensionPoint.Mode.ANNOTATED_ELEMENT -> { FirExtensionPoint.Mode.ANNOTATED_ELEMENT -> {
for (annotation in extension.annotations) { for (annotation in extension.directlyApplicableAnnotations) {
extensionsWithAnnotatedMode.put(annotation, extension) extensionsWithAnnotatedMode.put(annotation, extension)
} }
} for (annotation in extension.childrenApplicableAnnotations) {
FirExtensionPoint.Mode.ALL_IN_ANNOTATED_ELEMENT -> {
for (annotation in extension.annotations) {
extensionsWithAllInAnnotatedMode.put(annotation, extension) extensionsWithAllInAnnotatedMode.put(annotation, extension)
} }
} }
@@ -98,13 +97,17 @@ class FirExtensionPointService(
for (extension in extensions) { for (extension in extensions) {
val registeredExtensions = this[extension.extensionType] val registeredExtensions = this[extension.extensionType]
@Suppress("UNCHECKED_CAST") val metaAnnotationMode = extension.metaAnnotations.getValue(metaAnnotation)
val map = when (extension.mode) {
FirExtensionPoint.Mode.ANNOTATED_ELEMENT -> registeredExtensions.extensionsWithAnnotatedMode if (metaAnnotationMode.directed) {
FirExtensionPoint.Mode.ALL_IN_ANNOTATED_ELEMENT -> registeredExtensions.extensionsWithAllInAnnotatedMode @Suppress("UNCHECKED_CAST")
FirExtensionPoint.Mode.ALL -> throw IllegalStateException("Extension with mode ALL can't be subscribed to meta annotation") (registeredExtensions.extensionsWithAnnotatedMode as Multimap<AnnotationFqn, FirExtensionPoint>).put(fqName, extension)
} as Multimap<AnnotationFqn, FirExtensionPoint> }
map.put(fqName, extension)
if (metaAnnotationMode.children) {
@Suppress("UNCHECKED_CAST")
(registeredExtensions.extensionsWithAllInAnnotatedMode as Multimap<AnnotationFqn, FirExtensionPoint>).put(fqName, extension)
}
} }
} }
} }