From 00cfb3054a937e633b00da57dba8007416f6dfde Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Thu, 16 Jul 2015 18:57:54 +0300 Subject: [PATCH] Support @receiver annotations --- .../org/jetbrains/kotlin/codegen/FunctionCodegen.java | 8 ++++++++ .../src/org/jetbrains/kotlin/diagnostics/Errors.java | 1 + .../diagnostics/rendering/DefaultErrorMessages.java | 1 + .../kotlin/psi/JetAnnotationUseSiteTarget.kt | 1 + .../jetbrains/kotlin/resolve/ModifiersChecker.java | 11 +++++++++++ .../annotations/AnnotationUseSiteTarget.kt | 3 ++- 6 files changed, 24 insertions(+), 1 deletion(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index 4abd93ab720..5905a0728a3 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -254,6 +254,14 @@ public class FunctionCodegen { v.getSerializationBindings().put(INDEX_FOR_VALUE_PARAMETER, parameter, i); AnnotationCodegen.forParameter(i, mv, typeMapper).genAnnotations(parameter, parameterSignature.getAsmType()); } + else if (kind == JvmMethodParameterKind.RECEIVER) { + Annotated annotationHolder = (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); + } } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 40af01971d1..4dc2594ff1c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -137,6 +137,7 @@ public interface Errors { DiagnosticFactory0 INAPPLICABLE_GET_TARGET = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 INAPPLICABLE_SET_TARGET = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 INAPPLICABLE_TARGET_PROPERTY_IMMUTABLE = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 INAPPLICABLE_RECEIVER_TARGET = DiagnosticFactory0.create(ERROR); // Classes and traits diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index e052a46a050..9ca1d52a067 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -130,6 +130,7 @@ public class DefaultErrorMessages { MAP.put(INAPPLICABLE_GET_TARGET, "''@get:'' annotations could be applied only to property declarations"); MAP.put(INAPPLICABLE_SET_TARGET, "''@set:'' annotations could be applied only to property declarations"); MAP.put(INAPPLICABLE_TARGET_PROPERTY_IMMUTABLE, "Property must be mutable"); + MAP.put(INAPPLICABLE_RECEIVER_TARGET, "''@receiver:'' annotations could be applied only to extension function or extension property declarations"); MAP.put(REDUNDANT_MODIFIER, "Modifier ''{0}'' is redundant because ''{1}'' is present", TO_STRING, TO_STRING); MAP.put(ABSTRACT_MODIFIER_IN_TRAIT, "Modifier ''abstract'' is redundant in interface"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetAnnotationUseSiteTarget.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetAnnotationUseSiteTarget.kt index 3973aa3c191..8c32f83b169 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetAnnotationUseSiteTarget.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetAnnotationUseSiteTarget.kt @@ -41,6 +41,7 @@ public class JetAnnotationUseSiteTarget : JetElementImplStub AnnotationUseSiteTarget.PROPERTY JetTokens.GET_KEYWORD -> AnnotationUseSiteTarget.PROPERTY_GETTER JetTokens.SET_KEYWORD -> AnnotationUseSiteTarget.PROPERTY_SETTER + JetTokens.RECEIVER_KEYWORD -> AnnotationUseSiteTarget.RECEIVER else -> throw IllegalStateException("Unknown annotation target " + node.getText()) } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.java index 3cb7c17d5f3..4e5fe32ef6c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.java @@ -244,6 +244,17 @@ public class ModifiersChecker { reportIfNotMutableProperty(descriptor, annotation, INAPPLICABLE_SET_TARGET); break; } + case RECEIVER: { + if (!(descriptor instanceof FunctionDescriptor) && !(descriptor instanceof PropertyDescriptor)) { + reportAnnotationTargetNotApplicable(annotation, INAPPLICABLE_RECEIVER_TARGET); + break; + } + + if (((CallableMemberDescriptor) descriptor).getExtensionReceiverParameter() == null) { + reportAnnotationTargetNotApplicable(annotation, INAPPLICABLE_RECEIVER_TARGET); + } + break; + } } } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationUseSiteTarget.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationUseSiteTarget.kt index af2fee5f27f..60bb4ea8306 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationUseSiteTarget.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationUseSiteTarget.kt @@ -21,7 +21,8 @@ public enum class AnnotationUseSiteTarget(renderName: String? = null) { FILE(), PROPERTY(), PROPERTY_GETTER("get"), - PROPERTY_SETTER("set"); + PROPERTY_SETTER("set"), + RECEIVER(); public val renderName: String = renderName ?: name().toLowerCase() } \ No newline at end of file