Skip to content

Commit

Permalink
feat: Add additional functionality to ConstantPool
Browse files Browse the repository at this point in the history
  • Loading branch information
Col-E committed Jul 24, 2020
1 parent 8631881 commit 398d6bc
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 37 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<groupId>me.coley</groupId>
<artifactId>cafedude</artifactId>
<url>https://github.com/Col-E/CAFED00D/</url>
<version>1.0.1</version>
<version>1.1.0</version>
<name>CAFED00D</name>

<properties>
Expand Down
135 changes: 99 additions & 36 deletions src/main/java/me/coley/cafedude/ConstPool.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import me.coley.cafedude.constant.ConstPoolEntry;

import java.util.ListIterator;
import java.util.Iterator;
import java.util.function.Function;
import java.util.function.Predicate;

/**
* Constant pool wrapper.
Expand Down Expand Up @@ -82,10 +84,69 @@ public int size() {
return last.getCpIndex();
}

/**
* @param entry
* Entry to fetch index of. Must not be {@code null}.
*
* @return Index in pool. {@code -1} if not in pool.
*/
public int indexOf(ConstPoolEntry entry) {
CpIter it = (CpIter) iterator();
ConstPoolEntry itEntry = null;
while ((itEntry = it.next()) != null) {
if (entry.equals(itEntry))
return it.currentIndex();
}
return -1;
}


/**
* Removes all entries in the pool that matches the given filter.
*
* @param filter
* Filter for constant matching.
*/
public void removeIf(Predicate<ConstPoolEntry> filter) {
CpIter it = (CpIter) iterator();
ConstPoolEntry entry = null;
while ((entry = it.next()) != null) {
if (filter.test(entry))
it.remove();
}
}

/**
* Replace all entries in the pool that matches the given filter.
*
* @param filter
* Filter for constant matching.
* @param replacer
* Function of old constant to replacement constant.
*/
public void replaceIf(Predicate<ConstPoolEntry> filter, Function<ConstPoolEntry, ConstPoolEntry> replacer) {
CpIter it = (CpIter) iterator();
ConstPoolEntry entry = null;
while ((entry = it.next()) != null) {
if (filter.test(entry))
it.replace(replacer.apply(entry));
}
}

@Override
public ListIterator<ConstPoolEntry> iterator() {
public Iterator<ConstPoolEntry> iterator() {
assertNotEmpty();
return new CpIter(first, true);
}

/**
* Iterates over the constant pool from the last to the first.
*
* @return Backwards iterator.
*/
public Iterator<ConstPoolEntry> backwardsIterator() {
assertNotEmpty();
return new CpIter(first);
return new CpIter(last, false);
}

/**
Expand Down Expand Up @@ -124,8 +185,10 @@ private void assertNotEmpty() {

/**
* Linked list entry wrapper.
*
* @author Matt Coley
*/
protected static class CpListNode {
public static class CpListNode {
private ConstPoolEntry entry;
private CpListNode next;
private CpListNode prev;
Expand Down Expand Up @@ -218,60 +281,60 @@ public void delete() {

/**
* Linked list iterator.
*
* @author Matt Coley
*/
private static class CpIter implements ListIterator<ConstPoolEntry> {
public static class CpIter implements Iterator<ConstPoolEntry> {
private final boolean forward;
private CpListNode current;

private CpIter(CpListNode initial) {
private CpIter(CpListNode initial, boolean forward) {
current = initial;
this.forward = forward;
}

@Override
public boolean hasNext() {
return current != null;
}

@Override
public boolean hasPrevious() {
return current.prev != null;
/**
* @return Current index.
*/
public int currentIndex() {
return current.getCpIndex();
}

@Override
public int nextIndex() {
return current.getCpIndex() + current.getCpEntrySize();
/**
* Replace the current constant pool entry.
*
* @param entry
* New constant pool entry.
*/
public void replace(ConstPoolEntry entry) {
if (forward) {
current.prev.set(entry);
} else {
current.next.set(entry);
}
}

@Override
public int previousIndex() {
return current.getCpIndex() - current.prev.getCpEntrySize();
public boolean hasNext() {
return current != null;
}

@Override
public ConstPoolEntry next() {
ConstPoolEntry value = current.entry;
current = current.next;
current = forward ? current.next : current.prev;
return value;
}

@Override
public ConstPoolEntry previous() {
current = current.prev;
return current.entry;
}

@Override
public void remove() {
current.delete();
}

@Override
public void set(ConstPoolEntry entry) {
current.set(entry);
}

@Override
public void add(ConstPoolEntry entry) {
current.insertAfter(entry);
// This is valid because to get the "current" value the user will have to call "next"
if (forward) {
current.prev.delete();
} else {
current.next.delete();
}
}
}
}

0 comments on commit 398d6bc

Please sign in to comment.