diff --git a/nullaway/src/main/java/com/uber/nullaway/NullabilityUtil.java b/nullaway/src/main/java/com/uber/nullaway/NullabilityUtil.java index a525d0e65b..81e0d846bc 100644 --- a/nullaway/src/main/java/com/uber/nullaway/NullabilityUtil.java +++ b/nullaway/src/main/java/com/uber/nullaway/NullabilityUtil.java @@ -323,6 +323,10 @@ private static boolean isDirectTypeUseAnnotation( // In JSpecify mode and without the LegacyAnnotationLocations flag, annotations on array // dimensions are *not* treated as applying to the top-level type, consistent with the JSpecify // spec. + // Outside of JSpecify mode, annotations which are *not* on the inner type are not treated as + // being + // applied to the inner type. This can be bypassed the LegacyAnnotationLocations flag, in which + // annotations on all locations are treated as applying to the inner type. // We don't allow mixing of inner types and array dimensions in the same location // (i.e. `Foo.@Nullable Bar []` is meaningless). // These aren't correct semantics for type use annotations, but a series of hacky @@ -342,15 +346,19 @@ private static boolean isDirectTypeUseAnnotation( break; case ARRAY: if (config.isJSpecifyMode() || !config.isLegacyAnnotationLocation()) { + // Annotations on array element types do not apply to the top-level + // type outside of legacy mode return false; } locationHasArray = true; break; default: + // Wildcard or type argument! return false; } } if (config.isLegacyAnnotationLocation()) { + // Make sure it's not a mix of inner types and arrays for this annotation's location return !(locationHasInnerTypes && locationHasArray); } if (!hasNestedClass(symbol.type)) {