aboutsummaryrefslogtreecommitdiffstats
path: root/javaparser-core/src/main/java/com/github/javaparser/utils/VisitorSet.java
diff options
context:
space:
mode:
Diffstat (limited to 'javaparser-core/src/main/java/com/github/javaparser/utils/VisitorSet.java')
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/utils/VisitorSet.java191
1 files changed, 191 insertions, 0 deletions
diff --git a/javaparser-core/src/main/java/com/github/javaparser/utils/VisitorSet.java b/javaparser-core/src/main/java/com/github/javaparser/utils/VisitorSet.java
new file mode 100644
index 000000000..70fc358c7
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/utils/VisitorSet.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2007-2010 JĂșlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.utils;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.Visitable;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * A set that overrides the equals and hashcode calculation of the added nodes
+ * by using another equals and hashcode visitor for those methods.
+ */
+public class VisitorSet<N extends Node> implements Set<N> {
+
+ private final Set<EqualsHashcodeOverridingFacade> innerSet = new HashSet<>();
+ private final GenericVisitor<Integer, Void> hashcodeVisitor;
+ private final GenericVisitor<Boolean, Visitable> equalsVisitor;
+
+ /**
+ * Pass the visitors to use for equals and hashcode.
+ */
+ public VisitorSet(GenericVisitor<Integer, Void> hashcodeVisitor, GenericVisitor<Boolean, Visitable> equalsVisitor) {
+ this.hashcodeVisitor = hashcodeVisitor;
+ this.equalsVisitor = equalsVisitor;
+ }
+
+ @Override
+ public boolean add(N elem) {
+ return innerSet.add(new EqualsHashcodeOverridingFacade(elem));
+ }
+
+ @Override
+ public boolean addAll(Collection<? extends N> col) {
+ boolean modified = false;
+ for (N elem : col)
+ if (add(elem))
+ modified = true;
+ return modified;
+ }
+
+ @Override
+ public void clear() {
+ innerSet.clear();
+ }
+
+ @Override
+ public boolean contains(Object elem) {
+ return innerSet.contains(new EqualsHashcodeOverridingFacade((N) elem));
+ }
+
+ @Override
+ public boolean containsAll(Collection<?> col) {
+ for (Object elem : col)
+ if (!contains(elem))
+ return false;
+ return true;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return innerSet.isEmpty();
+ }
+
+ @Override
+ public Iterator<N> iterator() {
+ return new Iterator<N>() {
+ final Iterator<EqualsHashcodeOverridingFacade> itr = innerSet.iterator();
+
+ @Override
+ public boolean hasNext() {
+ return itr.hasNext();
+ }
+
+ @Override
+ public N next() {
+ return itr.next().overridden;
+ }
+
+ @Override
+ public void remove() {
+ itr.remove();
+ }
+ };
+ }
+
+ @Override
+ public boolean remove(Object elem) {
+ return innerSet.remove(new EqualsHashcodeOverridingFacade((N) elem));
+ }
+
+ @Override
+ public boolean removeAll(Collection<?> col) {
+ boolean modified = false;
+ for (Object elem : col)
+ if (remove(elem))
+ modified = true;
+ return modified;
+ }
+
+ @Override
+ public boolean retainAll(Collection<?> col) {
+ int oldSize = size();
+ clear();
+ addAll((Collection<? extends N>) col);
+ return size() != oldSize;
+ }
+
+ @Override
+ public int size() {
+ return innerSet.size();
+ }
+
+ @Override
+ public Object[] toArray() {
+ return innerSet.stream().map(facade -> facade.overridden).collect(Collectors.toList()).toArray();
+ }
+
+ @Override
+ public <T> T[] toArray(T[] arr) {
+ return innerSet.stream().map(facade -> facade.overridden).collect(Collectors.toList()).toArray(arr);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("[");
+ if (size() == 0)
+ return sb.append("]").toString();
+ for (EqualsHashcodeOverridingFacade facade : innerSet) {
+ sb.append(facade.overridden.toString() + ",");
+ }
+ return sb.replace(sb.length() - 2, sb.length(), "]").toString();
+ }
+
+ private class EqualsHashcodeOverridingFacade implements Visitable {
+ private final N overridden;
+
+ EqualsHashcodeOverridingFacade(N overridden) {
+ this.overridden = overridden;
+ }
+
+ @Override
+ public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+ throw new AssertionError();
+ }
+
+ @Override
+ public <A> void accept(VoidVisitor<A> v, A arg) {
+ throw new AssertionError();
+ }
+
+ @Override
+ public final int hashCode() {
+ return overridden.accept(hashcodeVisitor, null);
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null || !(obj instanceof VisitorSet.EqualsHashcodeOverridingFacade)) {
+ return false;
+ }
+ return overridden.accept(equalsVisitor, ((EqualsHashcodeOverridingFacade) obj).overridden);
+ }
+ }
+
+}