diff --git a/api/src/main/java/me/lucko/luckperms/api/Node.java b/api/src/main/java/me/lucko/luckperms/api/Node.java index 8d360e982..5339bbe78 100644 --- a/api/src/main/java/me/lucko/luckperms/api/Node.java +++ b/api/src/main/java/me/lucko/luckperms/api/Node.java @@ -430,17 +430,6 @@ public interface Node { @Override boolean equals(Object obj); - /** - * Gets if this Node is equal to another node as defined by the given - * {@link StandardNodeEquality} predicate. - * - * @param other the other node - * @param equalityPredicate the predicate - * @return true if this node is considered equal - * @since 4.1 - */ - boolean standardEquals(Node other, StandardNodeEquality equalityPredicate); - /** * Gets if this Node is equal to another node as defined by the given * {@link NodeEqualityPredicate}. @@ -450,9 +439,7 @@ public interface Node { * @return true if this node is considered equal * @since 4.1 */ - default boolean equals(Node other, NodeEqualityPredicate equalityPredicate) { - return equalityPredicate.areEqual(this, other); - } + boolean equals(Node other, NodeEqualityPredicate equalityPredicate); /** * Similar to {@link Node#equals(Object)}, except doesn't take note of the diff --git a/api/src/main/java/me/lucko/luckperms/api/NodeEqualityPredicate.java b/api/src/main/java/me/lucko/luckperms/api/NodeEqualityPredicate.java index e3d0500a8..428fdcea4 100644 --- a/api/src/main/java/me/lucko/luckperms/api/NodeEqualityPredicate.java +++ b/api/src/main/java/me/lucko/luckperms/api/NodeEqualityPredicate.java @@ -41,7 +41,10 @@ import org.checkerframework.checker.nullness.qual.NonNull; public interface NodeEqualityPredicate { /** - * Returns if the two nodes are equal + * Returns if the two nodes are equal. + * + *
This method should avoid making calls to {@link Node#equals(Node, NodeEqualityPredicate)} + * with {@code this} as the second argument, directly or otherwise.
* * @param o1 the first node * @param o2 the second node diff --git a/api/src/main/java/me/lucko/luckperms/api/StandardNodeEquality.java b/api/src/main/java/me/lucko/luckperms/api/StandardNodeEquality.java index 2efed101e..6b06c44db 100644 --- a/api/src/main/java/me/lucko/luckperms/api/StandardNodeEquality.java +++ b/api/src/main/java/me/lucko/luckperms/api/StandardNodeEquality.java @@ -73,6 +73,6 @@ public enum StandardNodeEquality implements NodeEqualityPredicate { @Override public boolean areEqual(@NonNull Node o1, @NonNull Node o2) { - return o1.standardEquals(o2, this); + return o1.equals(o2, this); } } diff --git a/common/src/main/java/me/lucko/luckperms/common/model/NodeMap.java b/common/src/main/java/me/lucko/luckperms/common/model/NodeMap.java index a3b24bb7d..a36a92cd3 100644 --- a/common/src/main/java/me/lucko/luckperms/common/model/NodeMap.java +++ b/common/src/main/java/me/lucko/luckperms/common/model/NodeMap.java @@ -166,10 +166,12 @@ public final class NodeMap { } private LocalizedNode localise(Node node) { - if (node instanceof LocalizedNode) { + while (node instanceof LocalizedNode) { LocalizedNode localizedNode = (LocalizedNode) node; if (this.holder.getObjectName().equals(localizedNode.getLocation())) { return localizedNode; + } else { + node = localizedNode.getNode(); } } diff --git a/common/src/main/java/me/lucko/luckperms/common/node/model/ForwardingNode.java b/common/src/main/java/me/lucko/luckperms/common/node/model/ForwardingNode.java index fd6fe4c16..af10e7d3c 100644 --- a/common/src/main/java/me/lucko/luckperms/common/node/model/ForwardingNode.java +++ b/common/src/main/java/me/lucko/luckperms/common/node/model/ForwardingNode.java @@ -42,6 +42,16 @@ import java.util.Optional; public abstract class ForwardingNode implements Node { + static ImmutableNode unwrapForwarding(Node node) { + while (node instanceof ForwardingNode) { + node = ((ForwardingNode) node).delegate(); + } + if (!(node instanceof ImmutableNode)) { + throw new IllegalArgumentException("Node type cannot be casted to ImmutableNode: " + node.getClass()); + } + return ((ImmutableNode) node); + } + public abstract Node delegate(); @Override @@ -224,11 +234,6 @@ public abstract class ForwardingNode implements Node { return delegate().getSuffix(); } - @Override - public boolean standardEquals(Node other, StandardNodeEquality equalityPredicate) { - return delegate().standardEquals(other, equalityPredicate); - } - @Override public boolean equals(Node other, NodeEqualityPredicate equalityPredicate) { return delegate().equals(other, equalityPredicate); diff --git a/common/src/main/java/me/lucko/luckperms/common/node/model/ImmutableNode.java b/common/src/main/java/me/lucko/luckperms/common/node/model/ImmutableNode.java index 06f897c67..e280c864a 100644 --- a/common/src/main/java/me/lucko/luckperms/common/node/model/ImmutableNode.java +++ b/common/src/main/java/me/lucko/luckperms/common/node/model/ImmutableNode.java @@ -29,6 +29,7 @@ import com.google.common.collect.ImmutableList; import me.lucko.luckperms.api.Contexts; import me.lucko.luckperms.api.Node; +import me.lucko.luckperms.api.NodeEqualityPredicate; import me.lucko.luckperms.api.StandardNodeEquality; import me.lucko.luckperms.api.context.ContextSet; import me.lucko.luckperms.api.context.ImmutableContextSet; @@ -273,37 +274,31 @@ public final class ImmutableNode implements Node { public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof Node)) return false; - - Node other = (Node) o; - while (other instanceof ForwardingNode) { - other = ((ForwardingNode) other).delegate(); - } - return other instanceof ImmutableNode && Equality.EXACT.areEqual(this, (ImmutableNode) other); + return Equality.EXACT.areEqual(this, ForwardingNode.unwrapForwarding((Node) o)); } @Override - public boolean standardEquals(Node o, StandardNodeEquality equalityPredicate) { - while (o instanceof ForwardingNode) { - o = ((ForwardingNode) o).delegate(); - } - if (!(o instanceof ImmutableNode)) { - return false; - } - ImmutableNode other = (ImmutableNode) o; - switch (equalityPredicate) { - case EXACT: - return Equality.EXACT.areEqual(this, other); - case IGNORE_VALUE: - return Equality.IGNORE_VALUE.areEqual(this, other); - case IGNORE_EXPIRY_TIME: - return Equality.IGNORE_EXPIRY_TIME.areEqual(this, other); - case IGNORE_EXPIRY_TIME_AND_VALUE: - return Equality.IGNORE_EXPIRY_TIME_AND_VALUE.areEqual(this, other); - case IGNORE_VALUE_OR_IF_TEMPORARY: - return Equality.IGNORE_VALUE_OR_IF_TEMPORARY.areEqual(this, other); - default: - throw new AssertionError(); + public boolean equals(Node o, NodeEqualityPredicate equalityPredicate) { + if (equalityPredicate instanceof StandardNodeEquality) { + StandardNodeEquality stdEqualityPredicate = (StandardNodeEquality) equalityPredicate; + ImmutableNode other = ForwardingNode.unwrapForwarding(o); + switch (stdEqualityPredicate) { + case EXACT: + return Equality.EXACT.areEqual(this, other); + case IGNORE_VALUE: + return Equality.IGNORE_VALUE.areEqual(this, other); + case IGNORE_EXPIRY_TIME: + return Equality.IGNORE_EXPIRY_TIME.areEqual(this, other); + case IGNORE_EXPIRY_TIME_AND_VALUE: + return Equality.IGNORE_EXPIRY_TIME_AND_VALUE.areEqual(this, other); + case IGNORE_VALUE_OR_IF_TEMPORARY: + return Equality.IGNORE_VALUE_OR_IF_TEMPORARY.areEqual(this, other); + default: + throw new AssertionError(); + } } + + return equalityPredicate.areEqual(this, o); } @Override