@Override public void initExprents() { headexprent.set(0, first.getExprents().remove(first.getExprents().size() - 1)); }
@Override public void initExprents() { SwitchExprent swexpr = (SwitchExprent)first.getExprents().remove(first.getExprents().size() - 1); swexpr.setCaseValues(caseValues); headexprent.set(0, swexpr); }
@Override public void initExprents() { IfExprent ifexpr = (IfExprent)first.getExprents().remove(first.getExprents().size() - 1); if (negated) { ifexpr = (IfExprent)ifexpr.copy(); ifexpr.negateIf(); } headexprent.set(0, ifexpr); }
private static void hideEmptySuper(ClassWrapper wrapper) { for (MethodWrapper method : wrapper.getMethods()) { if (CodeConstants.INIT_NAME.equals(method.methodStruct.getName()) && method.root != null) { Statement firstData = Statements.findFirstData(method.root); if (firstData == null || firstData.getExprents().isEmpty()) { return; } Exprent exprent = firstData.getExprents().get(0); if (exprent.type == Exprent.EXPRENT_INVOCATION) { InvocationExprent invExpr = (InvocationExprent)exprent; if (Statements.isInvocationInitConstructor(invExpr, method, wrapper, false) && invExpr.getLstParameters().isEmpty()) { firstData.getExprents().remove(0); } } } } }
private static Statement isExitEdge(StatEdge edge) { Statement dest = edge.getDestination(); if (edge.getType() == StatEdge.TYPE_BREAK && dest.type == Statement.TYPE_BASICBLOCK && edge.explicit && (edge.labeled || isOnlyEdge(edge))) { List<Exprent> data = dest.getExprents(); if (data != null && data.size() == 1) { if (data.get(0).type == Exprent.EXPRENT_EXIT) { return dest; } } } return null; }
private static Statement getFirstExprentlist(Statement stat) { if (stat.getExprents() != null) { return stat; } switch (stat.type) { case Statement.TYPE_IF: case Statement.TYPE_SEQUENCE: case Statement.TYPE_SWITCH: case Statement.TYPE_SYNCRONIZED: return getFirstExprentlist(stat.getFirst()); } return null; }
private static void setRetEdgesUnlabeled(RootStatement root) { Statement exit = root.getDummyExit(); for (StatEdge edge : exit.getAllPredecessorEdges()) { List<Exprent> lst = edge.getSource().getExprents(); if (edge.getType() == StatEdge.TYPE_FINALLYEXIT || (lst != null && !lst.isEmpty() && lst.get(lst.size() - 1).type == Exprent.EXPRENT_EXIT)) { edge.labeled = false; } } }
private static Statement findFirstBlock(Statement stat, Set<Statement> setStats) { LinkedList<Statement> stack = new LinkedList<>(); stack.add(stat); while (!stack.isEmpty()) { Statement st = stack.remove(0); if (stack.isEmpty() || setStats.contains(st)) { if (st.isLabeled() && !stack.isEmpty() || st.getExprents() != null) { return st; } stack.clear(); switch (st.type) { case Statement.TYPE_SEQUENCE: stack.addAll(0, st.getStats()); break; case Statement.TYPE_IF: case Statement.TYPE_ROOT: case Statement.TYPE_SWITCH: case Statement.TYPE_SYNCRONIZED: stack.add(st.getFirst()); break; default: return st; } } } return null; }
private static InvocationExprent isAssertionError(Statement stat) { if (stat == null || stat.getExprents() == null || stat.getExprents().size() != 1) { return null; } Exprent expr = stat.getExprents().get(0); if (expr.type == Exprent.EXPRENT_EXIT) { ExitExprent exexpr = (ExitExprent)expr; if (exexpr.getExitType() == ExitExprent.EXIT_THROW && exexpr.getValue().type == Exprent.EXPRENT_NEW) { NewExprent nexpr = (NewExprent)exexpr.getValue(); if (CLASS_ASSERTION_ERROR.equals(nexpr.getNewType()) && nexpr.getConstructor() != null) { return nexpr.getConstructor(); } } } return null; }
private static void setVersionsToNull(Statement stat) { if (stat.getExprents() == null) { for (Object obj : stat.getSequentialObjects()) { if (obj instanceof Statement) { setVersionsToNull((Statement)obj); } else if (obj instanceof Exprent) { setExprentVersionsToNull((Exprent)obj); } } } else { for (Exprent exprent : stat.getExprents()) { setExprentVersionsToNull(exprent); } } }
private static Statement getLastDirectData(Statement stat) { if (stat.getExprents() != null) { return stat; } if (stat.type == Statement.TYPE_SEQUENCE) { for (int i = stat.getStats().size() - 1; i >= 0; i--) { Statement tmp = getLastDirectData(stat.getStats().get(i)); if (tmp == null || !tmp.getExprents().isEmpty()) { return tmp; } } } return null; } }
private static boolean enhanceLoopsRec(Statement stat) { boolean res = false; for (Statement st : stat.getStats()) { if (st.getExprents() == null) { res |= enhanceLoopsRec(st); } } if (stat.type == Statement.TYPE_DO) { res |= enhanceLoop((DoStatement)stat); } return res; }
private static void hideDefaultSwitchEdges(Statement stat) { if (stat.type == Statement.TYPE_SWITCH) { SwitchStatement swst = (SwitchStatement)stat; int last = swst.getCaseStatements().size() - 1; if (last >= 0) { // empty switch possible Statement stlast = swst.getCaseStatements().get(last); if (stlast.getExprents() != null && stlast.getExprents().isEmpty()) { if (!stlast.getAllSuccessorEdges().get(0).explicit) { List<StatEdge> lstEdges = swst.getCaseEdges().get(last); lstEdges.remove(swst.getDefault_edge()); if (lstEdges.isEmpty()) { swst.getCaseStatements().remove(last); swst.getCaseEdges().remove(last); } } } } } for (Statement st : stat.getStats()) { hideDefaultSwitchEdges(st); } }
public static void removeRedundantReturns(RootStatement root) { DummyExitStatement dummyExit = root.getDummyExit(); for (StatEdge edge : dummyExit.getAllPredecessorEdges()) { if (!edge.explicit) { Statement source = edge.getSource(); List<Exprent> lstExpr = source.getExprents(); if (lstExpr != null && !lstExpr.isEmpty()) { Exprent expr = lstExpr.get(lstExpr.size() - 1); if (expr.type == Exprent.EXPRENT_EXIT) { ExitExprent ex = (ExitExprent)expr; if (ex.getExitType() == ExitExprent.EXIT_RETURN && ex.getValue() == null) { // remove redundant return dummyExit.addBytecodeOffsets(ex.bytecode); lstExpr.remove(lstExpr.size() - 1); } } } } } } }
public static Statement findFirstData(Statement stat) { if (stat.getExprents() != null) { return stat; } else if (stat.isLabeled()) { // FIXME: Why?? return null; } switch (stat.type) { case Statement.TYPE_SEQUENCE: case Statement.TYPE_IF: case Statement.TYPE_ROOT: case Statement.TYPE_SWITCH: case Statement.TYPE_SYNCRONIZED: return findFirstData(stat.getFirst()); default: return null; } }
private static boolean mergeAllIfsRec(Statement stat, Set<? super Integer> setReorderedIfs) { boolean res = false; if (stat.getExprents() == null) { while (true) { boolean changed = false; for (Statement st : stat.getStats()) { res |= mergeAllIfsRec(st, setReorderedIfs); // collapse composed if's if (changed = mergeIfs(st, setReorderedIfs)) { break; } } res |= changed; if (!changed) { break; } } } return res; }
public static void destroyAndFlattenStatement(Statement stat) { destroyStatementContent(stat, false); BasicBlockStatement bstat = new BasicBlockStatement(new BasicBlock( DecompilerContext.getCounterContainer().getCounterAndIncrement(CounterContainer.STATEMENT_COUNTER))); if (stat.getExprents() == null) { bstat.setExprents(new ArrayList<>()); } else { bstat.setExprents(DecHelper.copyExprentList(stat.getExprents())); } stat.getParent().replaceStatement(stat, bstat); }
private static void cleanUpUnreachableBlocks(Statement stat) { boolean found; do { found = false; for (int i = 0; i < stat.getStats().size(); i++) { Statement st = stat.getStats().get(i); cleanUpUnreachableBlocks(st); if (st.type == Statement.TYPE_SEQUENCE && st.getStats().size() > 1) { Statement last = st.getStats().getLast(); Statement secondlast = st.getStats().get(st.getStats().size() - 2); if (last.getExprents() == null || !last.getExprents().isEmpty()) { if (!secondlast.hasBasicSuccEdge()) { Set<Statement> set = last.getNeighboursSet(Statement.STATEDGE_DIRECT_ALL, Statement.DIRECTION_BACKWARD); set.remove(secondlast); if (set.isEmpty()) { last.setExprents(new ArrayList<>()); found = true; break; } } } } } } while (found); }
private static boolean extractFirstIf(DoStatement stat) { // search for an if condition at the entrance of the loop Statement first = stat.getFirst(); while (first.type == Statement.TYPE_SEQUENCE) { first = first.getFirst(); } // found an if statement if (first.type == Statement.TYPE_IF) { IfStatement firstif = (IfStatement)first; if (firstif.getFirst().getExprents().isEmpty()) { if (firstif.iftype == IfStatement.IFTYPE_IF && firstif.getIfstat() != null) { Statement ifstat = firstif.getIfstat(); if (isExternStatement(stat, ifstat, ifstat)) { extractIfBlock(stat, firstif); return true; } } } } return false; }
private static boolean collapseInlinedClass14(Statement stat) { boolean ret = class14Builder.match(stat); if (ret) { String class_name = (String)class14Builder.getVariableValue("$classname$"); AssignmentExprent assignment = (AssignmentExprent)class14Builder.getVariableValue("$assignfield$"); FieldExprent fieldExpr = (FieldExprent)class14Builder.getVariableValue("$field$"); assignment.replaceExprent(assignment.getRight(), new ConstExprent(VarType.VARTYPE_CLASS, class_name, null)); List<Exprent> data = new ArrayList<>(stat.getFirst().getExprents()); stat.setExprents(data); SequenceHelper.destroyAndFlattenStatement(stat); ClassWrapper wrapper = (ClassWrapper)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS_WRAPPER); if (wrapper != null) { wrapper.getHiddenMembers().add(InterpreterUtil.makeUniqueKey(fieldExpr.getName(), fieldExpr.getDescriptor().descriptorString)); } } return ret; } }