org.aspectj.weaver.Iterators Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aspectjtools Show documentation
Show all versions of aspectjtools Show documentation
Tools from the AspectJ project
/* *******************************************************************
* 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 v 2.0
* which accompanies this distribution and is available at
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
*
* 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();
}
};
}
}