Skip to content

Commit

Permalink
Implement and and or in Matcher directly
Browse files Browse the repository at this point in the history
Fixes #1716
Fixes #1177

COPYBARA_INTEGRATE_REVIEW=#1716 from kashike:feature/and-or-matchers d1d6322
PiperOrigin-RevId: 528558457
  • Loading branch information
kashike authored and Guice Team committed May 1, 2023
1 parent 36ff122 commit a99b87a
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 72 deletions.
78 changes: 8 additions & 70 deletions core/src/com/google/inject/matcher/AbstractMatcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,88 +16,26 @@

package com.google.inject.matcher;

import java.io.Serializable;

/**
* Implements {@code and()} and {@code or()}.
*
* @author crazybob@google.com (Bob Lee)
* @deprecated This class used to be useful to avoid implementing {@code and()} and {@code or()}
* yourself, but is no longer necessary now that {@link Matcher} implements these methods.
*/
@Deprecated
public abstract class AbstractMatcher<T> implements Matcher<T> {
// FYI: AbstractMatcher explicitly implements `and` and `or` in order
// to reduce binary compatibility issues, despite their impls directly
// delegating to the Matcher impl.

@Override
public Matcher<T> and(final Matcher<? super T> other) {
return new AndMatcher<T>(this, other);
return Matcher.super.and(other);
}

@Override
public Matcher<T> or(Matcher<? super T> other) {
return new OrMatcher<T>(this, other);
}

private static class AndMatcher<T> extends AbstractMatcher<T> implements Serializable {
private final Matcher<? super T> a, b;

public AndMatcher(Matcher<? super T> a, Matcher<? super T> b) {
this.a = a;
this.b = b;
}

@Override
public boolean matches(T t) {
return a.matches(t) && b.matches(t);
}

@Override
public boolean equals(Object other) {
return other instanceof AndMatcher
&& ((AndMatcher) other).a.equals(a)
&& ((AndMatcher) other).b.equals(b);
}

@Override
public int hashCode() {
return 41 * (a.hashCode() ^ b.hashCode());
}

@Override
public String toString() {
return "and(" + a + ", " + b + ")";
}

private static final long serialVersionUID = 0;
}

private static class OrMatcher<T> extends AbstractMatcher<T> implements Serializable {
private final Matcher<? super T> a, b;

public OrMatcher(Matcher<? super T> a, Matcher<? super T> b) {
this.a = a;
this.b = b;
}

@Override
public boolean matches(T t) {
return a.matches(t) || b.matches(t);
}

@Override
public boolean equals(Object other) {
return other instanceof OrMatcher
&& ((OrMatcher) other).a.equals(a)
&& ((OrMatcher) other).b.equals(b);
}

@Override
public int hashCode() {
return 37 * (a.hashCode() ^ b.hashCode());
}

@Override
public String toString() {
return "or(" + a + ", " + b + ")";
}

private static final long serialVersionUID = 0;
return Matcher.super.or(other);
}
}
8 changes: 6 additions & 2 deletions core/src/com/google/inject/matcher/Matcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,15 @@ public interface Matcher<T> {
* Returns a new matcher which returns {@code true} if both this and the given matcher return
* {@code true}.
*/
Matcher<T> and(Matcher<? super T> other);
default Matcher<T> and(Matcher<? super T> other) {
return new Matchers.AndMatcher<T>(this, other);
}

/**
* Returns a new matcher which returns {@code true} if either this or the given matcher return
* {@code true}.
*/
Matcher<T> or(Matcher<? super T> other);
default Matcher<T> or(Matcher<? super T> other) {
return new Matchers.OrMatcher<T>(this, other);
}
}
66 changes: 66 additions & 0 deletions core/src/com/google/inject/matcher/Matchers.java
Original file line number Diff line number Diff line change
Expand Up @@ -406,4 +406,70 @@ public String toString() {

private static final long serialVersionUID = 0;
}

static class AndMatcher<T> extends AbstractMatcher<T> implements Serializable {
private final Matcher<? super T> a, b;

public AndMatcher(Matcher<? super T> a, Matcher<? super T> b) {
this.a = a;
this.b = b;
}

@Override
public boolean matches(T t) {
return a.matches(t) && b.matches(t);
}

@Override
public boolean equals(Object other) {
return other instanceof AndMatcher
&& ((AndMatcher) other).a.equals(a)
&& ((AndMatcher) other).b.equals(b);
}

@Override
public int hashCode() {
return 41 * (a.hashCode() ^ b.hashCode());
}

@Override
public String toString() {
return "and(" + a + ", " + b + ")";
}

private static final long serialVersionUID = 0;
}

static class OrMatcher<T> extends AbstractMatcher<T> implements Serializable {
private final Matcher<? super T> a, b;

public OrMatcher(Matcher<? super T> a, Matcher<? super T> b) {
this.a = a;
this.b = b;
}

@Override
public boolean matches(T t) {
return a.matches(t) || b.matches(t);
}

@Override
public boolean equals(Object other) {
return other instanceof OrMatcher
&& ((OrMatcher) other).a.equals(a)
&& ((OrMatcher) other).b.equals(b);
}

@Override
public int hashCode() {
return 37 * (a.hashCode() ^ b.hashCode());
}

@Override
public String toString() {
return "or(" + a + ", " + b + ")";
}

private static final long serialVersionUID = 0;
}
}

0 comments on commit a99b87a

Please sign in to comment.