aboutsummaryrefslogtreecommitdiffstats
path: root/javaparser-core/src/main/java/com/github/javaparser/utils/VisitorList.java
diff options
context:
space:
mode:
Diffstat (limited to 'javaparser-core/src/main/java/com/github/javaparser/utils/VisitorList.java')
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/utils/VisitorList.java303
1 files changed, 303 insertions, 0 deletions
diff --git a/javaparser-core/src/main/java/com/github/javaparser/utils/VisitorList.java b/javaparser-core/src/main/java/com/github/javaparser/utils/VisitorList.java
new file mode 100644
index 000000000..ea21787c2
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/utils/VisitorList.java
@@ -0,0 +1,303 @@
+/*
+ * 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.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+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 list that overrides the equals and hashcode calculation of the added nodes
+ * by using another equals and hashcode visitor for those methods.
+ */
+public class VisitorList<N extends Node> implements List<N> {
+
+ protected List<EqualsHashcodeOverridingFacade> innerList;
+ protected final GenericVisitor<Integer, Void> hashcodeVisitor;
+ protected final GenericVisitor<Boolean, Visitable> equalsVisitor;
+
+ /**
+ * Pass the visitors to use for equals and hashcode.
+ */
+ public VisitorList(GenericVisitor<Integer, Void> hashcodeVisitor,
+ GenericVisitor<Boolean, Visitable> equalsVisitor) {
+ this.hashcodeVisitor = hashcodeVisitor;
+ this.equalsVisitor = equalsVisitor;
+ innerList = new ArrayList<>();
+ }
+
+ @Override
+ public boolean add(N elem) {
+ return innerList.add(new EqualsHashcodeOverridingFacade(elem));
+ }
+
+ @Override
+ public void add(int index, N elem) {
+ innerList.add(index, 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 boolean addAll(int index, Collection<? extends N> col) {
+ if (col.isEmpty())
+ return false;
+ for (N elem : col) {
+ if (index == size())
+ add(elem);
+ else
+ add(index, elem);
+ index++;
+ }
+ return true;
+ }
+
+ @Override
+ public void clear() {
+ innerList.clear();
+ }
+
+ @Override
+ public boolean contains(Object elem) {
+ return innerList.contains(new EqualsHashcodeOverridingFacade((N) elem));
+ }
+
+ @Override
+ public boolean containsAll(Collection<?> col) {
+ for (Object elem : col)
+ if (!contains(elem))
+ return false;
+ return true;
+ }
+
+ @Override
+ public N get(int index) {
+ return innerList.get(index).overridden;
+ }
+
+ @Override
+ public int indexOf(Object elem) {
+ return innerList.indexOf(new EqualsHashcodeOverridingFacade((N) elem));
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return innerList.isEmpty();
+ }
+
+ @Override
+ public Iterator<N> iterator() {
+ return new Iterator<N>() {
+ final Iterator<EqualsHashcodeOverridingFacade> itr = innerList.iterator();
+
+ @Override
+ public boolean hasNext() {
+ return itr.hasNext();
+ }
+
+ @Override
+ public N next() {
+ return itr.next().overridden;
+ }
+
+ @Override
+ public void remove() {
+ itr.remove();
+ }
+ };
+ }
+
+ @Override
+ public int lastIndexOf(Object elem) {
+ return innerList.lastIndexOf(new EqualsHashcodeOverridingFacade((N) elem));
+ }
+
+ @Override
+ public ListIterator<N> listIterator() {
+ return listIterator(0);
+ }
+
+ @Override
+ public ListIterator<N> listIterator(int index) {
+ return new ListIterator<N>() {
+ final ListIterator<EqualsHashcodeOverridingFacade> itr = innerList.listIterator(index);
+
+ @Override
+ public boolean hasNext() {
+ return itr.hasNext();
+ }
+
+ @Override
+ public N next() {
+ return itr.next().overridden;
+ }
+
+ @Override
+ public void remove() {
+ itr.remove();
+ }
+
+ @Override
+ public void add(N elem) {
+ itr.add(new EqualsHashcodeOverridingFacade((N) elem));
+ }
+
+ @Override
+ public boolean hasPrevious() {
+ return itr.hasPrevious();
+ }
+
+ @Override
+ public int nextIndex() {
+ return itr.nextIndex();
+ }
+
+ @Override
+ public N previous() {
+ return itr.previous().overridden;
+ }
+
+ @Override
+ public int previousIndex() {
+ return itr.previousIndex();
+ }
+
+ @Override
+ public void set(N elem) {
+ itr.set(new EqualsHashcodeOverridingFacade((N) elem));
+ }
+ };
+ }
+
+ @Override
+ public boolean remove(Object elem) {
+ return innerList.remove(new EqualsHashcodeOverridingFacade((N) elem));
+ }
+
+ @Override
+ public N remove(int index) {
+ return innerList.remove(index).overridden;
+ }
+
+ @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 N set(int index, N elem) {
+ return innerList.set(index, new EqualsHashcodeOverridingFacade((N) elem)).overridden;
+ }
+
+ @Override
+ public int size() {
+ return innerList.size();
+ }
+
+ @Override
+ public List<N> subList(int fromIndex, int toIndex) {
+ return new VisitorList<N>(hashcodeVisitor, equalsVisitor) {
+ {
+ this.innerList = VisitorList.this.innerList.subList(fromIndex, toIndex);
+ }
+ };
+ }
+
+ @Override
+ public Object[] toArray() {
+ return innerList.stream().map(facade -> facade.overridden).collect(Collectors.toList()).toArray();
+ }
+
+ @Override
+ public <T> T[] toArray(T[] arr) {
+ return innerList.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 : innerList) {
+ 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 VisitorList.EqualsHashcodeOverridingFacade)) {
+ return false;
+ }
+ return overridden.accept(equalsVisitor, ((EqualsHashcodeOverridingFacade) obj).overridden);
+ }
+ }
+}