Drop Annotations.getAllAnnotations

This commit is contained in:
Alexander Udalov
2018-08-16 12:18:36 +02:00
parent 83fbabd628
commit 87c0d56618
22 changed files with 51 additions and 109 deletions
@@ -245,7 +245,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
private void genTypeAliasAnnotationsMethodIfRequired(TypeAliasDescriptor typeAliasDescriptor) {
boolean isAnnotationsMethodOwner = CodegenContextUtil.isImplClassOwner(context);
Annotations annotations = typeAliasDescriptor.getAnnotations();
if (!isAnnotationsMethodOwner || annotations.getAllAnnotations().isEmpty()) return;
if (!isAnnotationsMethodOwner || annotations.isEmpty()) return;
String name = JvmAbi.getSyntheticMethodNameForAnnotatedTypeAlias(typeAliasDescriptor.getName());
generateSyntheticAnnotationsMethod(typeAliasDescriptor, new Method(name, "()V"), annotations);
@@ -335,7 +335,7 @@ public class PropertyCodegen {
// accessible via reflection, and 'deprecated' and 'synthetic' flags prevent this method from being called accidentally
private void generateSyntheticMethodIfNeeded(@NotNull PropertyDescriptor descriptor, boolean isBackingFieldOwner) {
Annotations annotations = descriptor.getAnnotations();
if (annotations.getAllAnnotations().isEmpty()) return;
if (annotations.isEmpty()) return;
Method signature = getSyntheticMethodSignature(descriptor);
if (kind != OwnerKind.DEFAULT_IMPLS && CodegenContextUtil.isImplClassOwner(context)) {
@@ -92,14 +92,7 @@ class AnnotationSplitter(
val applicableTargets = applicableTargetsLazy()
val applicableTargetsWithoutUseSiteTarget = applicableTargets.intersect(TARGET_PRIORITIES)
outer@ for ((annotation, useSiteTarget) in allAnnotations.getAllAnnotations()) {
if (useSiteTarget != null) {
if (useSiteTarget in applicableTargets)
map.getOrPut(useSiteTarget) { arrayListOf() }.add(annotation)
continue@outer
}
outer@ for (annotation in allAnnotations) {
for (target in TARGET_PRIORITIES) {
if (target !in applicableTargetsWithoutUseSiteTarget) continue
@@ -115,6 +108,14 @@ 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)
}
}
map to AnnotationsImpl(other)
}
@@ -137,14 +138,15 @@ class AnnotationSplitter(
}
override fun forceResolveAllContents() {
getAllAnnotations()
for (annotation in this) {
// TODO: probably we should do ForceResolveUtil.forceResolveAllContents(annotation) here
}
}
override fun isEmpty() = annotations.isEmpty()
override fun hasAnnotation(fqName: FqName) = annotations.hasAnnotation(fqName)
override fun findAnnotation(fqName: FqName) = annotations.findAnnotation(fqName)
override fun getUseSiteTargetedAnnotations() = annotations.getUseSiteTargetedAnnotations()
override fun getAllAnnotations() = annotations.getAllAnnotations()
override fun iterator() = annotations.iterator()
override fun toString() = annotations.toString()
}
@@ -20,7 +20,7 @@ import com.intellij.openapi.diagnostic.Logger;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
@@ -64,8 +64,8 @@ public class ForceResolveUtil {
public static void forceResolveAllContents(@NotNull Annotations annotations) {
doForceResolveAllContents(annotations);
for (AnnotationWithTarget annotationWithTarget : annotations.getAllAnnotations()) {
doForceResolveAllContents(annotationWithTarget.getAnnotation());
for (AnnotationDescriptor annotation : annotations) {
doForceResolveAllContents(annotation);
}
}
@@ -56,7 +56,6 @@ class LazyAnnotations(
override fun isEmpty() = annotationEntries.isEmpty()
private val annotation = c.storageManager.createMemoizedFunction { entry: KtAnnotationEntry ->
val descriptor = LazyAnnotationDescriptor(c, entry)
val target = entry.useSiteTarget?.getAnnotationUseSiteTarget()
AnnotationWithTarget(descriptor, target)
@@ -70,8 +69,6 @@ class LazyAnnotations(
}
}
override fun getAllAnnotations() = annotationEntries.map(annotation)
override fun iterator(): Iterator<AnnotationDescriptor> {
return annotationEntries
.asSequence()
@@ -83,7 +80,9 @@ class LazyAnnotations(
override fun forceResolveAllContents() {
// To resolve all entries
getAllAnnotations()
for (annotation in this) {
// TODO: probably we should do ForceResolveUtil.forceResolveAllContents(annotation) here
}
}
}
@@ -109,10 +109,7 @@ class TypeTranslator(
}
private fun translateTypeAnnotations(annotations: Annotations): List<IrCall> =
annotations.getAllAnnotations().map {
// TODO filter out annotation targets
constantValueGenerator.generateAnnotationConstructorCall(it.annotation)
}
annotations.map(constantValueGenerator::generateAnnotationConstructorCall)
private fun translateTypeArguments(arguments: List<TypeProjection>) =
arguments.map {
@@ -121,4 +118,4 @@ class TypeTranslator(
else
translateType(it.type, it.projectionKind)
}
}
}
@@ -32,7 +32,6 @@ import org.jetbrains.kotlin.resolve.constants.EnumValue
import org.jetbrains.kotlin.resolve.constants.IntValue
import org.jetbrains.kotlin.resolve.constants.NullValue
import org.jetbrains.kotlin.resolve.constants.StringValue
import org.jetbrains.kotlin.resolve.descriptorUtil.isSourceAnnotation
import org.jetbrains.kotlin.resolve.descriptorUtil.nonSourceAnnotations
import org.jetbrains.kotlin.serialization.deserialization.ProtoEnumFlags
import org.jetbrains.kotlin.types.*
@@ -752,11 +751,8 @@ class DescriptorSerializer private constructor(
Variance.OUT_VARIANCE -> ProtoBuf.Type.Argument.Projection.OUT
}
private fun hasAnnotations(descriptor: Annotated): Boolean {
// Sadly, we can't just return `descriptor.nonSourceAnnotations.isNotEmpty()` because that would not
// consider use-site-targeted annotations
return descriptor.annotations.getAllAnnotations().filterNot { it.annotation.isSourceAnnotation }.isNotEmpty()
}
private fun hasAnnotations(descriptor: Annotated): Boolean =
descriptor.nonSourceAnnotations.isNotEmpty()
fun <T : DeclarationDescriptor> sort(descriptors: Collection<T>): List<T> =
ArrayList(descriptors).apply {
@@ -1,8 +1,8 @@
package
public final class A {
public constructor A(/*0*/ @Ann @Ann x: kotlin.Int, /*1*/ @RepeatableAnn @Ann y: kotlin.Int)
@Ann @RepeatableAnn @RepeatableAnn @field:Ann public final val a: kotlin.Int = 0
public constructor A(/*0*/ @Ann @Ann x: kotlin.Int, /*1*/ @Ann @RepeatableAnn y: kotlin.Int)
@RepeatableAnn @Ann @RepeatableAnn @field:Ann public final val a: kotlin.Int = 0
@Ann @Ann @field:Ann public final val b: kotlin.Int = 0
@field:RepeatableAnn @field:RepeatableAnn public final val c: kotlin.Int = 0
@RepeatableAnn @RepeatableAnn public final val d: kotlin.Int = 0
@@ -153,7 +153,7 @@ public abstract class AbstractAnnotationDescriptorResolveTest extends KotlinTest
}
private static void checkAnnotationsOnProperty(String expectedAnnotation, PropertyDescriptor prop) {
checkDescriptorWithTarget(expectedAnnotation, prop, AnnotationUseSiteTarget.FIELD);
checkDescriptor(expectedAnnotation, prop);
checkDescriptor(expectedAnnotation, prop.getGetter());
PropertySetterDescriptor propSetter = prop.getSetter();
assertNotNull(propSetter);
@@ -361,32 +361,15 @@ public abstract class AbstractAnnotationDescriptorResolveTest extends KotlinTest
return KotlinTestUtils.doLoadFile(file).replaceAll("ANNOTATION", annotationText);
}
private static String renderAnnotations(Annotations annotations, @Nullable AnnotationUseSiteTarget defaultTarget) {
return StringUtil.join(annotations.getAllAnnotations(), annotationWithTarget -> {
AnnotationUseSiteTarget targetToRender = annotationWithTarget.getTarget();
if (targetToRender == defaultTarget) {
targetToRender = null;
}
return WITH_ANNOTATION_ARGUMENT_TYPES.renderAnnotation(annotationWithTarget.getAnnotation(), targetToRender);
}, " ");
public static String renderAnnotations(Annotations annotations) {
return StringUtil.join(annotations, annotation -> WITH_ANNOTATION_ARGUMENT_TYPES.renderAnnotation(annotation, null), " ");
}
protected static void checkDescriptor(String expectedAnnotation, DeclarationDescriptor member) {
String actual = getAnnotations(member);
private static void checkDescriptor(String expectedAnnotation, DeclarationDescriptor member) {
String actual = renderAnnotations(member.getAnnotations());
assertEquals("Failed to resolve annotation descriptor for " + member.toString(), expectedAnnotation, actual);
}
private static void checkDescriptorWithTarget(String expectedAnnotation, DeclarationDescriptor member, AnnotationUseSiteTarget target) {
String actual = renderAnnotations(member.getAnnotations(), target);
assertEquals("Failed to resolve annotation descriptor for " + member.toString(), expectedAnnotation, actual);
}
@NotNull
protected static String getAnnotations(DeclarationDescriptor member) {
return renderAnnotations(member.getAnnotations(), null);
}
@Override
public void tearDown() throws Exception {
analysisResult = null;
@@ -28,7 +28,7 @@ abstract class AbstractAnnotationParameterTest : AbstractAnnotationDescriptorRes
val classDescriptor = AbstractAnnotationDescriptorResolveTest.getClassDescriptor(packageView, "MyClass")
val expected = InTextDirectivesUtils.findListWithPrefixes(fileText, "// EXPECTED: ").joinToString(", ")
val actual = AbstractAnnotationDescriptorResolveTest.getAnnotations(classDescriptor)
val actual = AbstractAnnotationDescriptorResolveTest.renderAnnotations(classDescriptor.annotations)
KotlinTestUtils.assertEqualsToFile(File(path), fileText.replace(expected, actual))
}
@@ -38,8 +38,6 @@ class LazyJavaAnnotations(
override fun getUseSiteTargetedAnnotations() = emptyList<AnnotationWithTarget>()
override fun getAllAnnotations() = this.map { AnnotationWithTarget(it, null) }
override fun iterator() =
(annotationOwner.annotations.asSequence().map(annotationDescriptors)
+ JavaAnnotationMapper.findMappedJavaAnnotation(KotlinBuiltIns.FQ_NAMES.deprecated, annotationOwner, c)).filterNotNull().iterator()
@@ -198,8 +198,6 @@ private class EnhancedTypeAnnotations(private val fqNameToMatch: FqName) : Annot
else -> null
}
override fun getAllAnnotations() = this.map { AnnotationWithTarget(it, null) }
override fun getUseSiteTargetedAnnotations() = emptyList<AnnotationWithTarget>()
// Note, that this class may break Annotations contract (!isEmpty && iterator.isEmpty())
@@ -28,7 +28,6 @@ interface Annotations : Iterable<AnnotationDescriptor> {
* there may be use-site-targeted annotations applicable to the declaration!
*
* @see getUseSiteTargetedAnnotations
* @see getAllAnnotations
*/
fun isEmpty(): Boolean
@@ -38,11 +37,6 @@ interface Annotations : Iterable<AnnotationDescriptor> {
fun getUseSiteTargetedAnnotations(): List<AnnotationWithTarget>
/**
* @return both targeted and annotations without target. Annotation order is preserved.
*/
fun getAllAnnotations(): List<AnnotationWithTarget>
companion object {
val EMPTY: Annotations = object : Annotations {
override fun isEmpty() = true
@@ -51,8 +45,6 @@ interface Annotations : Iterable<AnnotationDescriptor> {
override fun getUseSiteTargetedAnnotations() = emptyList<AnnotationWithTarget>()
override fun getAllAnnotations() = emptyList<AnnotationWithTarget>()
override fun iterator() = emptyList<AnnotationDescriptor>().iterator()
override fun toString() = "EMPTY"
@@ -77,10 +69,6 @@ class FilteredAnnotations(
return delegate.getUseSiteTargetedAnnotations().filter { shouldBeReturned(it.annotation) }
}
override fun getAllAnnotations(): List<AnnotationWithTarget> {
return delegate.getAllAnnotations().filter { shouldBeReturned(it.annotation) }
}
override fun iterator() = delegate.filter(this::shouldBeReturned).iterator()
override fun isEmpty() = delegate.any(this::shouldBeReturned)
@@ -104,8 +92,6 @@ class CompositeAnnotations(
override fun getUseSiteTargetedAnnotations() = delegates.flatMap { it.getUseSiteTargetedAnnotations() }
override fun getAllAnnotations() = delegates.flatMap { it.getAllAnnotations() }
override fun iterator() = delegates.asSequence().flatMap { it.asSequence() }.iterator()
}
@@ -42,8 +42,6 @@ class AnnotationsImpl : Annotations {
.map { AnnotationWithTarget(it.annotation, it.target!!) }
}
override fun getAllAnnotations() = targetedAnnotations
override fun iterator() = annotations.iterator()
override fun toString() = annotations.toString()
@@ -50,6 +50,4 @@ private class AnnotationsWithOnly(val presentAnnotation: FqName): Annotations {
override fun hasAnnotation(fqName: FqName): Boolean = fqName == this.presentAnnotation
override fun getUseSiteTargetedAnnotations(): List<AnnotationWithTarget> = emptyList()
override fun getAllAnnotations(): List<AnnotationWithTarget> = emptyList()
}
@@ -125,8 +125,8 @@ abstract class SimpleType : UnwrappedType() {
override fun toString(): String {
return buildString {
for ((annotation, target) in annotations.getAllAnnotations()) {
append("[", DescriptorRenderer.DEBUG_TEXT.renderAnnotation(annotation, target), "] ")
for (annotation in annotations) {
append("[", DescriptorRenderer.DEBUG_TEXT.renderAnnotation(annotation), "] ")
}
append(constructor)
@@ -33,8 +33,6 @@ open class DeserializedAnnotations(
override fun getUseSiteTargetedAnnotations(): List<AnnotationWithTarget> = emptyList()
override fun getAllAnnotations(): List<AnnotationWithTarget> = annotations.map { AnnotationWithTarget(it, null) }
override fun iterator(): Iterator<AnnotationDescriptor> = annotations.iterator()
}
@@ -58,8 +56,6 @@ open class DeserializedAnnotationsWithPossibleTargets(
override fun getUseSiteTargetedAnnotations(): List<AnnotationWithTarget> = annotations.filter { it.target != null }
override fun getAllAnnotations(): List<AnnotationWithTarget> = annotations
override fun iterator(): Iterator<AnnotationDescriptor> {
return annotations.asSequence().filter { it.target == null }.map { it.annotation }.iterator()
}
@@ -19,16 +19,16 @@ package org.jetbrains.kotlin.idea.run
import com.intellij.execution.JUnitRecognizer
import com.intellij.psi.PsiMethod
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.idea.caches.project.implementingDescriptors
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.project.platform
import org.jetbrains.kotlin.idea.util.module
import org.jetbrains.kotlin.platform.impl.isCommon
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
@@ -45,13 +45,12 @@ class KotlinMultiplatformJUnitRecognizer : JUnitRecognizer() {
if (implModules.isEmpty()) return false
val methodDescriptor = origin.resolveToDescriptorIfAny() ?: return false
return methodDescriptor.annotations.getAllAnnotations().any { it.isExpectOfAnnotation("org.junit.Test", implModules) }
return methodDescriptor.annotations.any { it.isExpectOfAnnotation("org.junit.Test", implModules) }
}
}
private fun AnnotationWithTarget.isExpectOfAnnotation(fqName: String, implModules: Collection<ModuleDescriptor>): Boolean {
val annotationClass = annotation.type.constructor.declarationDescriptor as? ClassifierDescriptorWithTypeParameters ?: return false
private fun AnnotationDescriptor.isExpectOfAnnotation(fqName: String, implModules: Collection<ModuleDescriptor>): Boolean {
val annotationClass = annotationClass ?: return false
if (!annotationClass.isExpect) return false
val classId = annotationClass.classId ?: return false
val segments = classId.relativeClassName.pathSegments()
@@ -32,7 +32,6 @@ import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.core.OptionalParametersHelper
import org.jetbrains.kotlin.idea.core.resolveCandidates
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
import org.jetbrains.kotlin.idea.util.ShadowedDeclarationsFilter
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.load.java.NULLABILITY_ANNOTATIONS
@@ -259,10 +258,9 @@ abstract class KotlinParameterInfoWithCallHandlerBase<TArgumentList : KtElement,
parameter
.annotations
.getAllAnnotations()
.filterNot { it.annotation.fqName in NULLABILITY_ANNOTATIONS }
.filterNot { it.fqName in NULLABILITY_ANNOTATIONS }
.forEach {
it.annotation.fqName?.let { append("@${it.shortName().asString()} ") }
it.fqName?.let { fqName -> append("@${fqName.shortName().asString()} ") }
}
if (parameter.varargElementType != null) {
@@ -20,8 +20,8 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.MemberDescriptor
import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.resolve.descriptorUtil.getAnnotationRetention
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
@@ -29,16 +29,15 @@ import org.jetbrains.kotlin.resolve.source.PsiSourceElement
object JsRuntimeAnnotationChecker : DeclarationChecker {
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
for ((annotationDescriptor, _) in descriptor.annotations.getAllAnnotations()) {
val annotationClass = annotationDescriptor.annotationClass ?: continue
for (annotation in descriptor.annotations) {
val annotationClass = annotation.annotationClass ?: continue
if (annotationClass.getAnnotationRetention() != KotlinRetention.RUNTIME) continue
val annotationPsi = (annotationDescriptor.source as? PsiSourceElement)?.psi ?: declaration
val annotationPsi = (annotation.source as? PsiSourceElement)?.psi ?: declaration
if (descriptor is MemberDescriptor && descriptor.isEffectivelyExternal()) {
context.trace.report(ErrorsJs.RUNTIME_ANNOTATION_ON_EXTERNAL_DECLARATION.on(annotationPsi))
}
else {
} else {
context.trace.report(ErrorsJs.RUNTIME_ANNOTATION_NOT_SUPPORTED.on(annotationPsi))
}
}
@@ -88,10 +88,10 @@ class ParcelableAnnotationChecker : CallChecker {
val descriptor = context.trace[BindingContext.DECLARATION_TO_DESCRIPTOR, element] ?: return
val thisMappedType = resolvedCall.typeArguments.values.takeIf { it.size == 2 }?.first() ?: return
val duplicatingAnnotationCount = descriptor.annotations.getAllAnnotations()
.filter { it.annotation.fqName == TYPE_PARCELER_FQNAME }
.mapNotNull { it.annotation.type.arguments.takeIf { it.size == 2 }?.first()?.type }
.count { it == thisMappedType }
val duplicatingAnnotationCount = descriptor.annotations
.filter { it.fqName == TYPE_PARCELER_FQNAME }
.mapNotNull { it.type.arguments.takeIf { args -> args.size == 2 }?.first()?.type }
.count { it == thisMappedType }
if (duplicatingAnnotationCount > 1) {
val reportElement = annotationEntry.typeArguments.firstOrNull() ?: annotationEntry
@@ -19,8 +19,6 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.diagnostics.reportFromPlugin
@@ -88,10 +86,7 @@ class ParcelableDeclarationChecker : DeclarationChecker {
bindingContext: BindingContext
) {
fun hasIgnoredOnParcel(): Boolean {
fun AnnotationDescriptor.isIgnoredOnParcel() = fqName == IGNORED_ON_PARCEL_FQNAME
fun Annotations.hasIgnoredOnParcel() = getAllAnnotations()
.any { (it.target == null || it.target == AnnotationUseSiteTarget.PROPERTY_GETTER) && it.annotation.isIgnoredOnParcel() }
fun Annotations.hasIgnoredOnParcel() = any { it.fqName == IGNORED_ON_PARCEL_FQNAME }
return property.annotations.hasIgnoredOnParcel() || (property.getter?.annotations?.hasIgnoredOnParcel() ?: false)
}