From eef11c669a16106830d22cfd038be0071feb0741 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 23 Aug 2018 00:11:12 +0200 Subject: [PATCH] Extract TargetedAnnotations out of AnnotationsImpl Minimize AnnotationsImpl to leave it usable in simple scenarios where there's no use-site targeted annotations, and use TargetedAnnotations in the only place in the frontend (AnnotationResolverImpl) where use-sites were needed. Also, delete kdoc on Annotations.isEmpty to prevent readers from putting too much thought into how it works. With the exception of a few places in the frontend where use-site targeted annotations are still accessed via the Annotations object, it's now an implementation detail and users (such as backends, IDE) should not care about them at all, and instead should just deal with the correct element when processing annotations --- .../annotations/AnnotationSplitter.kt | 8 ++-- .../annotations/TargetedAnnotations.kt | 19 ++++++++++ .../resolve/AnnotationResolverImpl.java | 16 +++++--- .../annotations/AnnotationWithTarget.kt | 2 +- .../descriptors/annotations/Annotations.kt | 6 --- .../annotations/AnnotationsImpl.kt | 38 ++----------------- 6 files changed, 38 insertions(+), 51 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/kotlin/descriptors/annotations/TargetedAnnotations.kt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationSplitter.kt b/compiler/frontend/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationSplitter.kt index f531ecf4a0d..42d760bca55 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationSplitter.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationSplitter.kt @@ -108,11 +108,9 @@ class AnnotationSplitter( other.add(annotation) } - for ((annotation, useSiteTarget) in allAnnotations.getUseSiteTargetedAnnotations()) { - if (useSiteTarget == null) continue - - if (useSiteTarget in applicableTargets) { - map.getOrPut(useSiteTarget) { arrayListOf() }.add(annotation) + for ((annotation, target) in allAnnotations.getUseSiteTargetedAnnotations()) { + if (target in applicableTargets) { + map.getOrPut(target) { arrayListOf() }.add(annotation) } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/descriptors/annotations/TargetedAnnotations.kt b/compiler/frontend/src/org/jetbrains/kotlin/descriptors/annotations/TargetedAnnotations.kt new file mode 100644 index 00000000000..d52de358a06 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/kotlin/descriptors/annotations/TargetedAnnotations.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.descriptors.annotations + +class TargetedAnnotations( + private val standardAnnotations: List, + private val targetedAnnotations: List +) : Annotations { + override fun isEmpty(): Boolean = standardAnnotations.isEmpty() && targetedAnnotations.isEmpty() + + override fun getUseSiteTargetedAnnotations(): List = targetedAnnotations + + override fun iterator(): Iterator = standardAnnotations.iterator() + + override fun toString(): String = (standardAnnotations + targetedAnnotations).toString() +} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationResolverImpl.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationResolverImpl.java index d3575c7ba01..ebe91f62947 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationResolverImpl.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationResolverImpl.java @@ -17,10 +17,14 @@ package org.jetbrains.kotlin.resolve; import com.intellij.psi.util.PsiTreeUtil; +import kotlin.collections.CollectionsKt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.descriptors.*; -import org.jetbrains.kotlin.descriptors.annotations.*; +import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget; +import org.jetbrains.kotlin.descriptors.annotations.Annotations; +import org.jetbrains.kotlin.descriptors.annotations.TargetedAnnotations; import org.jetbrains.kotlin.diagnostics.Errors; import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.resolve.calls.CallResolver; @@ -79,7 +83,9 @@ public class AnnotationResolverImpl extends AnnotationResolver { boolean shouldResolveArguments ) { if (annotationEntryElements.isEmpty()) return Annotations.Companion.getEMPTY(); - List result = new ArrayList<>(0); + + List standard = new ArrayList<>(); + List targeted = new ArrayList<>(); for (KtAnnotationEntry entryElement : annotationEntryElements) { AnnotationDescriptor descriptor = trace.get(BindingContext.ANNOTATION, entryElement); @@ -92,13 +98,13 @@ public class AnnotationResolverImpl extends AnnotationResolver { KtAnnotationUseSiteTarget target = entryElement.getUseSiteTarget(); if (target != null) { - result.add(new AnnotationWithTarget(descriptor, target.getAnnotationUseSiteTarget())); + targeted.add(new AnnotationWithTarget(descriptor, target.getAnnotationUseSiteTarget())); } else { - result.add(new AnnotationWithTarget(descriptor, null)); + standard.add(descriptor); } } - return AnnotationsImpl.create(result); + return new TargetedAnnotations(CollectionsKt.toList(standard), CollectionsKt.toList(targeted)); } @Override diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationWithTarget.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationWithTarget.kt index 200cd834a02..08e1f2bf133 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationWithTarget.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationWithTarget.kt @@ -16,4 +16,4 @@ package org.jetbrains.kotlin.descriptors.annotations -data class AnnotationWithTarget(val annotation: AnnotationDescriptor, val target: AnnotationUseSiteTarget?) \ No newline at end of file +data class AnnotationWithTarget(val annotation: AnnotationDescriptor, val target: AnnotationUseSiteTarget) diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/Annotations.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/Annotations.kt index d4941dd0426..aee9d6dc195 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/Annotations.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/Annotations.kt @@ -23,12 +23,6 @@ interface Annotated { } interface Annotations : Iterable { - /** - * @return `true` iff there are no "direct" annotations applicable to this declaration. Note that even if [isEmpty] is `true`, - * there may be use-site-targeted annotations applicable to the declaration! - * - * @see getUseSiteTargetedAnnotations - */ fun isEmpty(): Boolean fun findAnnotation(fqName: FqName): AnnotationDescriptor? = firstOrNull { it.fqName == fqName } diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationsImpl.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationsImpl.kt index c02013fac21..05767127852 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationsImpl.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationsImpl.kt @@ -16,40 +16,10 @@ package org.jetbrains.kotlin.descriptors.annotations -class AnnotationsImpl : Annotations { - private val annotations: List - private val targetedAnnotations: List +class AnnotationsImpl(private val annotations: List) : Annotations { + override fun isEmpty(): Boolean = annotations.isEmpty() - constructor(annotations: List) { - this.annotations = annotations - this.targetedAnnotations = annotations.map { AnnotationWithTarget(it, null) } - } + override fun iterator(): Iterator = annotations.iterator() - // List and List have the same signature - private constructor( - targetedAnnotations: List, - @Suppress("UNUSED_PARAMETER") i: Int - ) { - this.targetedAnnotations = targetedAnnotations - this.annotations = targetedAnnotations.filter { it.target == null }.map { it.annotation } - } - - override fun isEmpty() = targetedAnnotations.isEmpty() - - override fun getUseSiteTargetedAnnotations(): List { - return targetedAnnotations - .filter { it.target != null } - .map { AnnotationWithTarget(it.annotation, it.target!!) } - } - - override fun iterator() = annotations.iterator() - - override fun toString() = annotations.toString() - - companion object { - @JvmStatic - fun create(annotationsWithTargets: List): AnnotationsImpl { - return AnnotationsImpl(annotationsWithTargets, 0) - } - } + override fun toString(): String = annotations.toString() }