From c76e6f502843d6233b487466c398c0fe2c4d4376 Mon Sep 17 00:00:00 2001 From: Lazaro Clapp Date: Fri, 29 Mar 2019 13:26:05 -0400 Subject: [PATCH] Warn about unsupported @Nullable var args case. --- .../java/com/uber/nullaway/ErrorMessage.java | 1 + .../main/java/com/uber/nullaway/NullAway.java | 21 ++++++++++++++++--- .../java/com/uber/nullaway/NullAwayTest.java | 21 +++++++++++++++++++ 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/nullaway/src/main/java/com/uber/nullaway/ErrorMessage.java b/nullaway/src/main/java/com/uber/nullaway/ErrorMessage.java index 15d1910cb6..6b12e8c680 100644 --- a/nullaway/src/main/java/com/uber/nullaway/ErrorMessage.java +++ b/nullaway/src/main/java/com/uber/nullaway/ErrorMessage.java @@ -48,6 +48,7 @@ public enum MessageTypes { FIELD_NO_INIT, UNBOX_NULLABLE, NONNULL_FIELD_READ_BEFORE_INIT, + NULLABLE_VARARGS_UNSUPPORTED, ANNOTATION_VALUE_INVALID, CAST_TO_NONNULL_ARG_NONNULL, GET_ON_EMPTY_OPTIONAL; diff --git a/nullaway/src/main/java/com/uber/nullaway/NullAway.java b/nullaway/src/main/java/com/uber/nullaway/NullAway.java index 3b5e848013..154d69fef3 100644 --- a/nullaway/src/main/java/com/uber/nullaway/NullAway.java +++ b/nullaway/src/main/java/com/uber/nullaway/NullAway.java @@ -487,10 +487,25 @@ public Description matchMethod(MethodTree tree, VisitorState state) { if (isOverriding || !exhaustiveOverride) { Symbol.MethodSymbol closestOverriddenMethod = getClosestOverriddenMethod(methodSymbol, state.getTypes()); - if (closestOverriddenMethod == null) { - return Description.NO_MATCH; + if (closestOverriddenMethod != null) { + return checkOverriding(closestOverriddenMethod, methodSymbol, null, state); + } + } + // Check that var args (if any) is @Nullable, as NullAway doesn't currently support this case + if (methodSymbol.isVarArgs()) { + VarSymbol varArgsSymbol = + methodSymbol.getParameters().get(methodSymbol.getParameters().size() - 1); + if (Nullness.hasNullableAnnotation(varArgsSymbol)) { + String message = + "NullAway doesn't currently support @Nullable VarArgs. " + + "Consider removing the @Nullable annotation from " + + varArgsSymbol.toString() + + " in " + + methodSymbol.toString() + + " (this issue can cause other errors below, wherever the var args array is dereferenced)"; + return createErrorDescription( + MessageTypes.NULLABLE_VARARGS_UNSUPPORTED, tree, message, state.getPath()); } - return checkOverriding(closestOverriddenMethod, methodSymbol, null, state); } return Description.NO_MATCH; } diff --git a/nullaway/src/test/java/com/uber/nullaway/NullAwayTest.java b/nullaway/src/test/java/com/uber/nullaway/NullAwayTest.java index a6151acdc5..8e1bb802e4 100644 --- a/nullaway/src/test/java/com/uber/nullaway/NullAwayTest.java +++ b/nullaway/src/test/java/com/uber/nullaway/NullAwayTest.java @@ -1707,6 +1707,27 @@ public void testNonNullVarargs() { .doTest(); } + @Test + public void testNullableVarargs() { + compilationHelper + .addSourceLines( + "Utilities.java", + "package com.uber;", + "import javax.annotation.Nullable;", + "public class Utilities {", + " // BUG: Diagnostic contains: NullAway doesn't currently support @Nullable VarArgs", + " public static String takesNullableVarargs(Object o, @Nullable Object... others) {", + " String s = o.toString() + \" \";", + " // BUG: Diagnostic contains: enhanced-for expression others is @Nullable", + " for (Object other : others) {", + " s += (other == null) ? \"(null) \" : other.toString() + \" \";", + " }", + " return s;", + " }", + "}") + .doTest(); + } + @Test public void testNonNullVarargsFromHandler() { String generatedAnnot =