From a3ba1af42193b548385c54c1095e00eacb020399 Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Wed, 5 Aug 2015 15:14:11 +0300 Subject: [PATCH] Generate receiver annotations using extension receiver type parameter --- .../kotlin/codegen/FunctionCodegen.java | 12 ++++---- .../resolve/AnnotationUseSiteTargetChecker.kt | 29 ++++++++++++++----- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index 7071b957bec..5591804944a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -268,12 +268,14 @@ public class FunctionCodegen { } } else if (kind == JvmMethodParameterKind.RECEIVER) { - Annotated annotationHolder = (functionDescriptor instanceof PropertyAccessorDescriptor) + ReceiverParameterDescriptor receiver = ((functionDescriptor instanceof PropertyAccessorDescriptor) ? ((PropertyAccessorDescriptor) functionDescriptor).getCorrespondingProperty() - : functionDescriptor; - AnnotationCodegen annotationCodegen = AnnotationCodegen.forParameter(i, mv, typeMapper); - Annotated targetedAnnotations = new AnnotatedWithAdditionalAnnotations(null, annotationHolder); - annotationCodegen.genAnnotations(targetedAnnotations, parameterSignature.getAsmType(), RECEIVER); + : functionDescriptor).getExtensionReceiverParameter(); + if (receiver != null) { + AnnotationCodegen annotationCodegen = AnnotationCodegen.forParameter(i, mv, typeMapper); + Annotated targetedAnnotations = new AnnotatedWithAdditionalAnnotations(null, receiver.getType()); + annotationCodegen.genAnnotations(targetedAnnotations, parameterSignature.getAsmType(), RECEIVER); + } } } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationUseSiteTargetChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationUseSiteTargetChecker.kt index e38027ba283..e80bfa825a5 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationUseSiteTargetChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationUseSiteTargetChecker.kt @@ -38,6 +38,26 @@ public object AnnotationUseSiteTargetChecker { } } + if (descriptor is CallableDescriptor) trace.checkReceiverAnnotations(descriptor) + } + + private fun BindingTrace.checkReceiverAnnotations(descriptor: CallableDescriptor) { + val extensionReceiver = descriptor.extensionReceiverParameter ?: return + for (annotationWithTarget in extensionReceiver.type.annotations.getUseSiteTargetedAnnotations()) { + val annotation = annotationWithTarget.annotation + val target = annotationWithTarget.target ?: continue + + when (target) { + AnnotationUseSiteTarget.RECEIVER -> {} + AnnotationUseSiteTarget.FIELD, + AnnotationUseSiteTarget.PROPERTY, + AnnotationUseSiteTarget.PROPERTY_GETTER, + AnnotationUseSiteTarget.PROPERTY_SETTER, + AnnotationUseSiteTarget.SETTER_PARAMETER -> report(annotationWithTarget, INAPPLICABLE_TARGET_ON_PROPERTY) + AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER -> report(annotation, INAPPLICABLE_PARAM_TARGET) + AnnotationUseSiteTarget.FILE -> throw IllegalArgumentException("@file annotations are not allowed here") + } + } } private fun BindingTrace.checkDeclaration(annotated: JetAnnotated, descriptor: DeclarationDescriptor) { @@ -50,14 +70,6 @@ public object AnnotationUseSiteTargetChecker { AnnotationUseSiteTarget.PROPERTY -> checkIfPropertyDescriptor(descriptor, annotationWithTarget) AnnotationUseSiteTarget.PROPERTY_GETTER -> checkIfPropertyDescriptor(descriptor, annotationWithTarget) AnnotationUseSiteTarget.PROPERTY_SETTER -> checkMutableProperty(descriptor, annotationWithTarget) - AnnotationUseSiteTarget.RECEIVER -> { - if (descriptor !is FunctionDescriptor && descriptor !is PropertyDescriptor) { - report(annotation, INAPPLICABLE_RECEIVER_TARGET) - } - else if ((descriptor as CallableMemberDescriptor).extensionReceiverParameter == null) { - report(annotation, INAPPLICABLE_RECEIVER_TARGET) - } - } AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER -> { if (annotated !is JetParameter) { report(annotation, INAPPLICABLE_PARAM_TARGET) @@ -74,6 +86,7 @@ public object AnnotationUseSiteTargetChecker { } AnnotationUseSiteTarget.SETTER_PARAMETER -> checkMutableProperty(descriptor, annotationWithTarget) AnnotationUseSiteTarget.FILE -> throw IllegalArgumentException("@file annotations are not allowed here") + AnnotationUseSiteTarget.RECEIVER -> report(annotation, INAPPLICABLE_RECEIVER_TARGET) } } }