Repository navigation
Add @Nullable to more parameters. - #176
Merged
Merged
Conversation
This is almost all from https://errorprone.info/bugpattern/ParameterMissingNullable but in its more aggressive mode, the one that [looks for `someParam == null` in the implementation of a method](https://github.com/google/error-prone/blob/9360a0a9423f0e4be68f3683dcfa080460ed0827/core/src/main/java/com/google/errorprone/bugpatterns/nullness/ParameterMissingNullable.java#L83) and assumes that that makes the parameter nullable unless it's clearly doing something like `throw new NullPointerException()`. But I made two manual additions and many manual reverts. Additions: I covered another overload of `Signature.ClassTypeSign.of` beyond the one identified by the static checking. I annotated the _return type_ of `Identity.getScope()` as `@Nullable` to match the newly annotated constructor parameter. (Notice also that that field is left null by the other constructors.) Reverts: In `InetAddress` and `Inet6Address`, I reverted because the code goes on to throw `UnknownHostException`. In `URLConnection`, I wasn't sure how seriously to take the seemingly nullable `url` constructor parameter, to say nothing of the `protected` `url` field or the public `getURL` method. In `URLStreamHandler.openConnection`, I think maybe the checking got confused by `||?` In `URLStreamHandler.setURL`, I wasn't sure how seriously to take the seemingly nullable `file` and especially `host` parameter, and the method is deprecated, anyway. (It has an undeprecated overload that I didn't get into.) `BasicPermission.implies` allows `null`, but it's an undocumented behavior of a deprecated method that overrides an inherited method, so I backed away. `Date` has handling for `null` but only to fall through to throw IAE. `HashMap` and `CompletableFuture` show that ParameterMissingNullable wants to turn `V` into `@Nullable V` in its aggressive mode, even when it shouldn't. `Hashtable.merge` doesn't exactly show the same, and I think that method should probably throw for a null `value`, per [the contract of `Map.merge`](https://docs.oracle.com/en/java/javase/27/docs/api/java.base/java/util/Map.html#merge(K,V,java.util.function.BiFunction)), as [implemented in `HashMap`](https://github.com/openjdk/jdk/blob/a5afd6e6bf1be7c2c6b166b70e5e704e692b9854/src/java.base/share/classes/java/util/HashMap.java#L1388) and [tested in Guava](https://github.com/google/guava/blob/6b3a8d7498a7fde122967ba37a023ba3dcb47792/guava-testlib/src/com/google/common/collect/testing/testers/MapMergeTester.java#L150). I didn't feel like figuring out `Cipher.init` and its overload. I was grossed out enough by the fact that `Mac.update(null, ...)` works for byte array (but not `ByteBuffer`!) that I didn't touch it. (I was also grossed out by how `CipherInputStream.read(null, off, len)` doesn't throw NPE, but I begrudgingly added `@Nullable` anyway.) In `ChoiceCallback` and `ConfirmationCallback`, I didn't feel like I had a good enough handle on null `choices` to add `@Nullable` there. `X500Principal.getName` checks for `null` but falls through to throw IAE. I added `@Nullable` to the parameter of `RuleBasedCollator.getCollationKey`, matching my previous work on the return type. It would have made sense to continue on to `Collator` itself, but the null "support" here seems questionable: `RulesBasedComparator` itself throws if `getCollationKey` returns null, and proper null annotation in `Collator` would involve `@Nullable` on parameters of both `compare` overloads and in its implemented interface (producing `Comparator<@nullable Object>`). `getCollationKey` might be a case for [`@PolyNull`](jspecify/jspecify#79), but there is more going on there. (`Collator` probably "should have" been made a generic type.)
msridhar
approved these changes
Oct 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is almost all from https://errorprone.info/bugpattern/ParameterMissingNullable but in its more aggressive mode, the one that looks for
someParam == nullin the implementation of a method and assumes that that makes the parameter nullable unless it's clearly doing something likethrow new NullPointerException().But I made two manual additions and many manual reverts.
Additions:
I covered another overload of
Signature.ClassTypeSign.ofbeyond the one identified by the static checking.I annotated the return type of
Identity.getScope()as@Nullableto match the newly annotated constructor parameter. (Notice also that that field is left null by the other constructors.)Reverts:
In
InetAddressandInet6Address, I reverted because the code goes on to throwUnknownHostException.In
URLConnection, I wasn't sure how seriously to take the seemingly nullableurlconstructor parameter, to say nothing of theprotectedurlfield or the publicgetURLmethod.In
URLStreamHandler.openConnection, I think maybe the checking got confused by||?In
URLStreamHandler.setURL, I wasn't sure how seriously to take the seemingly nullablefileand especiallyhostparameter, and the method is deprecated, anyway. (It has an undeprecated overload that I didn't get into.)BasicPermission.impliesallowsnull, but it's an undocumented behavior of a deprecated method that overrides an inherited method, so I backed away.Datehas handling fornullbut only to fall through to throw IAE.HashMapandCompletableFutureshow that ParameterMissingNullable wants to turnVinto@Nullable Vin its aggressive mode, even when it shouldn't.Hashtable.mergedoesn't exactly show the same, and I think that method should probably throw for a nullvalue, per the contract ofMap.merge, as implemented inHashMapand tested in Guava.I didn't feel like figuring out
Cipher.initand its overload.I was grossed out enough by the fact that
Mac.update(null, ...)works for byte array (but notByteBuffer!) that I didn't touch it. (I was also grossed out by howCipherInputStream.read(null, off, len)doesn't throw NPE, but I begrudgingly added@Nullableanyway.)In
ChoiceCallbackandConfirmationCallback, I didn't feel like I had a good enough handle on nullchoicesto add@Nullablethere.X500Principal.getNamechecks fornullbut falls through to throw IAE.I added
@Nullableto the parameter ofRuleBasedCollator.getCollationKey, matching my previous work on the return type. It would have made sense to continue on toCollatoritself, but the null "support" here seems questionable:RulesBasedComparatoritself throws ifgetCollationKeyreturns null, and proper null annotation inCollatorwould involve@Nullableon parameters of bothcompareoverloads and in its implemented interface (producingComparator<@Nullable Object>).getCollationKeymight be a case for@PolyNull, but there is more going on there. (Collatorprobably "should have" been made a generic type.)