Skip to content

Commit

Permalink
Introduce additional equality Refaster rules
Browse files Browse the repository at this point in the history
  • Loading branch information
Stephan202 authored and rickie committed Sep 1, 2023
1 parent 1f4a684 commit a841153
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package tech.picnic.errorprone.refasterrules;

import static java.util.function.Predicate.not;

import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.refaster.Refaster;
import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.AlsoNegation;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import com.google.errorprone.refaster.annotation.MayOptionallyUse;
import com.google.errorprone.refaster.annotation.Placeholder;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Predicate;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;

Expand Down Expand Up @@ -131,4 +136,62 @@ boolean after(boolean a, boolean b) {
return a == b;
}
}

/**
* Don't pass a lambda expression to {@link Predicate#not(Predicate)}; instead push the negation
* into the lambda expression.
*/
abstract static class PredicateLambda<T> {
@Placeholder(allowsIdentity = true)
abstract boolean predicate(@MayOptionallyUse T value);

@BeforeTemplate
Predicate<T> before() {
return not(v -> predicate(v));
}

@AfterTemplate
Predicate<T> after() {
return v -> !predicate(v);
}
}

/** Avoid contrived ways of handling {@code null} values during equality testing. */
static final class EqualsLhsNullable<T, S> {
@BeforeTemplate
boolean before(T value1, S value2) {
return Optional.ofNullable(value1).equals(Optional.of(value2));
}

@AfterTemplate
boolean after(T value1, S value2) {
return value2.equals(value1);
}
}

/** Avoid contrived ways of handling {@code null} values during equality testing. */
static final class EqualsRhsNullable<T, S> {
@BeforeTemplate
boolean before(T value1, S value2) {
return Optional.of(value1).equals(Optional.ofNullable(value2));
}

@AfterTemplate
boolean after(T value1, S value2) {
return value1.equals(value2);
}
}

/** Avoid contrived ways of handling {@code null} values during equality testing. */
static final class EqualsLhsAndRhsNullable<T, S> {
@BeforeTemplate
boolean before(T value1, S value2) {
return Optional.ofNullable(value1).equals(Optional.ofNullable(value2));
}

@AfterTemplate
boolean after(T value1, S value2) {
return Objects.equals(value1, value2);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
package tech.picnic.errorprone.refasterrules;

import static java.util.function.Predicate.not;

import com.google.common.collect.BoundType;
import com.google.common.collect.ImmutableSet;
import java.math.RoundingMode;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Stream;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;

final class EqualityRulesTest implements RefasterRuleCollectionTestCase {
@Override
public ImmutableSet<Object> elidedTypesAndStaticImports() {
return ImmutableSet.of(Objects.class);
return ImmutableSet.of(Objects.class, Optional.class, not(null));
}

ImmutableSet<Boolean> testPrimitiveOrReferenceEquality() {
Expand Down Expand Up @@ -60,4 +64,20 @@ ImmutableSet<Boolean> testIndirectDoubleNegation() {
!(3.0 != 4.0),
!(BoundType.OPEN != BoundType.CLOSED));
}

Predicate<String> testPredicateLambda() {
return not(v -> v.isEmpty());
}

boolean testEqualsLhsNullable() {
return Optional.ofNullable("foo").equals(Optional.of("bar"));
}

boolean testEqualsRhsNullable() {
return Optional.of("foo").equals(Optional.ofNullable("bar"));
}

boolean testEqualsLhsAndRhsNullable() {
return Optional.ofNullable("foo").equals(Optional.ofNullable("bar"));
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
package tech.picnic.errorprone.refasterrules;

import static java.util.function.Predicate.not;

import com.google.common.collect.BoundType;
import com.google.common.collect.ImmutableSet;
import java.math.RoundingMode;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Stream;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;

final class EqualityRulesTest implements RefasterRuleCollectionTestCase {
@Override
public ImmutableSet<Object> elidedTypesAndStaticImports() {
return ImmutableSet.of(Objects.class);
return ImmutableSet.of(Objects.class, Optional.class, not(null));
}

ImmutableSet<Boolean> testPrimitiveOrReferenceEquality() {
Expand Down Expand Up @@ -60,4 +64,20 @@ ImmutableSet<Boolean> testIndirectDoubleNegation() {
3.0 == 4.0,
BoundType.OPEN == BoundType.CLOSED);
}

Predicate<String> testPredicateLambda() {
return v -> !v.isEmpty();
}

boolean testEqualsLhsNullable() {
return "bar".equals("foo");
}

boolean testEqualsRhsNullable() {
return "foo".equals("bar");
}

boolean testEqualsLhsAndRhsNullable() {
return Objects.equals("foo", "bar");
}
}

0 comments on commit a841153

Please sign in to comment.