use of org.candle.decompiler.intermediate.code.StatementIntermediate in project candle-decompiler by bradsdavis.
the class ConstantArrayCompressor method collectConstantAssignments.
public void collectConstantAssignments(AbstractIntermediate current, Map<Integer, Expression> assignments) {
StatementIntermediate si = (StatementIntermediate) current;
// get the assignment...
Assignment assignment = extractConstantArrayAssignment(si.getExpression());
if (assignment == null) {
return;
}
Expression right = assignment.getRightHandSide();
ArrayAccess apr = (ArrayAccess) assignment.getLeftHandSide();
assignments.put(toInteger(apr.getIndex()), right);
List<AbstractIntermediate> predecessor = Graphs.predecessorListOf(igc.getGraph(), current);
if (predecessor.size() != 1) {
return;
}
if (!(predecessor.get(0) instanceof StatementIntermediate)) {
return;
}
for (AbstractIntermediate a : predecessor) {
collectConstantAssignments(a, assignments);
}
}
use of org.candle.decompiler.intermediate.code.StatementIntermediate in project candle-decompiler by bradsdavis.
the class WhileToForLoopIncrement method visitWhileIntermediate.
@Override
public void visitWhileIntermediate(WhileIntermediate line) {
List<AbstractIntermediate> predecessors = Graphs.predecessorListOf(igc.getGraph(), line);
// look at the predecessor lines; validate there are only 2 predecessors.
if (predecessors.size() == 2) {
StatementIntermediate declaration = null;
StatementIntermediate iteration = null;
for (AbstractIntermediate predecessor : predecessors) {
if (comparator.before(predecessor, line)) {
if (predecessor instanceof StatementIntermediate) {
declaration = (StatementIntermediate) predecessor;
continue;
} else {
// a for loop.
return;
}
}
// if the
if (comparator.after(predecessor, line)) {
if (predecessor instanceof StatementIntermediate) {
iteration = (StatementIntermediate) predecessor;
} else {
return;
}
}
}
// at this point, both should be set.
if (declaration != null && iteration != null) {
if (declaration.getExpression() instanceof Declaration) {
Declaration declarationExpression = (Declaration) declaration.getExpression();
if (iteration.getExpression() instanceof Increment) {
Increment incrementExpression = (Increment) iteration.getExpression();
if (incrementExpression.getVariable().getType().equals(declarationExpression.getVariable().getType())) {
// now check names.
if (incrementExpression.getVariable().getName().equals(declarationExpression.getVariable().getName())) {
// we can actually convert this to a for loop.
ForIntermediate forIntermediate = new ForIntermediate(line, declarationExpression, incrementExpression);
// forIntermediate.setTrueBranch(line.getTrueBranch());
// forIntermediate.setFalseBranch(line.getFalseBranch());
igc.getGraph().addVertex(forIntermediate);
igc.redirectSuccessors(line, forIntermediate);
igc.redirectPredecessors(iteration, forIntermediate);
igc.redirectPredecessors(declaration, forIntermediate);
// remove the while loop, increment, and declaration.
igc.getGraph().removeVertex(line);
igc.getGraph().removeVertex(declaration);
igc.getGraph().removeVertex(iteration);
}
}
}
}
}
}
}
use of org.candle.decompiler.intermediate.code.StatementIntermediate in project candle-decompiler by bradsdavis.
the class WhileToForLoopIterator method visitWhileIntermediate.
@Override
public void visitWhileIntermediate(WhileIntermediate line) {
if (line.getExpression() instanceof SingleConditional) {
if (((SingleConditional) line.getExpression()).getExpression() instanceof MethodInvocation) {
MethodInvocation mi = (MethodInvocation) ((SingleConditional) line.getExpression()).getExpression();
String iteratorName = null;
if (mi.getTarget() instanceof Variable) {
iteratorName = ((Variable) mi.getTarget()).getName();
} else {
return;
}
if (StringUtils.equals("hasNext", mi.getMethodName())) {
// probably an iterator.
List<AbstractIntermediate> predecessors = Graphs.predecessorListOf(igc.getGraph(), line);
// look at the predecessor lines; validate there are only 2 predecessors.
if (predecessors.size() == 2) {
StatementIntermediate declaration = null;
for (AbstractIntermediate predecessor : predecessors) {
if (comparator.before(predecessor, line)) {
if (predecessor instanceof StatementIntermediate) {
declaration = (StatementIntermediate) predecessor;
break;
}
}
}
// check to see if the declaration is a temporary variable..
if (declaration == null) {
return;
}
// otherwise, let's see if the declaration is an iterator.
if (declaration.getExpression() instanceof Declaration) {
Declaration declarationExpression = (Declaration) declaration.getExpression();
Variable v = (Variable) declarationExpression.getAssignment().getLeftHandSide();
// check to see if the declaration is the same as the iterator's name.
if (StringUtils.equals(iteratorName, v.getName())) {
LOG.debug("Identified Likely Iterator: " + v.getName());
// get the ".next()" statement, which should be the first child.
AbstractIntermediate firstChild = igc.getTrueTarget(line);
// then check the right side to see if it is an invocation.. and the invocation has the method name "next"...
if (firstChild instanceof StatementIntermediate) {
StatementIntermediate nextStatement = (StatementIntermediate) firstChild;
if (nextStatement.getExpression() instanceof Declaration) {
// the statement is indeed a declaration.
Declaration nextDeclaration = (Declaration) nextStatement.getExpression();
if (nextDeclaration.getAssignment().getRightHandSide() instanceof MethodInvocation) {
MethodInvocation nextMethodInvocation = (MethodInvocation) nextDeclaration.getAssignment().getRightHandSide();
if (StringUtils.equals("next", nextMethodInvocation.getMethodName())) {
// check to see if the next method is on the candidate iterator.
if (nextMethodInvocation.getTarget() instanceof Variable) {
Variable nextMethodTarget = (Variable) nextMethodInvocation.getTarget();
if (StringUtils.equals(iteratorName, nextMethodTarget.getName())) {
LOG.info("Definitely an enhanced for loop.");
if (declarationExpression.getAssignment().getRightHandSide() instanceof MethodInvocation) {
MethodInvocation iteratorInvocation = (MethodInvocation) declarationExpression.getAssignment().getRightHandSide();
if (StringUtils.equals("iterator", iteratorInvocation.getMethodName())) {
// now, we are pretty certain this is an enhanced for loop... we can chop up the graph.
EnhancedForIntermediate enhancedFor = new EnhancedForIntermediate(line, nextDeclaration.getVariable(), iteratorInvocation.getTarget());
igc.getGraph().addVertex(enhancedFor);
igc.redirectSuccessors(line, enhancedFor);
igc.redirectPredecessors(line, enhancedFor);
igc.getGraph().removeVertex(line);
igc.redirectPredecessors(declaration, igc.getSingleSuccessor(declaration));
igc.getGraph().removeVertex(declaration);
igc.redirectPredecessors(firstChild, igc.getSingleSuccessor(firstChild));
igc.getGraph().removeVertex(firstChild);
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
use of org.candle.decompiler.intermediate.code.StatementIntermediate in project candle-decompiler by bradsdavis.
the class CatchUpperRangeVisitor method visitCatchIntermediate.
@Override
public void visitCatchIntermediate(CatchIntermediate line) {
// first, check if the line has an end already..
if (line.getBlockRange().getEnd() != null) {
return;
}
// processLastCatch(line);
BreadthFirstIterator<AbstractIntermediate, IntermediateEdge> bfi = new BreadthFirstIterator<AbstractIntermediate, IntermediateEdge>(igc.getGraph(), line);
AbstractIntermediate lastStatement = null;
while (bfi.hasNext()) {
AbstractIntermediate next = bfi.next();
if (next instanceof GoToIntermediate) {
// this would be a possible GOTO... find previous.
LOG.debug("Catch GOGO: " + next + " goto:" + next.getInstruction().getPosition());
lastStatement = igc.getSinglePredecessor(next);
break;
}
if (next instanceof StatementIntermediate) {
// determine what type of statement...
if (((StatementIntermediate) next).getExpression() instanceof Throw) {
lastStatement = next;
break;
}
if (((StatementIntermediate) next).getExpression() instanceof Return) {
lastStatement = next;
break;
}
}
}
if (lastStatement != null) {
line.getBlockRange().setEnd(lastStatement.getInstruction());
}
}
Aggregations