/* This file is part of the db4o object database http://www.db4o.com
Copyright (C) 2004 - 2011 Versant Corporation http://www.versant.com
db4o is free software; you can redistribute it and/or modify it under
the terms of version 3 of the GNU General Public License as published
by the Free Software Foundation.
db4o 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 General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program. If not, see http://www.gnu.org/licenses/. */
package EDU.purdue.cs.bloat.tree;
import java.util.*;
import EDU.purdue.cs.bloat.cfg.*;
/**
* ReplaceVisitor traverses a tree and replaces each occurrence of one Node with
* another Node.
*/
public class ReplaceVisitor extends TreeVisitor {
Node from;
Node to;
/**
* Constructor.
*
* @param from
* The "old" Node.
* @param to
* The "new" Node.
*/
public ReplaceVisitor(final Node from, final Node to) {
this.from = from;
this.to = to;
if (Tree.DEBUG) {
System.out.println("replace " + from + " VN=" + from.valueNumber()
+ " in " + from.parent + " with " + to);
}
}
public void visitTree(final Tree tree) {
if (to instanceof Stmt) {
((Stmt) to).setParent(tree);
// The most common statement replacement is the last statement.
// so search from the end of the statement list.
final ListIterator iter = tree.stmts
.listIterator(tree.stmts.size());
while (iter.hasPrevious()) {
final Stmt s = (Stmt) iter.previous();
if (s == from) {
iter.set(to);
break;
}
}
} else {
tree.visitChildren(this);
}
}
public void visitExprStmt(final ExprStmt stmt) {
if (stmt.expr == from) {
stmt.expr = (Expr) to;
((Expr) to).setParent(stmt);
} else {
stmt.visitChildren(this);
}
}
public void visitInitStmt(final InitStmt stmt) {
for (int i = 0; i < stmt.targets.length; i++) {
if (stmt.targets[i] == from) {
stmt.targets[i] = (LocalExpr) to;
((LocalExpr) to).setParent(stmt);
return;
}
}
stmt.visitChildren(this);
}
public void visitGotoStmt(final GotoStmt stmt) {
stmt.visitChildren(this);
}
public void visitMonitorStmt(final MonitorStmt stmt) {
if (stmt.object == from) {
stmt.object = (Expr) to;
((Expr) to).setParent(stmt);
} else {
stmt.visitChildren(this);
}
}
public void visitStackManipStmt(final StackManipStmt stmt) {
for (int i = 0; i < stmt.target.length; i++) {
if (stmt.target[i] == from) {
stmt.target[i] = (StackExpr) to;
((Expr) to).setParent(stmt);
return;
}
}
for (int i = 0; i < stmt.source.length; i++) {
if (stmt.source[i] == from) {
stmt.source[i] = (StackExpr) to;
((Expr) to).setParent(stmt);
return;
}
}
stmt.visitChildren(this);
}
public void visitCatchExpr(final CatchExpr expr) {
expr.visitChildren(this);
}
public void visitPhiJoinStmt(final PhiJoinStmt stmt) {
if (stmt.target == from) {
stmt.target = (VarExpr) to;
((VarExpr) to).setParent(stmt);
} else {
final Iterator e = stmt.operands.keySet().iterator();
while (e.hasNext()) {
final Block block = (Block) e.next();
if (stmt.operandAt(block) == from) {
stmt.setOperandAt(block, (Expr) to);
((Expr) to).setParent(stmt);
return;
}
}
stmt.visitChildren(this);
}
}
public void visitPhiCatchStmt(final PhiCatchStmt stmt) {
if (stmt.target == from) {
stmt.target = (LocalExpr) to;
((LocalExpr) to).setParent(stmt);
} else {
final ListIterator e = stmt.operands.listIterator();
while (e.hasNext()) {
final LocalExpr expr = (LocalExpr) e.next();
if (expr == from) {
e.set(to);
from.cleanup();
((LocalExpr) to).setParent(stmt);
return;
}
}
stmt.visitChildren(this);
}
}
public void visitRetStmt(final RetStmt stmt) {
stmt.visitChildren(this);
}
public void visitReturnExprStmt(final ReturnExprStmt stmt) {
if (stmt.expr == from) {
stmt.expr = (Expr) to;
((Expr) to).setParent(stmt);
} else {
stmt.visitChildren(this);
}
}
public void visitReturnStmt(final ReturnStmt stmt) {
stmt.visitChildren(this);
}
public void visitAddressStoreStmt(final AddressStoreStmt stmt) {
stmt.visitChildren(this);
}
public void visitStoreExpr(final StoreExpr expr) {
if (expr.target == from) {
expr.target = (MemExpr) to;
((MemExpr) to).setParent(expr);
} else if (expr.expr == from) {
expr.expr = (Expr) to;
((Expr) to).setParent(expr);
} else {
expr.visitChildren(this);
}
}
public void visitSwitchStmt(final SwitchStmt stmt) {
if (stmt.index == from) {
stmt.index = (Expr) to;
((Expr) to).setParent(stmt);
} else {
stmt.visitChildren(this);
}
}
public void visitThrowStmt(final ThrowStmt stmt) {
if (stmt.expr == from) {
stmt.expr = (Expr) to;
((Expr) to).setParent(stmt);
} else {
stmt.visitChildren(this);
}
}
public void visitSCStmt(final SCStmt stmt) {
if (stmt.array == from) {
stmt.array = (Expr) to;
((Expr) to).setParent(stmt);
} else if (stmt.index == from) {
stmt.index = (Expr) to;
((Expr) to).setParent(stmt);
} else {
stmt.visitChildren(this);
}
}
public void visitSRStmt(final SRStmt stmt) {
if (stmt.array == from) {
stmt.array = (Expr) to;
((Expr) to).setParent(stmt);
} else if (stmt.start == from) {
stmt.start = (Expr) to;
((Expr) to).setParent(stmt);
} else if (stmt.end == from) {
stmt.end = (Expr) to;
((Expr) to).setParent(stmt);
} else {
stmt.visitChildren(this);
}
}
public void visitDefExpr(final DefExpr expr) {
expr.visitChildren(this);
}
public void visitArrayLengthExpr(final ArrayLengthExpr expr) {
if (expr.array == from) {
expr.array = (Expr) to;
((Expr) to).setParent(expr);
} else {
expr.visitChildren(this);
}
}
public void visitArithExpr(final ArithExpr expr) {
if (expr.left == from) {
expr.left = (Expr) to;
((Expr) to).setParent(expr);
} else if (expr.right == from) {
expr.right = (Expr) to;
((Expr) to).setParent(expr);
} else {
expr.visitChildren(this);
}
}
public void visitArrayRefExpr(final ArrayRefExpr expr) {
if (expr.array == from) {
expr.array = (Expr) to;
((Expr) to).setParent(expr);
} else if (expr.index == from) {
expr.index = (Expr) to;
((Expr) to).setParent(expr);
} else {
expr.visitChildren(this);
}
}
public void visitCallMethodExpr(final CallMethodExpr expr) {
if (expr.receiver == from) {
expr.receiver = (Expr) to;
((Expr) to).setParent(expr);
} else {
for (int i = 0; i < expr.params.length; i++) {
if (expr.params[i] == from) {
expr.params[i] = (Expr) to;
((Expr) to).setParent(expr);
return;
}
}
expr.visitChildren(this);
}
}
public void visitCallStaticExpr(final CallStaticExpr expr) {
for (int i = 0; i < expr.params.length; i++) {
if (expr.params[i] == from) {
expr.params[i] = (Expr) to;
((Expr) to).setParent(expr);
return;
}
}
expr.visitChildren(this);
}
public void visitCastExpr(final CastExpr expr) {
if (expr.expr == from) {
expr.expr = (Expr) to;
((Expr) to).setParent(expr);
} else {
expr.visitChildren(this);
}
}
public void visitConstantExpr(final ConstantExpr expr) {
expr.visitChildren(this);
}
public void visitFieldExpr(final FieldExpr expr) {
if (expr.object == from) {
expr.object = (Expr) to;
((Expr) to).setParent(expr);
} else {
expr.visitChildren(this);
}
}
public void visitInstanceOfExpr(final InstanceOfExpr expr) {
if (expr.expr == from) {
expr.expr = (Expr) to;
((Expr) to).setParent(expr);
} else {
expr.visitChildren(this);
}
}
public void visitLocalExpr(final LocalExpr expr) {
expr.visitChildren(this);
}
public void visitNegExpr(final NegExpr expr) {
if (expr.expr == from) {
expr.expr = (Expr) to;
((Expr) to).setParent(expr);
} else {
expr.visitChildren(this);
}
}
public void visitNewArrayExpr(final NewArrayExpr expr) {
if (expr.size == from) {
expr.size = (Expr) to;
((Expr) to).setParent(expr);
} else {
expr.visitChildren(this);
}
}
public void visitNewExpr(final NewExpr expr) {
expr.visitChildren(this);
}
public void visitNewMultiArrayExpr(final NewMultiArrayExpr expr) {
for (int i = 0; i < expr.dimensions.length; i++) {
if (expr.dimensions[i] == from) {
expr.dimensions[i] = (Expr) to;
((Expr) to).setParent(expr);
return;
}
}
expr.visitChildren(this);
}
public void visitIfZeroStmt(final IfZeroStmt stmt) {
if (stmt.expr == from) {
stmt.expr = (Expr) to;
((Expr) to).setParent(stmt);
} else {
stmt.visitChildren(this);
}
}
public void visitIfCmpStmt(final IfCmpStmt stmt) {
if (stmt.left == from) {
stmt.left = (Expr) to;
((Expr) to).setParent(stmt);
} else if (stmt.right == from) {
stmt.right = (Expr) to;
((Expr) to).setParent(stmt);
} else {
stmt.visitChildren(this);
}
}
public void visitReturnAddressExpr(final ReturnAddressExpr expr) {
expr.visitChildren(this);
}
public void visitShiftExpr(final ShiftExpr expr) {
if (expr.expr == from) {
expr.expr = (Expr) to;
((Expr) to).setParent(expr);
} else if (expr.bits == from) {
expr.bits = (Expr) to;
((Expr) to).setParent(expr);
} else {
expr.visitChildren(this);
}
}
public void visitZeroCheckExpr(final ZeroCheckExpr expr) {
if (expr.expr == from) {
expr.expr = (Expr) to;
((Expr) to).setParent(expr);
} else {
expr.visitChildren(this);
}
}
public void visitRCExpr(final RCExpr expr) {
if (expr.expr == from) {
expr.expr = (Expr) to;
((Expr) to).setParent(expr);
} else {
expr.visitChildren(this);
}
}
public void visitUCExpr(final UCExpr expr) {
if (expr.expr == from) {
expr.expr = (Expr) to;
((Expr) to).setParent(expr);
} else {
expr.visitChildren(this);
}
}
public void visitStackExpr(final StackExpr expr) {
expr.visitChildren(this);
}
public void visitStaticFieldExpr(final StaticFieldExpr expr) {
expr.visitChildren(this);
}
}