org.aspectj.weaver.Iterators Maven / Gradle / Ivy
/* *******************************************************************
* Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* PARC initial implementation
* ******************************************************************/
package org.aspectj.weaver;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;
public final class Iterators {
/**
* Private constructor, nobody should ever make one of these
*/
private Iterators() {
}
/**
* A getter represents a mapping function from Object to Iterator
*/
public interface Getter {
Iterator get(A target);
}
/**
* A filter represents a mapping function from Iterator to Iterator
*/
public interface Filter {
Iterator filter(Iterator in);
}
/**
* Create a new filter F that, when wrapped around another iterator I, creates a new iterator I' that will return only those
* values of I that have not yet been returned by I', discarding duplicates.
*/
public static Filter dupFilter() {
return new Filter() {
final Set seen = new HashSet(); // should have weak ptrs?
public Iterator filter(final Iterator in) {
return new Iterator() {
boolean fresh = false;
T peek;
public boolean hasNext() {
if (fresh) {
return true;
}
while (true) {
if (!in.hasNext()) {
return false;
}
peek = in.next();
if (!seen.contains(peek)) {
fresh = true;
return true;
} else {
peek = null; // garbage collection
}
}
}
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
T ret = peek;
seen.add(peek);
peek = null;
fresh = false;
return ret;
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
};
}
/**
* Creates an iterator that will return the elements of a specified array, in order. Like Arrays.asList(o).iterator(), without
* all that pesky safety.
*/
public static Iterator array(final T[] o) {
return new Iterator() {
int i = 0;
int len = (o == null) ? 0 : o.length;
public boolean hasNext() {
return i < len;
}
public T next() {
if (i < len) {
return o[i++];
} else {
throw new NoSuchElementException();
}
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
public static class ResolvedTypeArrayIterator implements Iterator {
private ResolvedType[] array;
private int index;
private int len;
private boolean wantGenerics;
private List alreadySeen; // type signatures
public ResolvedTypeArrayIterator(ResolvedType[] array, List alreadySeen, boolean wantGenerics) {
assert array != null;
this.array = array;
this.wantGenerics = wantGenerics;
this.len = array.length;
this.index = 0;
this.alreadySeen = alreadySeen;
moveToNextNewOne();
}
private void moveToNextNewOne() {
while (index < len) {
ResolvedType interfaceType = array[index];
if (!wantGenerics && interfaceType.isParameterizedOrGenericType()) {
interfaceType = interfaceType.getRawType();
}
String signature = interfaceType.getSignature();
if (!alreadySeen.contains(signature)) {
break;
}
index++;
}
}
public boolean hasNext() {
return index < len;
}
public ResolvedType next() {
if (index < len) {
ResolvedType oo = array[index++];
if (!wantGenerics && (oo.isParameterizedType() || oo.isGenericType())) {
oo = oo.getRawType();
}
alreadySeen.add(oo.getSignature());
moveToNextNewOne();
return oo;
} else {
throw new NoSuchElementException();
}
}
public void remove() {
throw new UnsupportedOperationException();
}
}
public static Iterator array(final ResolvedType[] o, final boolean genericsAware) {
return new Iterator() {
int i = 0;
int len = (o == null) ? 0 : o.length;
public boolean hasNext() {
return i < len;
}
public ResolvedType next() {
if (i < len) {
ResolvedType oo = o[i++];
if (!genericsAware && (oo.isParameterizedType() || oo.isGenericType())) {
return oo.getRawType();
}
return oo;
} else {
throw new NoSuchElementException();
}
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
/**
* creates an iterator I based on a base iterator A and a getter G. I returns, in order, forall (i in A), G(i).
*/
public static Iterator mapOver(final Iterator a, final Getter g) {
return new Iterator() {
Iterator delegate = new Iterator() {
public boolean hasNext() {
if (!a.hasNext()) {
return false;
}
A o = a.next();
delegate = append1(g.get(o), this);
return delegate.hasNext();
}
public B next() {
if (!hasNext()) {
throw new UnsupportedOperationException();
}
return delegate.next();
}
public void remove() {
throw new UnsupportedOperationException();
}
};
public boolean hasNext() {
return delegate.hasNext();
}
public B next() {
return delegate.next();
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
/**
* creates an iterator I based on a base iterator A and a getter G. I returns, in order, forall (i in I) i :: forall (i' in
* g(i)) recur(i', g)
*/
public static Iterator recur(final A a, final Getter g) {
return new Iterator() {
Iterator delegate = one(a);
public boolean hasNext() {
return delegate.hasNext();
}
public A next() {
A next = delegate.next();
delegate = append(g.get(next), delegate);
return next;
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
/**
* creates an iterator I based on base iterators A and B. Returns the elements returned by A followed by those returned by B. If
* B is empty, simply returns A, and if A is empty, simply returns B. Do NOT USE if b.hasNext() is not idempotent.
*/
public static Iterator append(final Iterator a, final Iterator b) {
if (!b.hasNext()) {
return a;
}
return append1(a, b);
}
/**
* creates an iterator I based on base iterators A and B. Returns the elements returned by A followed by those returned by B. If
* A is empty, simply returns B. Guaranteed not to call B.hasNext() until A is empty.
*/
public static Iterator append1(final Iterator a, final Iterator b) {
if (!a.hasNext()) {
return b;
}
return new Iterator() {
public boolean hasNext() {
return a.hasNext() || b.hasNext();
}
public T next() {
if (a.hasNext()) {
return a.next();
}
if (b.hasNext()) {
return b.next();
}
throw new NoSuchElementException();
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
/**
* creates an iterator I based on a base iterator A and an object O. Returns the elements returned by A, followed by O.
*/
public static Iterator snoc(final Iterator first, final T last) {
return new Iterator() {
T last1 = last;
public boolean hasNext() {
return first.hasNext() || last1 != null;
}
public T next() {
if (first.hasNext()) {
return first.next();
} else if (last1 == null) {
throw new NoSuchElementException();
}
T ret = last1;
last1 = null;
return ret;
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
/**
* creates an iterator I based on an object O. Returns O, once.
*/
public static Iterator one(final T it) {
return new Iterator() {
boolean avail = true;
public boolean hasNext() {
return avail;
}
public T next() {
if (!avail) {
throw new NoSuchElementException();
}
avail = false;
return it;
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
}