From 37f83c653738e32d923258fe0ce862370993ef6a Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Tue, 21 Jan 2014 14:37:19 -0600 Subject: [PATCH] Add warning for potentially incorrect NotNull or Nullable annotations on derived methods and parameters --- .../v4/runtime/misc/NullUsageProcessor.java | 38 ++++++++++++++----- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/runtime/JavaAnnotations/src/org/antlr/v4/runtime/misc/NullUsageProcessor.java b/runtime/JavaAnnotations/src/org/antlr/v4/runtime/misc/NullUsageProcessor.java index d024c23f4..331926fee 100644 --- a/runtime/JavaAnnotations/src/org/antlr/v4/runtime/misc/NullUsageProcessor.java +++ b/runtime/JavaAnnotations/src/org/antlr/v4/runtime/misc/NullUsageProcessor.java @@ -69,6 +69,8 @@ import java.util.Set; *
  • Error: a parameter is annotated with {@link NotNull}, but the method overrides or implements a method where the parameter is annotated {@link Nullable}.
  • *
  • Error: a method is annotated with {@link Nullable}, but the method overrides or implements a method that is annotated with {@link NotNull}.
  • *
  • Warning: an element with a primitive type is annotated with {@link NotNull}.
  • + *
  • Warning: a parameter is annotated with {@link NotNull}, but the method overrides or implements a method where the parameter is not annotated.
  • + *
  • Warning: a method is annotated with {@link Nullable}, but the method overrides or implements a method that is not annotated.
  • * * * @author Sam Harwell @@ -261,6 +263,10 @@ public class NullUsageProcessor extends AbstractProcessor { String error = String.format("method annotated with %s cannot override or implement a method annotated with %s", nullableType.getSimpleName(), notNullType.getSimpleName()); processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, error, overrider); } + else if (isNullable(overrider) && !(isNullable(overridden) || isNotNull(overridden))) { + String error = String.format("method annotated with %s overrides a method that is not annotated", nullableType.getSimpleName()); + processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, error, overrider, getNullableAnnotationMirror(overrider)); + } List overriderParameters = overrider.getParameters(); List overriddenParameters = overridden.getParameters(); @@ -269,26 +275,38 @@ public class NullUsageProcessor extends AbstractProcessor { String error = String.format("parameter annotated with %s cannot override or implement a parameter annotated with %s", notNullType.getSimpleName(), nullableType.getSimpleName()); processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, error, overrider); } + else if (isNotNull(overriderParameters.get(i)) && !(isNullable(overriddenParameters.get(i)) || isNotNull(overriddenParameters.get(i)))) { + String error = String.format("parameter %s annotated with %s overrides a parameter that is not annotated", overriderParameters.get(i).getSimpleName(), notNullType.getSimpleName()); + processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, error, overriderParameters.get(i), getNotNullAnnotationMirror(overriderParameters.get(i))); + } } } private boolean isNotNull(Element element) { - for (AnnotationMirror annotationMirror : element.getAnnotationMirrors()) { - if (annotationMirror.getAnnotationType().asElement() == notNullType) { - return true; - } - } - - return false; + return getNotNullAnnotationMirror(element) != null; } private boolean isNullable(Element element) { + return getNullableAnnotationMirror(element) != null; + } + + private AnnotationMirror getNotNullAnnotationMirror(Element element) { for (AnnotationMirror annotationMirror : element.getAnnotationMirrors()) { - if (annotationMirror.getAnnotationType().asElement() == nullableType) { - return true; + if (annotationMirror.getAnnotationType().asElement() == notNullType) { + return annotationMirror; } } - return false; + return null; + } + + private AnnotationMirror getNullableAnnotationMirror(Element element) { + for (AnnotationMirror annotationMirror : element.getAnnotationMirrors()) { + if (annotationMirror.getAnnotationType().asElement() == nullableType) { + return annotationMirror; + } + } + + return null; } }