Skip to content

Commit

Permalink
Introduce Sets{Difference,Intersection}{,Map,Multimap} and `SetsUni…
Browse files Browse the repository at this point in the history
…on` Refaster rules (#607)
  • Loading branch information
mohamedsamehsalah authored May 3, 2023
1 parent 52245c6 commit 7d728e9
Show file tree
Hide file tree
Showing 3 changed files with 213 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
import static java.util.Collections.emptySet;
import static java.util.Collections.singleton;
import static java.util.function.Predicate.not;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import com.google.common.collect.Sets.SetView;
import com.google.common.collect.Streams;
import com.google.errorprone.refaster.Refaster;
Expand All @@ -15,6 +18,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
Expand Down Expand Up @@ -211,4 +215,116 @@ ImmutableSet<T> after(T e1, T e2, T e3, T e4, T e5) {
return ImmutableSet.of(e1, e2, e3, e4, e5);
}
}

/**
* Prefer an immutable copy of {@link Sets#difference(Set, Set)} over more contrived alternatives.
*/
static final class SetsDifference<S, T> {
@BeforeTemplate
ImmutableSet<S> before(Set<S> set1, Set<T> set2) {
return set1.stream()
.filter(Refaster.anyOf(not(set2::contains), e -> !set2.contains(e)))
.collect(toImmutableSet());
}

@AfterTemplate
ImmutableSet<S> after(Set<S> set1, Set<T> set2) {
return Sets.difference(set1, set2).immutableCopy();
}
}

/**
* Prefer an immutable copy of {@link Sets#difference(Set, Set)} over more contrived alternatives.
*/
static final class SetsDifferenceMap<T, K, V> {
@BeforeTemplate
ImmutableSet<T> before(Set<T> set, Map<K, V> map) {
return set.stream()
.filter(Refaster.anyOf(not(map::containsKey), e -> !map.containsKey(e)))
.collect(toImmutableSet());
}

@AfterTemplate
ImmutableSet<K> after(Set<K> set, Map<K, V> map) {
return Sets.difference(set, map.keySet()).immutableCopy();
}
}

/**
* Prefer an immutable copy of {@link Sets#difference(Set, Set)} over more contrived alternatives.
*/
static final class SetsDifferenceMultimap<T, K, V> {
@BeforeTemplate
ImmutableSet<T> before(Set<T> set, Multimap<K, V> multimap) {
return set.stream()
.filter(Refaster.anyOf(not(multimap::containsKey), e -> !multimap.containsKey(e)))
.collect(toImmutableSet());
}

@AfterTemplate
ImmutableSet<T> after(Set<T> set, Multimap<K, V> multimap) {
return Sets.difference(set, multimap.keySet()).immutableCopy();
}
}

/**
* Prefer an immutable copy of {@link Sets#intersection(Set, Set)} over more contrived
* alternatives.
*/
static final class SetsIntersection<S, T> {
@BeforeTemplate
ImmutableSet<S> before(Set<S> set1, Set<T> set2) {
return set1.stream().filter(set2::contains).collect(toImmutableSet());
}

@AfterTemplate
ImmutableSet<S> after(Set<S> set1, Set<T> set2) {
return Sets.intersection(set1, set2).immutableCopy();
}
}

/**
* Prefer an immutable copy of {@link Sets#intersection(Set, Set)} over more contrived
* alternatives.
*/
static final class SetsIntersectionMap<T, K, V> {
@BeforeTemplate
ImmutableSet<T> before(Set<T> set, Map<K, V> map) {
return set.stream().filter(map::containsKey).collect(toImmutableSet());
}

@AfterTemplate
ImmutableSet<T> after(Set<T> set, Map<K, V> map) {
return Sets.intersection(set, map.keySet()).immutableCopy();
}
}

/**
* Prefer an immutable copy of {@link Sets#intersection(Set, Set)} over more contrived
* alternatives.
*/
static final class SetsIntersectionMultimap<T, K, V> {
@BeforeTemplate
ImmutableSet<T> before(Set<T> set, Multimap<K, V> multimap) {
return set.stream().filter(multimap::containsKey).collect(toImmutableSet());
}

@AfterTemplate
ImmutableSet<T> after(Set<T> set, Multimap<K, V> multimap) {
return Sets.intersection(set, multimap.keySet()).immutableCopy();
}
}

/** Prefer an immutable copy of {@link Sets#union(Set, Set)} over more contrived alternatives. */
static final class SetsUnion<S, T extends S, U extends S> {
@BeforeTemplate
ImmutableSet<S> before(Set<T> set1, Set<U> set2) {
return Stream.concat(set1.stream(), set2.stream()).collect(toImmutableSet());
}

@AfterTemplate
ImmutableSet<S> after(Set<T> set1, Set<U> set2) {
return Sets.union(set1, set2).immutableCopy();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package tech.picnic.errorprone.refasterrules;

import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static java.util.function.Predicate.not;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.Sets;
import com.google.common.collect.Streams;
import java.util.Arrays;
Expand All @@ -15,7 +18,7 @@
final class ImmutableSetRulesTest implements RefasterRuleCollectionTestCase {
@Override
public ImmutableSet<Object> elidedTypesAndStaticImports() {
return ImmutableSet.of(Arrays.class, Collections.class, Streams.class);
return ImmutableSet.of(Arrays.class, Collections.class, Streams.class, not(null));
}

ImmutableSet.Builder<String> testImmutableSetBuilder() {
Expand Down Expand Up @@ -72,4 +75,57 @@ Set<Integer> testImmutableSetOf4() {
Set<Integer> testImmutableSetOf5() {
return Set.of(1, 2, 3, 4, 5);
}

ImmutableSet<ImmutableSet<Integer>> testSetsDifference() {
return ImmutableSet.of(
ImmutableSet.of(1).stream()
.filter(not(ImmutableSet.of(2)::contains))
.collect(toImmutableSet()),
ImmutableSet.of(3).stream()
.filter(v -> !ImmutableSet.of(4).contains(v))
.collect(toImmutableSet()));
}

ImmutableSet<ImmutableSet<Integer>> testSetsDifferenceMap() {
return ImmutableSet.of(
ImmutableSet.of(1).stream()
.filter(not(ImmutableMap.of(2, 3)::containsKey))
.collect(toImmutableSet()),
ImmutableSet.of(4).stream()
.filter(v -> !ImmutableMap.of(5, 6).containsKey(v))
.collect(toImmutableSet()));
}

ImmutableSet<ImmutableSet<Integer>> testSetsDifferenceMultimap() {
return ImmutableSet.of(
ImmutableSet.of(1).stream()
.filter(not(ImmutableSetMultimap.of(2, 3)::containsKey))
.collect(toImmutableSet()),
ImmutableSet.of(4).stream()
.filter(v -> !ImmutableSetMultimap.of(5, 6).containsKey(v))
.collect(toImmutableSet()));
}

ImmutableSet<Integer> testSetsIntersection() {
return ImmutableSet.of(1).stream()
.filter(ImmutableSet.of(2)::contains)
.collect(toImmutableSet());
}

ImmutableSet<Integer> testSetsIntersectionMap() {
return ImmutableSet.of(1).stream()
.filter(ImmutableMap.of(2, 3)::containsKey)
.collect(toImmutableSet());
}

ImmutableSet<Integer> testSetsIntersectionMultimap() {
return ImmutableSet.of(1).stream()
.filter(ImmutableSetMultimap.of(2, 3)::containsKey)
.collect(toImmutableSet());
}

ImmutableSet<Integer> testSetsUnion() {
return Stream.concat(ImmutableSet.of(1).stream(), ImmutableSet.of(2).stream())
.collect(toImmutableSet());
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package tech.picnic.errorprone.refasterrules;

import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static java.util.function.Predicate.not;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.Sets;
import com.google.common.collect.Streams;
import java.util.Arrays;
Expand All @@ -15,7 +18,7 @@
final class ImmutableSetRulesTest implements RefasterRuleCollectionTestCase {
@Override
public ImmutableSet<Object> elidedTypesAndStaticImports() {
return ImmutableSet.of(Arrays.class, Collections.class, Streams.class);
return ImmutableSet.of(Arrays.class, Collections.class, Streams.class, not(null));
}

ImmutableSet.Builder<String> testImmutableSetBuilder() {
Expand Down Expand Up @@ -67,4 +70,40 @@ Set<Integer> testImmutableSetOf4() {
Set<Integer> testImmutableSetOf5() {
return ImmutableSet.of(1, 2, 3, 4, 5);
}

ImmutableSet<ImmutableSet<Integer>> testSetsDifference() {
return ImmutableSet.of(
Sets.difference(ImmutableSet.of(1), ImmutableSet.of(2)).immutableCopy(),
Sets.difference(ImmutableSet.of(3), ImmutableSet.of(4)).immutableCopy());
}

ImmutableSet<ImmutableSet<Integer>> testSetsDifferenceMap() {
return ImmutableSet.of(
Sets.difference(ImmutableSet.of(1), ImmutableMap.of(2, 3).keySet()).immutableCopy(),
Sets.difference(ImmutableSet.of(4), ImmutableMap.of(5, 6).keySet()).immutableCopy());
}

ImmutableSet<ImmutableSet<Integer>> testSetsDifferenceMultimap() {
return ImmutableSet.of(
Sets.difference(ImmutableSet.of(1), ImmutableSetMultimap.of(2, 3).keySet()).immutableCopy(),
Sets.difference(ImmutableSet.of(4), ImmutableSetMultimap.of(5, 6).keySet())
.immutableCopy());
}

ImmutableSet<Integer> testSetsIntersection() {
return Sets.intersection(ImmutableSet.of(1), ImmutableSet.of(2)).immutableCopy();
}

ImmutableSet<Integer> testSetsIntersectionMap() {
return Sets.intersection(ImmutableSet.of(1), ImmutableMap.of(2, 3).keySet()).immutableCopy();
}

ImmutableSet<Integer> testSetsIntersectionMultimap() {
return Sets.intersection(ImmutableSet.of(1), ImmutableSetMultimap.of(2, 3).keySet())
.immutableCopy();
}

ImmutableSet<Integer> testSetsUnion() {
return Sets.union(ImmutableSet.of(1), ImmutableSet.of(2)).immutableCopy();
}
}

0 comments on commit 7d728e9

Please sign in to comment.