tech.picnic.errorprone.refasterrules.MapRules Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of error-prone-contrib Show documentation
Show all versions of error-prone-contrib Show documentation
Extra Error Prone plugins by Picnic.
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;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
import org.jspecify.annotations.Nullable;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with {@link Map} instances. */
@OnlineDocumentation
final class MapRules {
private MapRules() {}
// XXX: We could add a rule for `new EnumMap(Map m)`, but that constructor does
// not allow an empty non-EnumMap to be provided.
static final class CreateEnumMap, V> {
@BeforeTemplate
Map before() {
return new HashMap<>();
}
@AfterTemplate
Map after() {
return new EnumMap<>(Refaster.clazz());
}
}
static final class MapGetOrNull {
@BeforeTemplate
@Nullable V before(Map map, T key) {
return map.getOrDefault(key, null);
}
@AfterTemplate
@Nullable V after(Map map, T key) {
return map.get(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
boolean before(Map map) {
return Refaster.anyOf(map.keySet(), map.values(), map.entrySet()).isEmpty();
}
@AfterTemplate
boolean after(Map map) {
return map.isEmpty();
}
}
/** Prefer {@link Map#size()} over more contrived alternatives. */
static final class MapSize {
@BeforeTemplate
int before(Map map) {
return Refaster.anyOf(map.keySet(), map.values(), map.entrySet()).size();
}
@AfterTemplate
int after(Map map) {
return map.size();
}
}
/** Prefer {@link Map#containsKey(Object)} over more contrived alternatives. */
static final class MapContainsKey {
@BeforeTemplate
boolean before(Map map, T key) {
return map.keySet().contains(key);
}
@AfterTemplate
boolean after(Map map, T key) {
return map.containsKey(key);
}
}
/** Prefer {@link Map#containsValue(Object)} over more contrived alternatives. */
static final class MapContainsValue {
@BeforeTemplate
boolean before(Map map, T value) {
return map.values().contains(value);
}
@AfterTemplate
boolean after(Map map, T value) {
return map.containsValue(value);
}
}
/** Don't unnecessarily use {@link Map#entrySet()}. */
static final class MapKeyStream {
@BeforeTemplate
Stream before(Map map) {
return map.entrySet().stream().map(Map.Entry::getKey);
}
@AfterTemplate
Stream after(Map map) {
return map.keySet().stream();
}
}
/** Don't unnecessarily use {@link Map#entrySet()}. */
static final class MapValueStream {
@BeforeTemplate
Stream before(Map map) {
return map.entrySet().stream().map(Map.Entry::getValue);
}
@AfterTemplate
Stream after(Map map) {
return map.values().stream();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy