Search in sources :

Example 21 with StatementIntermediate

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);
    }
}
Also used : Assignment(org.candle.decompiler.intermediate.expression.Assignment) AbstractIntermediate(org.candle.decompiler.intermediate.code.AbstractIntermediate) ArrayAccess(org.candle.decompiler.intermediate.expression.ArrayAccess) Expression(org.candle.decompiler.intermediate.expression.Expression) StatementIntermediate(org.candle.decompiler.intermediate.code.StatementIntermediate)

Example 22 with StatementIntermediate

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);
                        }
                    }
                }
            }
        }
    }
}
Also used : AbstractIntermediate(org.candle.decompiler.intermediate.code.AbstractIntermediate) StatementIntermediate(org.candle.decompiler.intermediate.code.StatementIntermediate) Increment(org.candle.decompiler.intermediate.expression.Increment) Declaration(org.candle.decompiler.intermediate.expression.Declaration) ForIntermediate(org.candle.decompiler.intermediate.code.loop.ForIntermediate)

Example 23 with StatementIntermediate

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);
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
Also used : AbstractIntermediate(org.candle.decompiler.intermediate.code.AbstractIntermediate) Variable(org.candle.decompiler.intermediate.expression.Variable) EnhancedForIntermediate(org.candle.decompiler.intermediate.code.loop.EnhancedForIntermediate) StatementIntermediate(org.candle.decompiler.intermediate.code.StatementIntermediate) SingleConditional(org.candle.decompiler.intermediate.expression.SingleConditional) MethodInvocation(org.candle.decompiler.intermediate.expression.MethodInvocation) Declaration(org.candle.decompiler.intermediate.expression.Declaration)

Example 24 with StatementIntermediate

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());
    }
}
Also used : AbstractIntermediate(org.candle.decompiler.intermediate.code.AbstractIntermediate) BreadthFirstIterator(org.jgrapht.traverse.BreadthFirstIterator) Return(org.candle.decompiler.intermediate.expression.Return) GoToIntermediate(org.candle.decompiler.intermediate.code.GoToIntermediate) Throw(org.candle.decompiler.intermediate.expression.Throw) StatementIntermediate(org.candle.decompiler.intermediate.code.StatementIntermediate) IntermediateEdge(org.candle.decompiler.intermediate.graph.edge.IntermediateEdge)

Aggregations

StatementIntermediate (org.candle.decompiler.intermediate.code.StatementIntermediate)24 AbstractIntermediate (org.candle.decompiler.intermediate.code.AbstractIntermediate)11 Expression (org.candle.decompiler.intermediate.expression.Expression)10 TypedExpression (org.candle.decompiler.intermediate.expression.TypedExpression)9 Declaration (org.candle.decompiler.intermediate.expression.Declaration)7 ArithmeticType (org.candle.decompiler.intermediate.expression.ArithmeticType)5 Assignment (org.candle.decompiler.intermediate.expression.Assignment)5 OperationType (org.candle.decompiler.intermediate.expression.OperationType)5 GoToIntermediate (org.candle.decompiler.intermediate.code.GoToIntermediate)4 GeneratedVariable (org.candle.decompiler.intermediate.expression.GeneratedVariable)4 MethodInvocation (org.candle.decompiler.intermediate.expression.MethodInvocation)4 Variable (org.candle.decompiler.intermediate.expression.Variable)4 ArrayList (java.util.ArrayList)3 IntermediateVariable (org.candle.decompiler.intermediate.IntermediateVariable)3 Throw (org.candle.decompiler.intermediate.expression.Throw)3 TreeSet (java.util.TreeSet)2 BooleanBranchIntermediate (org.candle.decompiler.intermediate.code.BooleanBranchIntermediate)2 IntermediateComparator (org.candle.decompiler.intermediate.code.IntermediateComparator)2 EnhancedForIntermediate (org.candle.decompiler.intermediate.code.loop.EnhancedForIntermediate)2 ArrayAccess (org.candle.decompiler.intermediate.expression.ArrayAccess)2