Add diagnostics on annotations on super types. KT-23992 fixed

This commit is contained in:
Dmitriy Novozhilov
2019-02-21 17:08:25 +03:00
parent 1fc6f30c50
commit 677987c85f
10 changed files with 83 additions and 1 deletions
@@ -219,6 +219,8 @@ public interface Errors {
// Annotations
DiagnosticFactory0<KtSuperTypeList> SUPERTYPES_FOR_ANNOTATION_CLASS = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtAnnotationEntry> ANNOTATION_ON_SUPERCLASS = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtAnnotationEntry> ANNOTATION_ON_SUPERCLASS_WARNING = DiagnosticFactory0.create(WARNING);
DiagnosticFactory0<KtParameter> MISSING_VAL_ON_ANNOTATION_PARAMETER = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtParameter> VAR_ANNOTATION_PARAMETER = DiagnosticFactory0.create(ERROR, VAL_OR_VAR_NODE);
DiagnosticFactory0<KtCallExpression> ANNOTATION_CLASS_CONSTRUCTOR_CALL = DiagnosticFactory0.create(ERROR);
@@ -883,6 +883,9 @@ public class DefaultErrorMessages {
MAP.put(LOCAL_ANNOTATION_CLASS, "Local annotation classes are deprecated and will be unsupported in a future release");
MAP.put(LOCAL_ANNOTATION_CLASS_ERROR, "Annotation class cannot be local");
MAP.put(ANNOTATION_ON_SUPERCLASS, "Annotations on superclass are meaningless");
MAP.put(ANNOTATION_ON_SUPERCLASS_WARNING, "Annotations on superclass are meaningless and deprecated");
MAP.put(CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT, "Const 'val' are only allowed on top level or in objects");
MAP.put(CONST_VAL_WITH_DELEGATE, "Const 'val' should not have a delegate");
MAP.put(CONST_VAL_WITH_GETTER, "Const 'val' should not have a getter");
@@ -41,6 +41,9 @@ class AnnotationChecker(
if (annotated is KtProperty) {
checkPropertyUseSiteTargetAnnotations(annotated, trace)
}
if (annotated is KtClass) {
checkSuperTypeAnnotations(annotated, trace)
}
if (annotated is KtCallableDeclaration) {
annotated.typeReference?.let { check(it, trace) }
annotated.receiverTypeReference?.let { check(it, trace) }
@@ -104,6 +107,23 @@ class AnnotationChecker(
}
}
private fun checkSuperTypeAnnotations(annotated: KtClass, trace: BindingTrace) {
val reportError = languageVersionSettings.supportsFeature(LanguageFeature.ProhibitUseSiteTargetAnnotationsOnSuperTypes)
for (superType in annotated.superTypeListEntries.mapNotNull { it.typeReference }) {
for (entry in superType.annotationEntries) {
if (entry.useSiteTarget != null) {
val diagnostic = if (reportError) {
Errors.ANNOTATION_ON_SUPERCLASS.on(entry)
} else {
Errors.ANNOTATION_ON_SUPERCLASS_WARNING.on(entry)
}
trace.report(diagnostic)
}
}
}
}
private fun KtAnnotated?.getImplicitUseSiteTargetList(): List<AnnotationUseSiteTarget> = when (this) {
is KtParameter ->
if (ownerFunction is KtPrimaryConstructor) UseSiteTargetsList.T_CONSTRUCTOR_PARAMETER else emptyList()