com.googlecode.dex2jar.ir.stmt.StmtList Maven / Gradle / Ivy
package com.googlecode.dex2jar.ir.stmt;
import com.googlecode.dex2jar.ir.LabelAndLocalMapper;
import com.googlecode.dex2jar.ir.stmt.Stmt.ST;
import java.util.Collection;
import java.util.Iterator;
/**
* Represent a list of statement.
*
* @author Panxiaobo
* @version $Rev$
*/
public class StmtList implements Iterable, java.util.Comparator {
private static class StmtListIterator implements Iterator {
private Stmt current;
private Stmt next;
private final StmtList list;
/**
*
*/
StmtListIterator(StmtList list, Stmt next) {
super();
this.list = list;
this.next = next;
}
@Override
public boolean hasNext() {
return next != null;
}
@Override
public Stmt next() {
current = next;
Stmt x = current;
if (x != null) {
next = x.next;
}
return x;
}
@Override
public void remove() {
if (current != null) {
list.remove(current);
current = null;
}
}
}
private Stmt first;
private Stmt last;
private int index = 1;
private int size = 0;
public void add(Stmt stmt) {
insertLast(stmt);
}
public void addAll(Collection list) {
for (Stmt stmt : list) {
insertLast(stmt);
}
}
public StmtList clone(LabelAndLocalMapper mapper) {
StmtList nList = new StmtList();
for (Stmt stmt : this) {
nList.add(stmt.clone(mapper));
}
return nList;
}
@Override
public int compare(Stmt o1, Stmt o2) {
return o1.id - o2.id;
}
public boolean contains(Stmt stmt) {
return stmt.list == this;
}
public Stmt getFirst() {
return first;
}
public Stmt getLast() {
return last;
}
public int getSize() {
return size;
}
private void indexIt(Stmt stmt) {
if (stmt.id <= 0) {
stmt.id = this.index;
this.index++;
}
}
public void insertAfter(Stmt position, Stmt stmt) {
if (position.list == this) {
indexIt(stmt);
stmt.list = this;
size++;
stmt.next = position.next;
stmt.pre = position;
if (position.next == null) {
last = stmt;
} else {
position.next.pre = stmt;
}
position.next = stmt;
}
}
public void insertBefore(Stmt position, Stmt stmt) {
if (position.list == this) {
indexIt(stmt);
stmt.list = this;
size++;
stmt.pre = position.pre;
stmt.next = position;
if (position.pre == null) {
first = stmt;
} else {
position.pre.next = stmt;
}
position.pre = stmt;
}
}
public void insertFirst(Stmt stmt) {
indexIt(stmt);
stmt.list = this;
size++;
if (first == null) { // empty
last = stmt;
first = last;
stmt.next = null;
stmt.pre = null;
} else {
stmt.pre = null;
stmt.next = first;
first.pre = stmt;
first = stmt;
}
}
public void insertLast(Stmt stmt) {
indexIt(stmt);
stmt.list = this;
size++;
if (first == null) { // empty
last = stmt;
first = last;
stmt.next = null;
stmt.pre = null;
} else {
stmt.next = null;
stmt.pre = last;
last.next = stmt;
last = stmt;
}
}
@Override
public Iterator iterator() {
return new StmtListIterator(this, first);
}
public void remove(Stmt stmt) {
if (stmt.list == this) {
size--;
stmt.list = null;
if (stmt.pre == null) {
first = stmt.next;
} else {
stmt.pre.next = stmt.next;
}
if (stmt.next == null) {
last = stmt.pre;
} else {
stmt.next.pre = stmt.pre;
}
stmt.pre = null;
stmt.next = null;
}
}
public void replace(Stmt stmt, Stmt nas) {
if (stmt.list == this) {
indexIt(nas);
nas.list = this;
nas.next = stmt.next;
nas.pre = stmt.pre;
if (stmt.next != null) {
stmt.next.pre = nas;
} else {
this.last = nas;
}
if (stmt.pre != null) {
stmt.pre.next = nas;
} else {
this.first = nas;
}
stmt.next = null;
stmt.pre = null;
stmt.list = null;
}
}
@Override
public String toString() {
if (this.size == 0) {
return "[Empty]";
}
StringBuilder sb = new StringBuilder();
for (Stmt s : this) {
if (s.st == ST.LABEL) {
sb.append("\n");
}
sb.append(s).append("\n");
}
return sb.toString();
}
public void move(Stmt start, Stmt end, Stmt dist) {
if (start.pre == null) {
this.first = end.next;
} else {
start.pre.next = end.next;
}
if (end.next == null) {
this.last = start.pre;
} else {
end.next.pre = start.pre;
}
if (dist.next == null) {
this.last = end;
end.next = null;
} else {
dist.next.pre = end;
end.next = dist.next;
}
dist.next = start;
start.pre = dist;
}
public void clear() {
size = 0;
first = null;
last = null;
}
}