Repository navigation
Skip UseMapOf when values may be null or keys may repeat - #1382
Open
henriquejsza wants to merge 1 commit into
Open
henriquejsza wants to merge 1 commit into
henriquejsza wants to merge 1 commit into
Conversation
…te#1307) The anonymous-class form only rejected literal `null` arguments, so a put with a nullable parameter or method-call value was still folded into `Map.of(..)`, which throws a `NullPointerException`. Neither form checked for duplicate keys, so two puts with the same key produced a `Map.of(..)`/`Map.ofEntries(..)` call that throws `IllegalArgumentException` at runtime, where the original `HashMap` kept the last write. Reuse the prose form's `isProvablyNonNull` check for the anonymous-class form, and bail both forms when two statically comparable keys are equal. `isProvablyNonNull` now also accepts initialized `static final` constants so existing constant-key conversions keep working. Signed-off-by: henriquejsza <henriquejsza@gmail.com>
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.
What's changed?
UseMapOfrecognises two input shapes: the anonymous-class form(
new HashMap<>() {{ put(k, v); ... }}) and the prosenew HashMap<>()+put(..)chain. Both could emit a
Map.of(..)/Map.ofEntries(..)call that throws atruntime where the original
HashMapdid not:null. A nullable parameter or method-call value (as in the issue'sput("owner", dataOwner)) was still folded intoMap.of(..), which throwsNullPointerExceptionper JEP 269.Map.of(..)/Map.ofEntries(..)call that throwsIllegalArgumentException,where a
HashMap.put(..)chain had just kept the last write.This change:
isProvablyNonNullcheck for the anonymous-class form,so both forms only convert when every key and value is statically known to be
non-null.
(
SemanticallyEqual) are equal.isProvablyNonNullto also accept an initializedstatic finalconstant, so existing conversions with a constant key (e.g.
put(BLAH, "foo"))keep working rather than regressing under the stricter nullability guard.
The safe cases the recipe converts today are unchanged.
What's your motivation?
Fixes #1307.
Anything in particular you'd like reviewers to focus on?
SemanticallyEqual.areEqual(..)on the keyexpressions, so it only rejects keys it can prove equal (identical literals,
identical constant references); genuinely distinct runtime values are still
converted.
isProvablyNonNullto acceptstatic final+HasInitfields keepsthe pre-existing
changeDoubleBraceInitForNonStringTypesbehaviour; let me knowif you'd prefer a narrower condition.
Any additional context
This issue is cross-referenced from the recipe-quality tracking issue #1330 (item
D1). It is scoped to the null-value and duplicate-key hazards only; the
large-map /
maxEntriesconcern (#1310) is handled separately in #1368.Checklist
./gradlew buildlocally, and committed any resulting changes torecipes.csv