From 397da8746a587788ae319f7e0f05bebb90a2919a Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Mon, 3 Aug 2015 20:28:17 +0300 Subject: [PATCH] Report more detailed message if use site target is available --- .../jetbrains/kotlin/diagnostics/Errors.java | 7 +--- .../rendering/DefaultErrorMessages.java | 7 +--- .../kotlin/resolve/AnnotationChecker.kt | 9 ++++- .../resolve/AnnotationUseSiteTargetChecker.kt | 38 ++++++++++--------- 4 files changed, 33 insertions(+), 28 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 06cf0fc7e57..c376ffc2474 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -115,6 +115,7 @@ public interface Errors { DiagnosticFactory2 REDUNDANT_MODIFIER_FOR_TARGET = DiagnosticFactory2.create(WARNING); DiagnosticFactory2 WRONG_MODIFIER_CONTAINING_DECLARATION = DiagnosticFactory2.create(ERROR); DiagnosticFactory1 WRONG_ANNOTATION_TARGET = DiagnosticFactory1.create(ERROR); + DiagnosticFactory2 WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET = DiagnosticFactory2.create(ERROR); DiagnosticFactory0 REPEATED_ANNOTATION = DiagnosticFactory0.create(ERROR); // Annotations @@ -131,14 +132,10 @@ public interface Errors { DiagnosticFactory0 ANNOTATION_PARAMETER_MUST_BE_ENUM_CONST = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 ANNOTATION_PARAMETER_DEFAULT_VALUE_MUST_BE_CONSTANT = DiagnosticFactory0.create(ERROR); - DiagnosticFactory0 INAPPLICABLE_FIELD_TARGET = DiagnosticFactory0.create(ERROR); + DiagnosticFactory1 INAPPLICABLE_TARGET_ON_PROPERTY = DiagnosticFactory1.create(ERROR); DiagnosticFactory0 INAPPLICABLE_FIELD_TARGET_NO_BACKING_FIELD = DiagnosticFactory0.create(ERROR); - DiagnosticFactory0 INAPPLICABLE_PROPERTY_TARGET = DiagnosticFactory0.create(ERROR); - 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); - DiagnosticFactory0 INAPPLICABLE_SPARAM_TARGET = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 INAPPLICABLE_PARAM_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 9ebdbf85681..ca32889e33b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -122,16 +122,13 @@ public class DefaultErrorMessages { MAP.put(REDUNDANT_MODIFIER_FOR_TARGET, "Modifier ''{0}'' is redundant for ''{1}''", TO_STRING, TO_STRING); MAP.put(WRONG_MODIFIER_CONTAINING_DECLARATION, "Modifier ''{0}'' is not applicable inside ''{1}''", TO_STRING, TO_STRING); MAP.put(WRONG_ANNOTATION_TARGET, "This annotation is not applicable to target ''{0}''", TO_STRING); + MAP.put(WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET, "This annotation is not applicable to target ''{0}'' and use site target ''@{1}''", TO_STRING, TO_STRING); MAP.put(REPEATED_ANNOTATION, "This annotation is not repeatable"); - MAP.put(INAPPLICABLE_FIELD_TARGET, "''@field:'' annotations could be applied only to property declarations"); + MAP.put(INAPPLICABLE_TARGET_ON_PROPERTY, "''@{0}'' annotations could be applied only to property declarations", TO_STRING); MAP.put(INAPPLICABLE_FIELD_TARGET_NO_BACKING_FIELD, "Property has neither a backing field nor a delegate"); - MAP.put(INAPPLICABLE_PROPERTY_TARGET, "''@property:'' annotations could be applied only to property declarations"); - 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(INAPPLICABLE_SPARAM_TARGET, "''@sparam:'' annotations could be applied only to property declarations"); MAP.put(INAPPLICABLE_PARAM_TARGET, "''@param:'' annotations could be applied only to primary constructor parameters"); MAP.put(REDUNDANT_MODIFIER, "Modifier ''{0}'' is redundant because ''{1}'' is present", TO_STRING, TO_STRING); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationChecker.kt index e83471285f2..b6796269de5 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationChecker.kt @@ -84,7 +84,14 @@ public class AnnotationChecker(private val additionalCheckers: Iterable checkFieldTargetApplicability(annotated, descriptor, annotation) - AnnotationUseSiteTarget.PROPERTY -> checkIfPropertyDescriptor(descriptor, annotation, INAPPLICABLE_PROPERTY_TARGET) - AnnotationUseSiteTarget.PROPERTY_GETTER -> checkIfPropertyDescriptor(descriptor, annotation, INAPPLICABLE_GET_TARGET) - AnnotationUseSiteTarget.PROPERTY_SETTER -> checkMutableProperty(descriptor, annotation, INAPPLICABLE_SET_TARGET) + AnnotationUseSiteTarget.FIELD -> checkFieldTargetApplicability(annotated, descriptor, annotationWithTarget) + 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) @@ -67,7 +69,7 @@ public object AnnotationUseSiteTargetChecker { } } } - AnnotationUseSiteTarget.SETTER_PARAMETER -> checkMutableProperty(descriptor, annotation, INAPPLICABLE_SPARAM_TARGET) + AnnotationUseSiteTarget.SETTER_PARAMETER -> checkMutableProperty(descriptor, annotationWithTarget) AnnotationUseSiteTarget.FILE -> throw IllegalArgumentException("@file annotations are not allowed here") } } @@ -76,36 +78,32 @@ public object AnnotationUseSiteTargetChecker { private fun BindingTrace.checkFieldTargetApplicability( modifierListOwner: JetAnnotated, descriptor: DeclarationDescriptor, - annotation: AnnotationDescriptor) { - if (checkIfPropertyDescriptor(descriptor, annotation, INAPPLICABLE_FIELD_TARGET)) return + annotationWithTarget: AnnotationWithTarget) { + if (checkIfPropertyDescriptor(descriptor, annotationWithTarget)) return descriptor as PropertyDescriptor val hasDelegate = modifierListOwner is JetProperty && modifierListOwner.hasDelegate() if (!hasDelegate && !(bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, descriptor) ?: false)) { - report(annotation, INAPPLICABLE_FIELD_TARGET_NO_BACKING_FIELD) + report(annotationWithTarget.annotation, INAPPLICABLE_FIELD_TARGET_NO_BACKING_FIELD) } } - private fun BindingTrace.checkMutableProperty( - descriptor: DeclarationDescriptor, - annotation: AnnotationDescriptor, - diagnosticFactory: DiagnosticFactory0) { - checkIfPropertyDescriptor(descriptor, annotation, diagnosticFactory) + private fun BindingTrace.checkMutableProperty(descriptor: DeclarationDescriptor, annotationWIthTarget: AnnotationWithTarget) { + checkIfPropertyDescriptor(descriptor, annotationWIthTarget) if (descriptor is PropertyDescriptor) { if (!descriptor.isVar) { - report(annotation, INAPPLICABLE_TARGET_PROPERTY_IMMUTABLE) + report(annotationWIthTarget.annotation, INAPPLICABLE_TARGET_PROPERTY_IMMUTABLE) } } } private fun BindingTrace.checkIfPropertyDescriptor( descriptor: DeclarationDescriptor, - annotation: AnnotationDescriptor, - diagnosticFactory: DiagnosticFactory0): Boolean { + annotationWithTarget: AnnotationWithTarget): Boolean { if (descriptor !is PropertyDescriptor) { - report(annotation, diagnosticFactory) + report(annotationWithTarget, INAPPLICABLE_TARGET_ON_PROPERTY) return true } return false @@ -116,4 +114,10 @@ public object AnnotationUseSiteTargetChecker { report(diagnosticFactory.on(annotationEntry)) } + private fun BindingTrace.report(annotationWithTarget: AnnotationWithTarget, diagnosticFactory: DiagnosticFactory1) { + val annotationEntry = DescriptorToSourceUtils.getSourceFromAnnotation(annotationWithTarget.annotation) ?: return + report(diagnosticFactory.on(annotationEntry, annotationWithTarget.target?.renderName ?: "invalid target")) + } + + } \ No newline at end of file