Put @receiver-targeted annotations on receiver type

This commit is contained in:
Yan Zhulanow
2015-08-05 18:17:53 +03:00
parent 91626cf02e
commit 4ead50352d
8 changed files with 66 additions and 67 deletions
@@ -1,5 +1,7 @@
//ALLOW_AST_ACCESS
package test
target(AnnotationTarget.TYPE)
annotation class A
fun (@A String).foo() {}
fun @A String.foo() {}
@@ -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()
}
@@ -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) {}
@@ -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.<get-myLength2>(): kotlin.Int
@receiver:test.Ann() internal final var kotlin.String.myLength3: kotlin.Int
internal final fun kotlin.String.<get-myLength3>(): kotlin.Int
internal final fun kotlin.String.<set-myLength3>(/*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.<get-myLength2>(): kotlin.Int
internal final var @receiver:test.Ann() kotlin.String.myLength3: kotlin.Int
internal final fun @receiver:test.Ann() kotlin.String.<get-myLength3>(): kotlin.Int
internal final fun @receiver:test.Ann() kotlin.String.<set-myLength3>(/*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 {
@@ -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)
}
@@ -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<AnnotationWithTarget>()
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<AnnotationWithTarget>()
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<ValueParameterDescriptor> {
val callableDescriptor = c.containingDeclaration as CallableDescriptor
val containerOfCallable = callableDescriptor.getContainingDeclaration().asProtoContainer()
@@ -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<TypeParameterDescriptor>
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 {
@@ -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<JetType> result = new LinkedHashSet<JetType>(proto.getUpperBoundCount());
for (ProtoBuf.Type upperBound : proto.getUpperBoundList()) {
result.add(typeDeserializer.type(upperBound));
result.add(typeDeserializer.type(upperBound, Annotations.EMPTY));
}
return result;
}