tech.picnic.errorprone.refasterrules.MultimapRules Maven / Gradle / Ivy
Show all versions of error-prone-contrib Show documentation
package tech.picnic.errorprone.refasterrules;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.errorprone.refaster.Refaster;
import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
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 Multimap}s. */
@OnlineDocumentation
final class MultimapRules {
private MultimapRules() {}
/** Prefer {@link Multimap#keySet()} over more contrived alternatives. */
static final class MultimapKeySet {
@BeforeTemplate
Set before(Multimap multimap) {
return multimap.asMap().keySet();
}
@AfterTemplate
Set after(Multimap multimap) {
return multimap.keySet();
}
}
/** Prefer {@link Multimap#isEmpty()} over more contrived alternatives. */
static final class MultimapIsEmpty {
@BeforeTemplate
boolean before(Multimap multimap) {
return Refaster.anyOf(
multimap.keySet(), multimap.keys(), multimap.values(), multimap.entries())
.isEmpty();
}
@AfterTemplate
boolean after(Multimap multimap) {
return multimap.isEmpty();
}
}
/** Prefer {@link Multimap#size()} over more contrived alternatives. */
static final class MultimapSize {
@BeforeTemplate
int before(Multimap multimap) {
return multimap.values().size();
}
@AfterTemplate
int after(Multimap multimap) {
return multimap.size();
}
}
/** Prefer {@link Multimap#containsKey(Object)} over more contrived alternatives. */
static final class MultimapContainsKey {
@BeforeTemplate
boolean before(Multimap multimap, T key) {
return Refaster.anyOf(multimap.keySet(), multimap.keys()).contains(key);
}
@AfterTemplate
boolean after(Multimap multimap, T key) {
return multimap.containsKey(key);
}
}
/** Prefer {@link Multimap#containsValue(Object)} over more contrived alternatives. */
static final class MultimapContainsValue {
@BeforeTemplate
boolean before(Multimap multimap, T value) {
return multimap.values().contains(value);
}
@AfterTemplate
boolean after(Multimap multimap, T value) {
return multimap.containsValue(value);
}
}
/**
* Prefer {@link Multimap#get(Object)} over more contrived alternatives.
*
* Warning: this rewrite rule is not completely behavior preserving: the
* original code will yield {@code null} for unknown keys, while the replacement code will return
* an empty collection for unknown keys.
*/
static final class MultimapGet {
@BeforeTemplate
@Nullable Collection before(Multimap multimap, K key) {
return Refaster.anyOf(multimap.asMap(), Multimaps.asMap(multimap)).get(key);
}
@AfterTemplate
Collection after(Multimap multimap, K key) {
return multimap.get(key);
}
}
/** Don't unnecessarily use {@link Multimap#entries()}. */
static final class MultimapKeysStream {
@BeforeTemplate
Stream before(Multimap multimap) {
return multimap.entries().stream().map(Map.Entry::getKey);
}
@AfterTemplate
Stream after(Multimap multimap) {
return multimap.keys().stream();
}
}
/** Don't unnecessarily use {@link Multimap#entries()}. */
static final class MultimapValuesStream {
@BeforeTemplate
Stream before(Multimap multimap) {
return multimap.entries().stream().map(Map.Entry::getValue);
}
@AfterTemplate
Stream after(Multimap multimap) {
return multimap.values().stream();
}
}
}