From 6b622c7d855c9464d599bf90eefa6a9426d79af0 Mon Sep 17 00:00:00 2001 From: Manu Sridharan Date: Sat, 31 Aug 2024 18:42:02 -0700 Subject: [PATCH] @Nullable declaration annotation makes varargs array elements @Nullable in JSpecify mode --- .../src/main/java/com/uber/nullaway/NullabilityUtil.java | 6 ++++++ nullaway/src/main/java/com/uber/nullaway/Nullness.java | 3 ++- .../com/uber/nullaway/jspecify/JSpecifyVarargsTests.java | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/nullaway/src/main/java/com/uber/nullaway/NullabilityUtil.java b/nullaway/src/main/java/com/uber/nullaway/NullabilityUtil.java index 87f37fc602..9bf78f796c 100644 --- a/nullaway/src/main/java/com/uber/nullaway/NullabilityUtil.java +++ b/nullaway/src/main/java/com/uber/nullaway/NullabilityUtil.java @@ -38,6 +38,7 @@ import com.sun.source.tree.VariableTree; import com.sun.source.util.TreePath; import com.sun.tools.javac.code.Attribute; +import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.TargetType; import com.sun.tools.javac.code.Type; @@ -432,6 +433,11 @@ public static boolean isArrayElementNullable(Symbol arraySymbol, Config config) } } } + // In JSpecify mode, for varargs symbols we also consider the elements to be @Nullable if there + // is a @Nullable declaration annotation on the parameter + if (config.isJSpecifyMode() && (arraySymbol.flags() & Flags.VARARGS) != 0) { + return Nullness.hasNullableDeclarationAnnotation(arraySymbol, config); + } return false; } } diff --git a/nullaway/src/main/java/com/uber/nullaway/Nullness.java b/nullaway/src/main/java/com/uber/nullaway/Nullness.java index d2fc224713..157632df33 100644 --- a/nullaway/src/main/java/com/uber/nullaway/Nullness.java +++ b/nullaway/src/main/java/com/uber/nullaway/Nullness.java @@ -282,7 +282,8 @@ private static boolean individualVarargsParamsAreNullable(Symbol paramSymbol, Co || NullabilityUtil.isArrayElementNullable(paramSymbol, config); } - private static boolean hasNullableDeclarationAnnotation(Symbol symbol, Config config) { + /** Checks if the symbol has a {@code @Nullable} declaration annotation */ + public static boolean hasNullableDeclarationAnnotation(Symbol symbol, Config config) { return hasNullableAnnotation(symbol.getRawAttributes().stream(), config); } } diff --git a/nullaway/src/test/java/com/uber/nullaway/jspecify/JSpecifyVarargsTests.java b/nullaway/src/test/java/com/uber/nullaway/jspecify/JSpecifyVarargsTests.java index c13dae81d0..6ff2f2d754 100644 --- a/nullaway/src/test/java/com/uber/nullaway/jspecify/JSpecifyVarargsTests.java +++ b/nullaway/src/test/java/com/uber/nullaway/jspecify/JSpecifyVarargsTests.java @@ -57,7 +57,7 @@ public void testNullableVarargs() { " public static String takesNullableVarargs(Object o, @Nullable Object... others) {", " String s = o.toString() + \" \" + others.toString();", " for (Object other : others) {", - " // no error here; requires a type-use annotation on the elements", + " // BUG: Diagnostic contains: dereferenced expression other is @Nullable", " s += other.toString();", " }", " return s;",