From 4ead50352d4525ba8ab94294d987d56ae490851f Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Wed, 5 Aug 2015 18:17:53 +0300 Subject: [PATCH] Put @receiver-targeted annotations on receiver type --- .../annotations/types/ReceiverParameter.kt | 4 +- .../annotations/types/ReceiverParameter.txt | 2 +- .../withUseSiteTarget/ReceiverTarget.kt | 10 +-- .../withUseSiteTarget/ReceiverTarget.txt | 12 +-- .../deserialization/DeserializedType.kt | 20 +++-- .../deserialization/MemberDeserializer.kt | 76 +++++++++---------- .../deserialization/TypeDeserializer.kt | 6 +- .../DeserializedTypeParameterDescriptor.java | 3 +- 8 files changed, 66 insertions(+), 67 deletions(-) diff --git a/compiler/testData/loadJava/compiledKotlin/annotations/types/ReceiverParameter.kt b/compiler/testData/loadJava/compiledKotlin/annotations/types/ReceiverParameter.kt index f02ab0d1577..cb32b4da07a 100644 --- a/compiler/testData/loadJava/compiledKotlin/annotations/types/ReceiverParameter.kt +++ b/compiler/testData/loadJava/compiledKotlin/annotations/types/ReceiverParameter.kt @@ -1,5 +1,7 @@ +//ALLOW_AST_ACCESS package test +target(AnnotationTarget.TYPE) annotation class A -fun (@A String).foo() {} +fun @A String.foo() {} diff --git a/compiler/testData/loadJava/compiledKotlin/annotations/types/ReceiverParameter.txt b/compiler/testData/loadJava/compiledKotlin/annotations/types/ReceiverParameter.txt index 49b0ae3d3da..1aea8d9d3f4 100644 --- a/compiler/testData/loadJava/compiledKotlin/annotations/types/ReceiverParameter.txt +++ b/compiler/testData/loadJava/compiledKotlin/annotations/types/ReceiverParameter.txt @@ -2,6 +2,6 @@ package test internal fun @[test.A()] kotlin.String.foo(): kotlin.Unit -kotlin.annotation.annotation() internal final class A : kotlin.Annotation { +kotlin.annotation.target(allowedTargets = {AnnotationTarget.TYPE}) kotlin.annotation.annotation() internal final class A : kotlin.Annotation { /*primary*/ public constructor A() } diff --git a/compiler/testData/loadJava/compiledKotlin/annotations/withUseSiteTarget/ReceiverTarget.kt b/compiler/testData/loadJava/compiledKotlin/annotations/withUseSiteTarget/ReceiverTarget.kt index 72ab25be3a8..7de05aeb649 100644 --- a/compiler/testData/loadJava/compiledKotlin/annotations/withUseSiteTarget/ReceiverTarget.kt +++ b/compiler/testData/loadJava/compiledKotlin/annotations/withUseSiteTarget/ReceiverTarget.kt @@ -1,3 +1,4 @@ +//ALLOW_AST_ACCESS package test target(AnnotationTarget.VALUE_PARAMETER) @@ -5,17 +6,14 @@ annotation class Ann class A { - @receiver:Ann - fun String.myLength(@Ann q:String): Int { + fun @receiver:Ann String.myLength(@Ann q:String): Int { return length() } - @receiver:Ann - val String.myLength2: Int + val @receiver:Ann String.myLength2: Int get() = length() - @receiver:Ann - var String.myLength3: Int + var @receiver:[Ann] String.myLength3: Int get() = length() set(v) {} diff --git a/compiler/testData/loadJava/compiledKotlin/annotations/withUseSiteTarget/ReceiverTarget.txt b/compiler/testData/loadJava/compiledKotlin/annotations/withUseSiteTarget/ReceiverTarget.txt index 2d708993bbf..e5c78579137 100644 --- a/compiler/testData/loadJava/compiledKotlin/annotations/withUseSiteTarget/ReceiverTarget.txt +++ b/compiler/testData/loadJava/compiledKotlin/annotations/withUseSiteTarget/ReceiverTarget.txt @@ -2,12 +2,12 @@ package test internal final class A { /*primary*/ public constructor A() - @receiver:test.Ann() internal final val kotlin.String.myLength2: kotlin.Int - internal final fun kotlin.String.(): kotlin.Int - @receiver:test.Ann() internal final var kotlin.String.myLength3: kotlin.Int - internal final fun kotlin.String.(): kotlin.Int - internal final fun kotlin.String.(/*0*/ v: kotlin.Int): kotlin.Unit - @receiver:test.Ann() internal final fun kotlin.String.myLength(/*0*/ test.Ann() q: kotlin.String): kotlin.Int + internal final val @receiver:test.Ann() kotlin.String.myLength2: kotlin.Int + internal final fun @receiver:test.Ann() kotlin.String.(): kotlin.Int + internal final var @receiver:test.Ann() kotlin.String.myLength3: kotlin.Int + internal final fun @receiver:test.Ann() kotlin.String.(): kotlin.Int + internal final fun @receiver:test.Ann() kotlin.String.(/*0*/ v: kotlin.Int): kotlin.Unit + internal final fun @receiver:test.Ann() kotlin.String.myLength(/*0*/ test.Ann() q: kotlin.String): kotlin.Int } kotlin.annotation.target(allowedTargets = {AnnotationTarget.VALUE_PARAMETER}) kotlin.annotation.annotation() internal final class Ann : kotlin.Annotation { diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedType.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedType.kt index 1acfc196b2f..7c757c4042e 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedType.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedType.kt @@ -16,9 +16,10 @@ package org.jetbrains.kotlin.serialization.deserialization +import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.serialization.ProtoBuf -import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedAnnotations +import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedAnnotationsWithPossibleTargets import org.jetbrains.kotlin.types.AbstractLazyType import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.LazyType @@ -26,26 +27,29 @@ import org.jetbrains.kotlin.utils.toReadOnlyList class DeserializedType( private val c: DeserializationContext, - private val typeProto: ProtoBuf.Type + private val typeProto: ProtoBuf.Type, + private val additionalAnnotations: Annotations = Annotations.EMPTY ) : AbstractLazyType(c.storageManager), LazyType { private val typeDeserializer = c.typeDeserializer override fun computeTypeConstructor() = typeDeserializer.typeConstructor(typeProto) override fun computeArguments() = - typeProto.getArgumentList().mapIndexed { + typeProto.argumentList.mapIndexed { index, proto -> - typeDeserializer.typeArgument(getConstructor().getParameters().getOrNull(index), proto) + typeDeserializer.typeArgument(constructor.parameters.getOrNull(index), proto) }.toReadOnlyList() - private val annotations = DeserializedAnnotations(c.storageManager) { - c.components.annotationAndConstantLoader.loadTypeAnnotations(typeProto, c.nameResolver) + private val annotations = DeserializedAnnotationsWithPossibleTargets(c.storageManager) { + c.components.annotationAndConstantLoader + .loadTypeAnnotations(typeProto, c.nameResolver) + .map { AnnotationWithTarget(it, null) } + additionalAnnotations.getAllAnnotations() } - override fun isMarkedNullable(): Boolean = typeProto.getNullable() + override fun isMarkedNullable(): Boolean = typeProto.nullable override fun isError(): Boolean { - val descriptor = getConstructor().getDeclarationDescriptor() + val descriptor = constructor.declarationDescriptor return descriptor != null && ErrorUtils.isError(descriptor) } diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MemberDeserializer.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MemberDeserializer.kt index 7d6944c83d8..a9b86f6df07 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MemberDeserializer.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MemberDeserializer.kt @@ -17,7 +17,6 @@ package org.jetbrains.kotlin.serialization.deserialization import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget import org.jetbrains.kotlin.descriptors.annotations.Annotations @@ -47,16 +46,9 @@ public class MemberDeserializer(private val c: DeserializationContext) { private fun loadProperty(proto: Callable): PropertyDescriptor { val flags = proto.getFlags() - val hasGetter = Flags.HAS_GETTER.get(flags) - - val propertyAnnotations = if (hasGetter) - getAnnotationsWithReceiverTargeted(proto, AnnotatedCallableKind.PROPERTY, AnnotatedCallableKind.PROPERTY_GETTER) - else - getAnnotations(proto, flags, AnnotatedCallableKind.PROPERTY) - val property = DeserializedPropertyDescriptor( c.containingDeclaration, null, - propertyAnnotations, + getAnnotations(proto, flags, AnnotatedCallableKind.PROPERTY), modality(Flags.MODALITY.get(flags)), visibility(Flags.VISIBILITY.get(flags)), Flags.CALLABLE_KIND.get(flags) == Callable.CallableKind.VAR, @@ -67,11 +59,18 @@ public class MemberDeserializer(private val c: DeserializationContext) { ) val local = c.childContext(property, proto.getTypeParameterList()) + + val hasGetter = Flags.HAS_GETTER.get(flags) + val receiverAnnotations = if (hasGetter) + getReceiverParameterAnnotations(proto, AnnotatedCallableKind.PROPERTY_GETTER) + else + Annotations.EMPTY + property.setType( local.typeDeserializer.type(proto.getReturnType()), local.typeDeserializer.ownTypeParameters, getDispatchReceiverParameter(), - if (proto.hasReceiverType()) local.typeDeserializer.type(proto.getReceiverType()) else null + if (proto.hasReceiverType()) local.typeDeserializer.type(proto.getReceiverType(), receiverAnnotations) else null ) val getter = if (hasGetter) { @@ -126,10 +125,10 @@ public class MemberDeserializer(private val c: DeserializationContext) { if (Flags.HAS_CONSTANT.get(flags)) { property.setCompileTimeInitializer( - c.storageManager.createNullableLazyValue { - val container = c.containingDeclaration.asProtoContainer() - c.components.annotationAndConstantLoader.loadPropertyConstant(container, proto, c.nameResolver, property.getReturnType()) - } + c.storageManager.createNullableLazyValue { + val container = c.containingDeclaration.asProtoContainer() + c.components.annotationAndConstantLoader.loadPropertyConstant(container, proto, c.nameResolver, property.getReturnType()) + } ) } @@ -139,13 +138,12 @@ public class MemberDeserializer(private val c: DeserializationContext) { } private fun loadFunction(proto: Callable): CallableMemberDescriptor { - val annotations = getAnnotationsWithReceiverTargeted(proto, AnnotatedCallableKind.FUNCTION) + val annotations = getAnnotations(proto, proto.getFlags(), AnnotatedCallableKind.FUNCTION) + val receiverAnnotations = getReceiverParameterAnnotations(proto, AnnotatedCallableKind.FUNCTION) val function = DeserializedSimpleFunctionDescriptor.create(c.containingDeclaration, proto, c.nameResolver, annotations) val local = c.childContext(function, proto.getTypeParameterList()) - val receiverParameterType = if (proto.hasReceiverType()) local.typeDeserializer.type(proto.getReceiverType()) else null - function.initialize( - receiverParameterType, + if (proto.hasReceiverType()) local.typeDeserializer.type(proto.getReceiverType(), receiverAnnotations) else null, getDispatchReceiverParameter(), local.typeDeserializer.ownTypeParameters, local.memberDeserializer.valueParameters(proto, AnnotatedCallableKind.FUNCTION), @@ -176,29 +174,6 @@ public class MemberDeserializer(private val c: DeserializationContext) { return descriptor } - private fun getAnnotationsWithReceiverTargeted( - proto: Callable, - kind: AnnotatedCallableKind, - receiverTargetedKind: AnnotatedCallableKind = kind - ): Annotations { - return DeserializedAnnotationsWithPossibleTargets(c.storageManager) { - val annotations = arrayListOf() - val container = c.containingDeclaration.asProtoContainer() - - annotations += c.components.annotationAndConstantLoader - .loadCallableAnnotations(container, proto, c.nameResolver, kind) - .map { AnnotationWithTarget(it, null) } - - if (proto.hasReceiverType()) { - annotations += c.components.annotationAndConstantLoader - .loadExtensionReceiverParameterAnnotations(container, proto, c.nameResolver, receiverTargetedKind) - .map { AnnotationWithTarget(it, AnnotationUseSiteTarget.RECEIVER) } - } - - annotations - } - } - private fun getAnnotations(proto: Callable, flags: Int, kind: AnnotatedCallableKind): Annotations { if (!Flags.HAS_ANNOTATIONS.get(flags)) { return Annotations.EMPTY @@ -210,6 +185,25 @@ public class MemberDeserializer(private val c: DeserializationContext) { } } + private fun getReceiverParameterAnnotations( + proto: Callable, + kind: AnnotatedCallableKind, + receiverTargetedKind: AnnotatedCallableKind = kind + ): Annotations { + return DeserializedAnnotationsWithPossibleTargets(c.storageManager) { + val annotations = arrayListOf() + val container = c.containingDeclaration.asProtoContainer() + + if (proto.hasReceiverType()) { + annotations += c.components.annotationAndConstantLoader + .loadExtensionReceiverParameterAnnotations(container, proto, c.nameResolver, receiverTargetedKind) + .map { AnnotationWithTarget(it, AnnotationUseSiteTarget.RECEIVER) } + } + + annotations + } + } + private fun valueParameters(callable: Callable, kind: AnnotatedCallableKind): List { val callableDescriptor = c.containingDeclaration as CallableDescriptor val containerOfCallable = callableDescriptor.getContainingDeclaration().asProtoContainer() diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt index 444f053ee67..0c6eb8c48a7 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt @@ -16,9 +16,9 @@ package org.jetbrains.kotlin.serialization.deserialization -import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor +import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedTypeParameterDescriptor import org.jetbrains.kotlin.types.* @@ -76,7 +76,7 @@ public class TypeDeserializer( val ownTypeParameters: List get() = typeParameterDescriptors().values().toReadOnlyList() - fun type(proto: ProtoBuf.Type): JetType { + fun type(proto: ProtoBuf.Type, additionalAnnotations: Annotations = Annotations.EMPTY): JetType { if (proto.hasFlexibleTypeCapabilitiesId()) { val id = c.nameResolver.getString(proto.getFlexibleTypeCapabilitiesId()) val capabilities = c.components.flexibleTypeCapabilitiesDeserializer.capabilitiesById(id) @@ -92,7 +92,7 @@ public class TypeDeserializer( ) } - return DeserializedType(c, proto) + return DeserializedType(c, proto, additionalAnnotations) } fun typeConstructor(proto: ProtoBuf.Type): TypeConstructor { diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedTypeParameterDescriptor.java b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedTypeParameterDescriptor.java index 0f61ee14831..292e04761a9 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedTypeParameterDescriptor.java +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedTypeParameterDescriptor.java @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.serialization.deserialization.descriptors; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.descriptors.SourceElement; +import org.jetbrains.kotlin.descriptors.annotations.Annotations; import org.jetbrains.kotlin.descriptors.impl.AbstractLazyTypeParameterDescriptor; import org.jetbrains.kotlin.serialization.ProtoBuf; import org.jetbrains.kotlin.serialization.deserialization.DeserializationContext; @@ -55,7 +56,7 @@ public class DeserializedTypeParameterDescriptor extends AbstractLazyTypeParamet } Set result = new LinkedHashSet(proto.getUpperBoundCount()); for (ProtoBuf.Type upperBound : proto.getUpperBoundList()) { - result.add(typeDeserializer.type(upperBound)); + result.add(typeDeserializer.type(upperBound, Annotations.EMPTY)); } return result; }