diff --git a/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/MapRules.java b/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/MapRules.java index cdf99f5e60..b9610c255c 100644 --- a/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/MapRules.java +++ b/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/MapRules.java @@ -1,5 +1,7 @@ package tech.picnic.errorprone.refasterrules; +import static java.util.Objects.requireNonNullElse; + import com.google.errorprone.refaster.Refaster; import com.google.errorprone.refaster.annotation.AfterTemplate; import com.google.errorprone.refaster.annotation.BeforeTemplate; @@ -43,6 +45,21 @@ V after(Map map, T key) { } } + /** Prefer {@link Map#getOrDefault(Object, Object)} over more contrived alternatives. */ + // XXX: Note that `requireNonNullElse` throws an NPE if the second argument is `null`, while the + // alternative does not. + static final class MapGetOrDefault { + @BeforeTemplate + V before(Map map, T key, V defaultValue) { + return requireNonNullElse(map.get(key), defaultValue); + } + + @AfterTemplate + V after(Map map, T key, V defaultValue) { + return map.getOrDefault(key, defaultValue); + } + } + /** Prefer {@link Map#isEmpty()} over more contrived alternatives. */ static final class MapIsEmpty { @BeforeTemplate diff --git a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/MapRulesTestInput.java b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/MapRulesTestInput.java index a8dc6e7fa4..707243ba4d 100644 --- a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/MapRulesTestInput.java +++ b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/MapRulesTestInput.java @@ -1,5 +1,7 @@ package tech.picnic.errorprone.refasterrules; +import static java.util.Objects.requireNonNullElse; + import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import java.math.RoundingMode; @@ -11,7 +13,7 @@ final class MapRulesTest implements RefasterRuleCollectionTestCase { @Override public ImmutableSet elidedTypesAndStaticImports() { - return ImmutableSet.of(HashMap.class); + return ImmutableSet.of(HashMap.class, requireNonNullElse(null, null)); } Map testCreateEnumMap() { @@ -22,6 +24,10 @@ String testMapGetOrNull() { return ImmutableMap.of(1, "foo").getOrDefault("bar", null); } + String testMapGetOrDefault() { + return requireNonNullElse(ImmutableMap.of(1, "foo").get("bar"), "baz"); + } + ImmutableSet testMapIsEmpty() { return ImmutableSet.of( ImmutableMap.of("foo", 1).keySet().isEmpty(), diff --git a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/MapRulesTestOutput.java b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/MapRulesTestOutput.java index 650cd4094f..9214fa6f79 100644 --- a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/MapRulesTestOutput.java +++ b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/MapRulesTestOutput.java @@ -1,5 +1,7 @@ package tech.picnic.errorprone.refasterrules; +import static java.util.Objects.requireNonNullElse; + import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import java.math.RoundingMode; @@ -12,7 +14,7 @@ final class MapRulesTest implements RefasterRuleCollectionTestCase { @Override public ImmutableSet elidedTypesAndStaticImports() { - return ImmutableSet.of(HashMap.class); + return ImmutableSet.of(HashMap.class, requireNonNullElse(null, null)); } Map testCreateEnumMap() { @@ -23,6 +25,10 @@ String testMapGetOrNull() { return ImmutableMap.of(1, "foo").get("bar"); } + String testMapGetOrDefault() { + return ImmutableMap.of(1, "foo").getOrDefault("bar", "baz"); + } + ImmutableSet testMapIsEmpty() { return ImmutableSet.of( ImmutableMap.of("foo", 1).isEmpty(),